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 sytems 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
27int
28flock(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 sytems 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
92int
93flock(int fd, int operation)
94{
95    switch (operation) {
96
97	/* LOCK_SH - get a shared lock */
98      case LOCK_SH:
99        rb_notimplement();
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
124int
125flock(int fd, int operation)
126{
127    rb_notimplement();
128    return -1;
129}
130#endif
131