This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
amigaos4: implement flock() emulation
authorAndy Broad <andy@broad.ology.org.uk>
Sun, 13 Sep 2015 23:55:41 +0000 (19:55 -0400)
committerJarkko Hietaniemi <jhi@iki.fi>
Wed, 16 Sep 2015 11:44:29 +0000 (07:44 -0400)
Beware: not an exact implementation, the locks follow the OS level
filehandle not the process.

README.amiga
amigaos4/amigaos.c
amigaos4/amigaos.h

index 0e6358d..934b037 100644 (file)
@@ -178,6 +178,9 @@ This will build the default setup that installs under SDK:local/newlib/lib/
 
 =item Fix issue with newlib's unlink, which could cause infinite loops.
 
+=item Add flock() emulation using IDOS->LockRecord thanks to Tony Cook
+for the suggestion.
+
 =back
 
 =item B<27th November 2013>
index 8e26064..f799430 100644 (file)
@@ -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;
+}
index 96f521d..2f6d4b2 100644 (file)
@@ -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