Ruby  2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)
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
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
flock
Definition: rb_mjit_min_header-2.7.0.h:1401
F_TLOCK
#define F_TLOCK
Definition: rb_mjit_min_header-2.7.0.h:3290
flock
int flock(int fd, int operation)
Definition: flock.c:125
LOCK_SH
#define LOCK_SH
Definition: file.c:5055
fcntl
int fcntl(int, int,...)
Definition: win32.c:4282
ruby.h
L
#define L(x)
Definition: asm.h:125
rb_notimplement
void rb_notimplement(void)
Definition: error.c:2712
lockf
int lockf(int __fd, int __cmd, off_t __len)
F_LOCK
#define F_LOCK
Definition: rb_mjit_min_header-2.7.0.h:3289
F_ULOCK
#define F_ULOCK
Definition: rb_mjit_min_header-2.7.0.h:3288
EINVAL
#define EINVAL
Definition: rb_mjit_min_header-2.7.0.h:10959
LOCK_UN
#define LOCK_UN
Definition: file.c:5064
LOCK_EX
#define LOCK_EX
Definition: file.c:5058
SEEK_SET
#define SEEK_SET
Definition: io.c:865
errno
int errno
LOCK_NB
#define LOCK_NB
Definition: file.c:5061