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