2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: getLock.c,v 1.7 1999/12/08 15:47:07 simonmar Exp $
6 * stdin/stout/stderr Runtime Support
12 #ifdef HAVE_SYS_TYPES_H
13 #include <sys/types.h>
16 #ifdef HAVE_SYS_STAT_H
29 #define FD_SETSIZE 256
38 static Lock readLock[FD_SETSIZE];
39 static Lock writeLock[FD_SETSIZE];
41 static int readLocks = 0;
42 static int writeLocks = 0;
45 lockFile(fd, for_writing, exclusive)
53 while (fstat(fd, &sb) < 0) {
58 /* fstat()ing socket fd's seems to fail with CRT's fstat(),
59 so let's just silently return and hope for the best..
66 /* Only lock regular files */
67 if (!S_ISREG(sb.st_mode))
71 /* opening a file for writing, check to see whether
72 we don't have any read locks on it already.. */
73 for (i = 0; i < readLocks; i++) {
74 if (readLock[i].inode == sb.st_ino && readLock[i].device == sb.st_dev) {
83 /* If we're determined that there is only a single
84 writer to the file, check to see whether the file
85 hasn't already been opened for writing..
88 for (i = 0; i < writeLocks; i++) {
89 if (writeLock[i].inode == sb.st_ino && writeLock[i].device == sb.st_dev) {
99 /* OK, everything is cool lock-wise, record it and leave. */
101 writeLock[i].device = sb.st_dev;
102 writeLock[i].inode = sb.st_ino;
103 writeLock[i].fd = fd;
106 /* For reading, it's simpler - just check to see
107 that there's no-one writing to the underlying file. */
108 for (i = 0; i < writeLocks; i++) {
109 if (writeLock[i].inode == sb.st_ino && writeLock[i].device == sb.st_dev) {
118 /* Fit in new entry, reusing an existing table entry, if possible. */
119 for (i = 0; i < readLocks; i++) {
120 if (readLock[i].inode == sb.st_ino && readLock[i].device == sb.st_dev) {
125 readLock[i].device = sb.st_dev;
126 readLock[i].inode = sb.st_ino;
139 for (i = 0; i < readLocks; i++)
140 if (readLock[i].fd == fd) {
141 while (++i < readLocks)
142 readLock[i - 1] = readLock[i];
147 for (i = 0; i < writeLocks; i++)
148 if (writeLock[i].fd == fd) {
149 while (++i < writeLocks)
150 writeLock[i - 1] = writeLock[i];
154 /* Signal that we did not find an entry */
158 /* getLock() is used when opening the standard file descriptors */
160 getLock(fd, for_writing)
164 if (lockFile(fd, for_writing, 0) < 0) {
175 ghc_errtype = ERR_RESOURCEBUSY;
176 ghc_errstr = "file is locked";
179 /* Not so sure we want to do this, since getLock()
180 is only called on the standard file descriptors.. */
181 /*(void) close(fd); */