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 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