summaryrefslogtreecommitdiff
path: root/amigaos4
diff options
context:
space:
mode:
authorAndy Broad <andy@broad.ology.org.uk>2015-09-13 19:55:41 -0400
committerJarkko Hietaniemi <jhi@iki.fi>2015-09-16 07:44:29 -0400
commit1cd70adfb6a06a0dc72d31fc7011592a3674b183 (patch)
treec9163447716e96f211377476cc035e79c60d72e4 /amigaos4
parent738ab09f5846887e462080d6443fb8d1e751f247 (diff)
downloadperl-1cd70adfb6a06a0dc72d31fc7011592a3674b183.tar.gz
amigaos4: implement flock() emulation
Beware: not an exact implementation, the locks follow the OS level filehandle not the process.
Diffstat (limited to 'amigaos4')
-rw-r--r--amigaos4/amigaos.c86
-rw-r--r--amigaos4/amigaos.h11
2 files changed, 97 insertions, 0 deletions
diff --git a/amigaos4/amigaos.c b/amigaos4/amigaos.c
index 8e26064f08..f79943079f 100644
--- a/amigaos4/amigaos.c
+++ b/amigaos4/amigaos.c
@@ -1078,3 +1078,89 @@ BPTR amigaos_get_file(int fd)
}
return fh;
}
+
+/*########################################################################*/
+
+#define LOCK_START 0xFFFFFFFFFFFFFFFELL
+#define LOCK_LENGTH 1LL
+
+// No wait forever option so lets wait for a loooong time.
+#define TIMEOUT 0x7FFFFFFF
+
+int amigaos_flock(int fd, int oper)
+{
+ BPTR fh;
+ int32 success = -1;
+
+ if (!(fh = amigaos_get_file(fd)))
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ switch (oper)
+ {
+ case LOCK_SH:
+ {
+ if (IDOS->LockRecord(fh, LOCK_START, LOCK_LENGTH,
+ REC_SHARED | RECF_DOS_METHOD_ONLY,
+ TIMEOUT))
+ {
+ success = 0;
+ }
+ break;
+ }
+ case LOCK_EX:
+ {
+ if (IDOS->LockRecord(fh, LOCK_START, LOCK_LENGTH,
+ REC_EXCLUSIVE | RECF_DOS_METHOD_ONLY,
+ TIMEOUT))
+ {
+ success = 0;
+ }
+ break;
+ }
+ case LOCK_SH | LOCK_NB:
+ {
+ if (IDOS->LockRecord(fh, LOCK_START, LOCK_LENGTH,
+ REC_SHARED_IMMED | RECF_DOS_METHOD_ONLY,
+ TIMEOUT))
+ {
+ success = 0;
+ }
+ else
+ {
+ errno = EWOULDBLOCK;
+ }
+ break;
+ }
+ case LOCK_EX | LOCK_NB:
+ {
+ if (IDOS->LockRecord(fh, LOCK_START, LOCK_LENGTH,
+ REC_EXCLUSIVE_IMMED | RECF_DOS_METHOD_ONLY,
+ TIMEOUT))
+ {
+ success = 0;
+ }
+ else
+ {
+ errno = EWOULDBLOCK;
+ }
+ break;
+ }
+ case LOCK_UN:
+ {
+ if (IDOS->UnLockRecord(fh, LOCK_START, LOCK_LENGTH))
+ {
+ success = 0;
+ }
+ break;
+ }
+ default:
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ }
+ return success;
+}
diff --git a/amigaos4/amigaos.h b/amigaos4/amigaos.h
index 96f521d59b..2f6d4b2d49 100644
--- a/amigaos4/amigaos.h
+++ b/amigaos4/amigaos.h
@@ -52,4 +52,15 @@ long amigaos_get_file(int fd);
// BOOL constructed;
+/* emulated flock stuff */
+
+#define LOCK_SH 1 /* Shared lock. */
+#define LOCK_EX 2 /* Exclusive lock. */
+#define LOCK_UN 8 /* Unlock. */
+#define LOCK_NB 4 /* Don't block when locking. */
+
+extern int flock(int fd, int operation);
+
+#define flock(a, b) amigaos_flock((a), (b))
+
#endif