diff options
Diffstat (limited to 'src/port/lockf.c')
-rw-r--r-- | src/port/lockf.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/port/lockf.c b/src/port/lockf.c new file mode 100644 index 0000000..09c613e --- /dev/null +++ b/src/port/lockf.c @@ -0,0 +1,62 @@ +#include "lockf.h" + +#include "string.h" /* for memset */ +#include "unistd.h" /* for getpid */ + +#if !defined HAVE_LOCKF + +#include <sys/types.h> /* for off_t */ +#include <errno.h> /* for errno */ + +int lockf( int fd, int cmd, off_t len ) { + struct flock fl; + + memset( (char *)&fl, 0, sizeof( fl ) ); + /* lockf is always relative to the current file position. */ + fl.l_whence = SEEK_CUR; + fl.l_start = 0; + fl.l_len = len; + + errno = 0; + + switch( cmd ) { + case F_TEST: + fl.l_type = F_RDLCK; + if( fcntl( fd, F_GETLK, &fl ) < 0 ) { + return -1; + } + if( fl.l_type == F_UNLCK || + fl.l_pid == getpid( ) ) { + return 0; + } + errno = EACCES; + return -1; + + case F_ULOCK: + fl.l_type = F_UNLCK; + cmd = F_SETLK; + break; + + case F_LOCK: + fl.l_type = F_WRLCK; + cmd = F_SETLKW; + break; + + case F_TLOCK: + fl.l_type = F_WRLCK; + cmd = F_SETLK; + break; + + default: + errno = EINVAL; + return -1; + } + + return fcntl( fd, cmd, &fl ); +} + +#else + +extern int dummy; /* prevent ISO C forbids an empty source file' warning */ + +#endif /* !defined HAVE_LOCKF */ |