From b8d3ceda7ef802e0269bd0268fc71202d7bef52d Mon Sep 17 00:00:00 2001 From: sszymczy Date: Thu, 16 Oct 2008 01:09:34 +0000 Subject: [PATCH] Implemented 4.4BSD flock() function needed for autotools along with a test utility. git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@29766 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- compiler/clib/arosc_functable.c | 1 + compiler/clib/flock.c | 173 ++++++++++++++++++++++++++++++++++ compiler/clib/include/sys/file.h | 33 +++++++ compiler/clib/include/sys/syscall.def | 1 + compiler/clib/mmakefile.src | 1 + 5 files changed, 209 insertions(+) create mode 100644 compiler/clib/flock.c create mode 100644 compiler/clib/include/sys/file.h diff --git a/compiler/clib/arosc_functable.c b/compiler/clib/arosc_functable.c index e9da8b6c1e..0da8abc0b5 100644 --- a/compiler/clib/arosc_functable.c +++ b/compiler/clib/arosc_functable.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/compiler/clib/flock.c b/compiler/clib/flock.c new file mode 100644 index 0000000000..520ceb4827 --- /dev/null +++ b/compiler/clib/flock.c @@ -0,0 +1,173 @@ +/* + Copyright © 2008, The AROS Development Team. All rights reserved. + $Id$ + + 4.4BSD function flock(). +*/ + +#define DEBUG 0 +#include +#include +#include +#include +#include + +#include + +#include "__open.h" +#include "__errno.h" + +/***************************************************************************** + + NAME */ +#include + + int flock ( + +/* SYNOPSIS */ + int fd, + int operation) + +/* FUNCTION + + INPUTS + + RESULT + + NOTES + + EXAMPLE + + BUGS + + SEE ALSO + + INTERNALS + +******************************************************************************/ +{ + fdesc *fdesc = __getfdesc(fd); + char *buffer; + int buffersize = 256; + struct SignalSemaphore *sem; + + D(bug("flock(%d, %d)\n", fd, operation)); + if (!fdesc) + { + errno = EBADF; + return -1; + } + + /* Sanity check */ + if( + (operation & ~LOCK_NB) != LOCK_SH && + (operation & ~LOCK_NB) != LOCK_EX && + (operation & ~LOCK_NB) != LOCK_UN + ) + { + errno = EINVAL; + return -1; + } + + /* Get the full path of the flocked filesystem object */ + do + { + if(!(buffer = AllocVec(buffersize, MEMF_ANY))) + { + errno = IoErr2errno(IoErr()); + return -1; + } + + if(NameFromLock(fdesc->fcb->fh, (STRPTR) ((IPTR) buffer + 6), buffersize - 7)) + break; + else if(IoErr() != ERROR_LINE_TOO_LONG) + { + errno = IoErr2errno(IoErr()); + FreeVec(buffer); + return -1; + } + FreeVec(buffer); + buffersize *= 2; + } + while(TRUE); + + CopyMem("FLOCK(", buffer, strlen("FLOCK(")); + buffer[strlen(buffer) + 1] = '\0'; + buffer[strlen(buffer)] = ')'; + + D(bug("[flock] Semaphore name: %s\n", buffer)); + + /* Find semaphore named FLOCK(path), add a new one if not found any */ + Forbid(); + sem = FindSemaphore((STRPTR) buffer); + if(!sem) + { + D(bug("[flock] Semaphore %s not found, creating a new one\n", buffer)); + sem = (struct SignalSemaphore*) + AllocVec(sizeof(struct SignalSemaphore), MEMF_PUBLIC|MEMF_CLEAR); + if(!sem) + { + errno = ENOMEM; + Permit(); + return -1; + } + sem->ss_Link.ln_Name = buffer; + AddSemaphore(sem); + } + else + { + D(bug("[flock] Semaphore %s found, freeing buffer\n", buffer)); + FreeVec(buffer); + } + + if(operation & LOCK_UN) + { + D(bug("[flock] Releasing semaphore %s\n", sem->ss_Link.ln_Name)); + ReleaseSemaphore(sem); + if(sem->ss_Owner == NULL && sem->ss_QueueCount == -1) + { + D(bug("[flock] All locks unlocked, removing semaphore %s\n", sem->ss_Link.ln_Name)); + /* All locks for this file were unlocked, we don't need semaphore + * anymore */ + RemSemaphore(sem); + FreeVec(sem->ss_Link.ln_Name); + FreeVec(sem); + Permit(); + return 0; + } + } + Permit(); + + switch(operation & ~LOCK_NB) + { + case LOCK_SH: + D(bug("[flock] Obtaining shared lock\n")); + if(operation & LOCK_NB) + { + if(!AttemptSemaphoreShared(sem)) + { + errno = EWOULDBLOCK; + return -1; + } + } + else + ObtainSemaphoreShared(sem); + D(bug("[flock] Shared lock obtained\n")); + break; + case LOCK_EX: + D(bug("[flock] Obtaining exclusive lock\n")); + if(operation & LOCK_NB) + { + if(!AttemptSemaphore(sem)) + { + errno = EWOULDBLOCK; + return -1; + } + } + else + ObtainSemaphore(sem); + D(bug("[flock] Exclusive lock obtained\n")); + break; + } + return 0; +} diff --git a/compiler/clib/include/sys/file.h b/compiler/clib/include/sys/file.h new file mode 100644 index 0000000000..15bcc31108 --- /dev/null +++ b/compiler/clib/include/sys/file.h @@ -0,0 +1,33 @@ +#ifndef _SYS__FILE_H_ +#define _SYS__FILE_H_ +/* + Copyright © 2008, The AROS Development Team. All rights reserved. + $Id$ + + Desc: 4.4BSD header file sys/stat.h + Lang: english +*/ + +/* flock() operations */ + +#ifndef SYS_TYPES_H +#include +#endif + +#define LOCK_SH 1 /* Shared lock. */ +#define LOCK_EX 2 /* Exclusive lock. */ +#define LOCK_UN 8 /* Unlock. */ + +/* operation modifiers (combined with OR) */ + +#define LOCK_NB 4 /* Non-blocking operation */ + +/* function declarations */ + +__BEGIN_DECLS + +int flock (int fd, int operation); + +__END_DECLS + +#endif /* _SYS__FILE_H_ */ diff --git a/compiler/clib/include/sys/syscall.def b/compiler/clib/include/sys/syscall.def index 1fc143021e..923f98d8aa 100644 --- a/compiler/clib/include/sys/syscall.def +++ b/compiler/clib/include/sys/syscall.def @@ -259,3 +259,4 @@ SYSTEM_CALL (vfork) SYSTEM_CALL (waitpid) SYSTEM_CALL (execv) SYSTEM_CALL (execlp) +SYSTEM_CALL (flock) diff --git a/compiler/clib/mmakefile.src b/compiler/clib/mmakefile.src index c857f6a5c4..31706d3327 100644 --- a/compiler/clib/mmakefile.src +++ b/compiler/clib/mmakefile.src @@ -164,6 +164,7 @@ SHARED := \ fgetpos \ fgets \ fileno \ + flock \ fopen \ fprintf \ fscanf \ -- 2.11.4.GIT