diff options
author | Andy Broad <andy@broad.ology.org.uk> | 2015-09-13 19:55:41 -0400 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2015-09-16 07:44:29 -0400 |
commit | 1cd70adfb6a06a0dc72d31fc7011592a3674b183 (patch) | |
tree | c9163447716e96f211377476cc035e79c60d72e4 /amigaos4/amigaos.c | |
parent | 738ab09f5846887e462080d6443fb8d1e751f247 (diff) | |
download | perl-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/amigaos.c')
-rw-r--r-- | amigaos4/amigaos.c | 86 |
1 files changed, 86 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; +} |