diff options
Diffstat (limited to 'ghc/lib/std/cbits/lockFile.c')
-rw-r--r-- | ghc/lib/std/cbits/lockFile.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/ghc/lib/std/cbits/lockFile.c b/ghc/lib/std/cbits/lockFile.c new file mode 100644 index 0000000000..14a0a38854 --- /dev/null +++ b/ghc/lib/std/cbits/lockFile.c @@ -0,0 +1,115 @@ +/* + * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998 + * + * $Id: lockFile.c,v 1.1 2001/05/18 16:54:06 simonmar Exp $ + * + * stdin/stout/stderr Runtime Support + */ + +#include "HsStd.h" + +#ifndef FD_SETSIZE +#define FD_SETSIZE 256 +#endif + +typedef struct { + dev_t device; + ino_t inode; + int fd; +} Lock; + +static Lock readLock[FD_SETSIZE]; +static Lock writeLock[FD_SETSIZE]; + +static int readLocks = 0; +static int writeLocks = 0; + +int +lockFile(int fd, int for_writing, int exclusive) +{ + int i; + struct stat sb; + + if (for_writing) { + /* opening a file for writing, check to see whether + we don't have any read locks on it already.. */ + for (i = 0; i < readLocks; i++) { + if (readLock[i].inode == sb.st_ino && readLock[i].device == sb.st_dev) { +#ifndef __MINGW32__ + return -1; +#else + break; +#endif + } + } + /* If we're determined that there is only a single + writer to the file, check to see whether the file + hasn't already been opened for writing.. + */ + if (exclusive) { + for (i = 0; i < writeLocks; i++) { + if (writeLock[i].inode == sb.st_ino && writeLock[i].device == sb.st_dev) { +#ifndef __MINGW32__ + return -1; +#else + break; +#endif + } + } + } + /* OK, everything is cool lock-wise, record it and leave. */ + i = writeLocks++; + writeLock[i].device = sb.st_dev; + writeLock[i].inode = sb.st_ino; + writeLock[i].fd = fd; + return 0; + } else { + /* For reading, it's simpler - just check to see + that there's no-one writing to the underlying file. */ + for (i = 0; i < writeLocks; i++) { + if (writeLock[i].inode == sb.st_ino && writeLock[i].device == sb.st_dev) { +#ifndef __MINGW32__ + return -1; +#else + break; +#endif + } + } + /* Fit in new entry, reusing an existing table entry, if possible. */ + for (i = 0; i < readLocks; i++) { + if (readLock[i].inode == sb.st_ino && readLock[i].device == sb.st_dev) { + return 0; + } + } + i = readLocks++; + readLock[i].device = sb.st_dev; + readLock[i].inode = sb.st_ino; + readLock[i].fd = fd; + return 0; + } + +} + +int +unlockFile(int fd) +{ + int i; + + for (i = 0; i < readLocks; i++) + if (readLock[i].fd == fd) { + while (++i < readLocks) + readLock[i - 1] = readLock[i]; + readLocks--; + return 0; + } + + for (i = 0; i < writeLocks; i++) + if (writeLock[i].fd == fd) { + while (++i < writeLocks) + writeLock[i - 1] = writeLock[i]; + writeLocks--; + return 0; + } + /* Signal that we did not find an entry */ + return 1; +} |