1b528cefcSMark Murray /*
2*ae771770SStanislav Sedov * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray * All rights reserved.
5b528cefcSMark Murray *
6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray * modification, are permitted provided that the following conditions
8b528cefcSMark Murray * are met:
9b528cefcSMark Murray *
10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray *
13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray * documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray *
17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray * may be used to endorse or promote products derived from this software
19b528cefcSMark Murray * without specific prior written permission.
20b528cefcSMark Murray *
21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray * SUCH DAMAGE.
32b528cefcSMark Murray */
33b528cefcSMark Murray
34b528cefcSMark Murray #include <config.h>
35b528cefcSMark Murray
36b528cefcSMark Murray #ifndef HAVE_FLOCK
37b528cefcSMark Murray
38b528cefcSMark Murray #include "roken.h"
39b528cefcSMark Murray
40b528cefcSMark Murray #define OP_MASK (LOCK_SH | LOCK_EX | LOCK_UN)
41b528cefcSMark Murray
42*ae771770SStanislav Sedov
43*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rk_flock(int fd,int operation)44*ae771770SStanislav Sedov rk_flock(int fd, int operation)
45b528cefcSMark Murray {
46b528cefcSMark Murray #if defined(HAVE_FCNTL) && defined(F_SETLK)
47b528cefcSMark Murray struct flock arg;
48b528cefcSMark Murray int code, cmd;
49b528cefcSMark Murray
50b528cefcSMark Murray arg.l_whence = SEEK_SET;
51b528cefcSMark Murray arg.l_start = 0;
52b528cefcSMark Murray arg.l_len = 0; /* means to EOF */
53b528cefcSMark Murray
54b528cefcSMark Murray if (operation & LOCK_NB)
55b528cefcSMark Murray cmd = F_SETLK;
56b528cefcSMark Murray else
57b528cefcSMark Murray cmd = F_SETLKW; /* Blocking */
58b528cefcSMark Murray
59b528cefcSMark Murray switch (operation & OP_MASK) {
60b528cefcSMark Murray case LOCK_UN:
61b528cefcSMark Murray arg.l_type = F_UNLCK;
62b528cefcSMark Murray code = fcntl(fd, F_SETLK, &arg);
63b528cefcSMark Murray break;
64b528cefcSMark Murray case LOCK_SH:
65b528cefcSMark Murray arg.l_type = F_RDLCK;
66b528cefcSMark Murray code = fcntl(fd, cmd, &arg);
67b528cefcSMark Murray break;
68b528cefcSMark Murray case LOCK_EX:
69b528cefcSMark Murray arg.l_type = F_WRLCK;
70b528cefcSMark Murray code = fcntl(fd, cmd, &arg);
71b528cefcSMark Murray break;
72b528cefcSMark Murray default:
73b528cefcSMark Murray errno = EINVAL;
74b528cefcSMark Murray code = -1;
75b528cefcSMark Murray break;
76b528cefcSMark Murray }
77b528cefcSMark Murray return code;
78*ae771770SStanislav Sedov
79*ae771770SStanislav Sedov #elif defined(_WIN32)
80*ae771770SStanislav Sedov /* Windows */
81*ae771770SStanislav Sedov
82*ae771770SStanislav Sedov #define FLOCK_OFFSET_LOW 0
83*ae771770SStanislav Sedov #define FLOCK_OFFSET_HIGH 0
84*ae771770SStanislav Sedov #define FLOCK_LENGTH_LOW 0x00000000
85*ae771770SStanislav Sedov #define FLOCK_LENGTH_HIGH 0x80000000
86*ae771770SStanislav Sedov
87*ae771770SStanislav Sedov HANDLE hFile;
88*ae771770SStanislav Sedov OVERLAPPED ov;
89*ae771770SStanislav Sedov BOOL rv = FALSE;
90*ae771770SStanislav Sedov DWORD f = 0;
91*ae771770SStanislav Sedov
92*ae771770SStanislav Sedov hFile = (HANDLE) _get_osfhandle(fd);
93*ae771770SStanislav Sedov if (hFile == NULL || hFile == INVALID_HANDLE_VALUE) {
94*ae771770SStanislav Sedov _set_errno(EBADF);
95*ae771770SStanislav Sedov return -1;
96*ae771770SStanislav Sedov }
97*ae771770SStanislav Sedov
98*ae771770SStanislav Sedov ZeroMemory(&ov, sizeof(ov));
99*ae771770SStanislav Sedov ov.hEvent = NULL;
100*ae771770SStanislav Sedov ov.Offset = FLOCK_OFFSET_LOW;
101*ae771770SStanislav Sedov ov.OffsetHigh = FLOCK_OFFSET_HIGH;
102*ae771770SStanislav Sedov
103*ae771770SStanislav Sedov if (operation & LOCK_NB)
104*ae771770SStanislav Sedov f = LOCKFILE_FAIL_IMMEDIATELY;
105*ae771770SStanislav Sedov
106*ae771770SStanislav Sedov switch (operation & OP_MASK) {
107*ae771770SStanislav Sedov case LOCK_UN: /* Unlock */
108*ae771770SStanislav Sedov rv = UnlockFileEx(hFile, 0,
109*ae771770SStanislav Sedov FLOCK_LENGTH_LOW, FLOCK_LENGTH_HIGH, &ov);
110*ae771770SStanislav Sedov break;
111*ae771770SStanislav Sedov
112*ae771770SStanislav Sedov case LOCK_SH: /* Shared lock */
113*ae771770SStanislav Sedov rv = LockFileEx(hFile, f, 0,
114*ae771770SStanislav Sedov FLOCK_LENGTH_LOW, FLOCK_LENGTH_HIGH, &ov);
115*ae771770SStanislav Sedov break;
116*ae771770SStanislav Sedov
117*ae771770SStanislav Sedov case LOCK_EX: /* Exclusive lock */
118*ae771770SStanislav Sedov rv = LockFileEx(hFile, f|LOCKFILE_EXCLUSIVE_LOCK, 0,
119*ae771770SStanislav Sedov FLOCK_LENGTH_LOW, FLOCK_LENGTH_HIGH,
120*ae771770SStanislav Sedov &ov);
121*ae771770SStanislav Sedov break;
122*ae771770SStanislav Sedov
123*ae771770SStanislav Sedov default:
124*ae771770SStanislav Sedov _set_errno(EINVAL);
125*ae771770SStanislav Sedov return -1;
126*ae771770SStanislav Sedov }
127*ae771770SStanislav Sedov
128*ae771770SStanislav Sedov if (!rv) {
129*ae771770SStanislav Sedov switch (GetLastError()) {
130*ae771770SStanislav Sedov case ERROR_SHARING_VIOLATION:
131*ae771770SStanislav Sedov case ERROR_LOCK_VIOLATION:
132*ae771770SStanislav Sedov case ERROR_IO_PENDING:
133*ae771770SStanislav Sedov _set_errno(EWOULDBLOCK);
134*ae771770SStanislav Sedov break;
135*ae771770SStanislav Sedov
136*ae771770SStanislav Sedov case ERROR_ACCESS_DENIED:
137*ae771770SStanislav Sedov _set_errno(EACCES);
138*ae771770SStanislav Sedov break;
139*ae771770SStanislav Sedov
140*ae771770SStanislav Sedov default:
141*ae771770SStanislav Sedov _set_errno(ENOLCK);
142*ae771770SStanislav Sedov }
143*ae771770SStanislav Sedov return -1;
144*ae771770SStanislav Sedov }
145*ae771770SStanislav Sedov
146*ae771770SStanislav Sedov return 0;
147*ae771770SStanislav Sedov
148b528cefcSMark Murray #else
149b528cefcSMark Murray return -1;
150b528cefcSMark Murray #endif
151b528cefcSMark Murray }
152b528cefcSMark Murray
153b528cefcSMark Murray #endif
154b528cefcSMark Murray
155