Ruby  2.5.0dev(2017-10-22revision60238)
flock.c
Go to the documentation of this file.
1 #include "ruby/config.h"
2 #include "ruby/ruby.h"
3 
4 #if defined _WIN32
5 #elif defined HAVE_FCNTL && defined HAVE_FCNTL_H && !defined(__native_client__)
6 
7 /* These are the flock() constants. Since this systems doesn't have
8  flock(), the values of the constants are probably not available.
9 */
10 # ifndef LOCK_SH
11 # define LOCK_SH 1
12 # endif
13 # ifndef LOCK_EX
14 # define LOCK_EX 2
15 # endif
16 # ifndef LOCK_NB
17 # define LOCK_NB 4
18 # endif
19 # ifndef LOCK_UN
20 # define LOCK_UN 8
21 # endif
22 
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include <errno.h>
26 
27 int
28 flock(int fd, int operation)
29 {
30  struct flock lock;
31 
32  switch (operation & ~LOCK_NB) {
33  case LOCK_SH:
34  lock.l_type = F_RDLCK;
35  break;
36  case LOCK_EX:
37  lock.l_type = F_WRLCK;
38  break;
39  case LOCK_UN:
40  lock.l_type = F_UNLCK;
41  break;
42  default:
43  errno = EINVAL;
44  return -1;
45  }
46  lock.l_whence = SEEK_SET;
47  lock.l_start = lock.l_len = 0L;
48 
49  return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &lock);
50 }
51 
52 #elif defined(HAVE_LOCKF)
53 
54 #include <unistd.h>
55 #include <errno.h>
56 
57 /* Emulate flock() with lockf() or fcntl(). This is just to increase
58  portability of scripts. The calls might not be completely
59  interchangeable. What's really needed is a good file
60  locking module.
61 */
62 
63 # ifndef F_ULOCK
64 # define F_ULOCK 0 /* Unlock a previously locked region */
65 # endif
66 # ifndef F_LOCK
67 # define F_LOCK 1 /* Lock a region for exclusive use */
68 # endif
69 # ifndef F_TLOCK
70 # define F_TLOCK 2 /* Test and lock a region for exclusive use */
71 # endif
72 # ifndef F_TEST
73 # define F_TEST 3 /* Test a region for other processes locks */
74 # endif
75 
76 /* These are the flock() constants. Since this systems doesn't have
77  flock(), the values of the constants are probably not available.
78 */
79 # ifndef LOCK_SH
80 # define LOCK_SH 1
81 # endif
82 # ifndef LOCK_EX
83 # define LOCK_EX 2
84 # endif
85 # ifndef LOCK_NB
86 # define LOCK_NB 4
87 # endif
88 # ifndef LOCK_UN
89 # define LOCK_UN 8
90 # endif
91 
92 int
93 flock(int fd, int operation)
94 {
95  switch (operation) {
96 
97  /* LOCK_SH - get a shared lock */
98  case LOCK_SH:
100  return -1;
101  /* LOCK_EX - get an exclusive lock */
102  case LOCK_EX:
103  return lockf (fd, F_LOCK, 0);
104 
105  /* LOCK_SH|LOCK_NB - get a non-blocking shared lock */
106  case LOCK_SH|LOCK_NB:
107  rb_notimplement();
108  return -1;
109  /* LOCK_EX|LOCK_NB - get a non-blocking exclusive lock */
110  case LOCK_EX|LOCK_NB:
111  return lockf (fd, F_TLOCK, 0);
112 
113  /* LOCK_UN - unlock */
114  case LOCK_UN:
115  return lockf (fd, F_ULOCK, 0);
116 
117  /* Default - can't decipher operation */
118  default:
119  errno = EINVAL;
120  return -1;
121  }
122 }
123 #else
124 int
125 flock(int fd, int operation)
126 {
127  rb_notimplement();
128  return -1;
129 }
130 #endif
int fcntl(int, int,...)
Definition: win32.c:4297
#define LOCK_NB
Definition: file.c:4703
#define LOCK_EX
Definition: file.c:4700
#define LOCK_UN
Definition: file.c:4706
int flock(int fd, int operation)
Definition: flock.c:125
void rb_notimplement(void)
Definition: error.c:2330
#define LOCK_SH
Definition: file.c:4697
int errno
#define SEEK_SET
Definition: io.c:790