xref: /freebsd/crypto/heimdal/lib/roken/flock.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
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