Skip to content
Snippets Groups Projects
Commit 3714b76c authored by deuce's avatar deuce
Browse files

Fix locking for BSD / FreeBSD w/Deuces sane fcntl() kernel hack.

Add more locking tests to wraptest.c
parent afa6e86c
Branches
Tags
No related merge requests found
......@@ -83,9 +83,11 @@ long DLLCALL filelength(int fd)
/* Sets a lock on a portion of a file */
int DLLCALL lock(int fd, long pos, int len)
{
int flags;
#if defined(F_SANERDLCKNO) || !defined(BSD)
struct flock alock;
#ifndef F_SANEWRLCKNO
int flags;
if((flags=fcntl(fd,F_GETFL))==-1)
return -1;
......@@ -93,16 +95,22 @@ int DLLCALL lock(int fd, long pos, int len)
alock.l_type = F_RDLCK; /* set read lock to prevent writes */
else
alock.l_type = F_WRLCK; /* set write lock to prevent all access */
#else
alock.l_type = F_SANEWRLCKNO;
#endif
alock.l_whence = L_SET; /* SEEK_SET */
alock.l_start = pos;
alock.l_len = len;
if(fcntl(fd, F_SETLK, &alock)==-1)
return(-1);
#endif
#ifndef F_SANEWRLCKNO
/* use flock (doesn't work over NFS) */
if(flock(fd,LOCK_EX|LOCK_NB)!=0)
return(-1);
#endif
return(0);
}
......@@ -110,18 +118,26 @@ int DLLCALL lock(int fd, long pos, int len)
/* Removes a lock from a file record */
int DLLCALL unlock(int fd, long pos, int len)
{
struct flock alock;
#if defined(F_SANEUNLCK) || !defined(BSD)
struct flock alock;
#ifdef F_SANEUNLCK
alock.l_type = F_SANEUNLCK; /* remove the lock */
#else
alock.l_type = F_UNLCK; /* remove the lock */
#endif
alock.l_whence = L_SET;
alock.l_start = pos;
alock.l_len = len;
if(fcntl(fd, F_SETLK, &alock)==-1)
return(-1);
#endif
#ifndef F_SANEUNLCK
/* use flock (doesn't work over NFS) */
if(flock(fd,LOCK_UN|LOCK_NB)!=0)
return(-1);
#endif
return(0);
}
......@@ -130,7 +146,9 @@ int DLLCALL unlock(int fd, long pos, int len)
int DLLCALL sopen(char *fn, int access, int share)
{
int fd;
#ifndef F_SANEWRLCKNO
int flock_op=LOCK_NB; /* non-blocking */
#endif
struct flock alock;
if ((fd = open(fn, access, S_IREAD|S_IWRITE)) < 0)
......@@ -139,6 +157,20 @@ int DLLCALL sopen(char *fn, int access, int share)
if (share == SH_DENYNO) /* no lock needed */
return fd;
#if defined(F_SANEWRLCKNO) || !defined(BSD)
/* use fcntl (doesn't work correctly with threads) */
alock.l_type = share;
alock.l_whence = L_SET;
alock.l_start = 0;
alock.l_len = 0; /* lock to EOF */
if(fcntl(fd, F_SETLK, &alock)==-1) {
close(fd);
return -1;
}
#endif
#ifndef F_SANEWRLCKNO
/* use flock (doesn't work over NFS) */
if(share==SH_DENYRW)
flock_op|=LOCK_EX;
......@@ -150,17 +182,7 @@ int DLLCALL sopen(char *fn, int access, int share)
close(fd);
return(-1);
}
/* use fcntl (doesn't work correctly with threads) */
alock.l_type = share;
alock.l_whence = L_SET;
alock.l_start = 0;
alock.l_len = 0; /* lock to EOF */
if(fcntl(fd, F_SETLK, &alock)==-1) {
close(fd);
return -1;
}
#endif
return fd;
}
......
......@@ -78,8 +78,17 @@
#define O_DENYNONE (1<<31) /* req'd for Baja/nopen compatibility */
#define SH_DENYNO 2 // no locks
#ifdef F_SANEWRLCKNO
#define SH_DENYRW F_SANEWRLCKNO // exclusive lock
#else
#define SH_DENYRW F_WRLCK // exclusive lock
#endif
#ifdef F_SANERDLCKNO
#define SH_DENYWR F_SANERDLCKNO // shareable lock
#else
#define SH_DENYWR F_RDLCK // shareable lock
#endif
#define chsize(fd,size) ftruncate(fd,size)
#define tell(fd) lseek(fd,0,SEEK_CUR)
......
......@@ -46,6 +46,7 @@ int main()
DIRENT* dirent;
thread_data_t thread_data;
int fd;
int fd2;
/* Show platform details */
DESCRIBE_COMPILER(compiler);
......@@ -115,6 +116,21 @@ int main()
printf("!FAILURE file locking\n");
else
printf("SUCCESS! Record locking\n");
if((fd2=sopen(LOCK_FNAME,O_RDWR,SH_DENYRW))!=-1) {
printf("SUCCESS! Cannot reopen SH_DENYRW while lock is held\n");
close(fd2);
}
else {
printf("!FAILURE can reopen SH_DENYRW while lock is held\n");
}
if(unlock(fd,LOCK_OFFSET,LOCK_LEN))
printf("!FAILURE unlock() non-functional\n");
if(lock(fd,LOCK_OFFSET+LOCK_LEN+1,LOCK_LEN))
printf("SUCCESS! Cannot re-lock after non-overlapping unlock()\n");
else
printf("!FAILURE can re-lock after non-overlappping unlock()\n");
if(lock(fd,LOCK_OFFSET,LOCK_LEN))
printf("!FAILURE cannot re-lock unlocked area\n");
close(fd);
/* getch test */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment