[project @ 2001-05-18 14:18:34 by simonmar]
[ghc-hetmet.git] / ghc / lib / std / cbits / lockFile.c
1 /* 
2  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
3  *
4  * $Id: lockFile.c,v 1.1 2001/05/18 16:54:06 simonmar Exp $
5  *
6  * stdin/stout/stderr Runtime Support
7  */
8
9 #include "HsStd.h"
10
11 #ifndef FD_SETSIZE
12 #define FD_SETSIZE 256
13 #endif
14
15 typedef struct {
16     dev_t device;
17     ino_t inode;
18     int fd;
19 } Lock;
20
21 static Lock readLock[FD_SETSIZE];
22 static Lock writeLock[FD_SETSIZE];
23
24 static int readLocks = 0;
25 static int writeLocks = 0;
26
27 int
28 lockFile(int fd, int for_writing, int exclusive)
29 {
30     int i;
31     struct stat sb;
32
33     if (for_writing) {
34       /* opening a file for writing, check to see whether
35          we don't have any read locks on it already.. */
36       for (i = 0; i < readLocks; i++) {
37          if (readLock[i].inode == sb.st_ino && readLock[i].device == sb.st_dev) {
38 #ifndef __MINGW32__
39             return -1;
40 #else
41             break;    
42 #endif
43          }          
44       }
45       /* If we're determined that there is only a single
46          writer to the file, check to see whether the file
47          hasn't already been opened for writing..
48       */
49       if (exclusive) {
50         for (i = 0; i < writeLocks; i++) {
51           if (writeLock[i].inode == sb.st_ino && writeLock[i].device == sb.st_dev) {
52 #ifndef __MINGW32__
53              return -1;
54 #else
55              break;
56 #endif
57           }
58         }
59       }
60       /* OK, everything is cool lock-wise, record it and leave. */
61       i = writeLocks++;
62       writeLock[i].device = sb.st_dev;
63       writeLock[i].inode = sb.st_ino;
64       writeLock[i].fd = fd;
65       return 0;
66     } else { 
67       /* For reading, it's simpler - just check to see
68          that there's no-one writing to the underlying file. */
69       for (i = 0; i < writeLocks; i++) {
70         if (writeLock[i].inode == sb.st_ino && writeLock[i].device == sb.st_dev) {
71 #ifndef __MINGW32__
72              return -1;
73 #else
74              break;
75 #endif
76         }
77       }
78       /* Fit in new entry, reusing an existing table entry, if possible. */
79       for (i = 0; i < readLocks; i++) {
80          if (readLock[i].inode == sb.st_ino && readLock[i].device == sb.st_dev) {
81            return 0;
82          }
83       }
84       i = readLocks++;
85       readLock[i].device = sb.st_dev;
86       readLock[i].inode = sb.st_ino;
87       readLock[i].fd = fd;
88       return 0;
89     }
90
91 }
92
93 int
94 unlockFile(int fd)
95 {
96     int i;
97
98     for (i = 0; i < readLocks; i++)
99         if (readLock[i].fd == fd) {
100             while (++i < readLocks)
101                 readLock[i - 1] = readLock[i];
102             readLocks--;
103             return 0;
104         }
105
106     for (i = 0; i < writeLocks; i++)
107         if (writeLock[i].fd == fd) {
108             while (++i < writeLocks)
109                 writeLock[i - 1] = writeLock[i];
110             writeLocks--;
111             return 0;
112         }
113      /* Signal that we did not find an entry */
114     return 1;
115 }