/*1* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#include <config.h>3435#ifndef HAVE_FLOCK3637#include "roken.h"3839#define OP_MASK (LOCK_SH | LOCK_EX | LOCK_UN)404142ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL43rk_flock(int fd, int operation)44{45#if defined(HAVE_FCNTL) && defined(F_SETLK)46struct flock arg;47int code, cmd;4849arg.l_whence = SEEK_SET;50arg.l_start = 0;51arg.l_len = 0; /* means to EOF */5253if (operation & LOCK_NB)54cmd = F_SETLK;55else56cmd = F_SETLKW; /* Blocking */5758switch (operation & OP_MASK) {59case LOCK_UN:60arg.l_type = F_UNLCK;61code = fcntl(fd, F_SETLK, &arg);62break;63case LOCK_SH:64arg.l_type = F_RDLCK;65code = fcntl(fd, cmd, &arg);66break;67case LOCK_EX:68arg.l_type = F_WRLCK;69code = fcntl(fd, cmd, &arg);70break;71default:72errno = EINVAL;73code = -1;74break;75}76return code;7778#elif defined(_WIN32)79/* Windows */8081#define FLOCK_OFFSET_LOW 082#define FLOCK_OFFSET_HIGH 083#define FLOCK_LENGTH_LOW 0x0000000084#define FLOCK_LENGTH_HIGH 0x800000008586HANDLE hFile;87OVERLAPPED ov;88BOOL rv = FALSE;89DWORD f = 0;9091hFile = (HANDLE) _get_osfhandle(fd);92if (hFile == NULL || hFile == INVALID_HANDLE_VALUE) {93_set_errno(EBADF);94return -1;95}9697ZeroMemory(&ov, sizeof(ov));98ov.hEvent = NULL;99ov.Offset = FLOCK_OFFSET_LOW;100ov.OffsetHigh = FLOCK_OFFSET_HIGH;101102if (operation & LOCK_NB)103f = LOCKFILE_FAIL_IMMEDIATELY;104105switch (operation & OP_MASK) {106case LOCK_UN: /* Unlock */107rv = UnlockFileEx(hFile, 0,108FLOCK_LENGTH_LOW, FLOCK_LENGTH_HIGH, &ov);109break;110111case LOCK_SH: /* Shared lock */112rv = LockFileEx(hFile, f, 0,113FLOCK_LENGTH_LOW, FLOCK_LENGTH_HIGH, &ov);114break;115116case LOCK_EX: /* Exclusive lock */117rv = LockFileEx(hFile, f|LOCKFILE_EXCLUSIVE_LOCK, 0,118FLOCK_LENGTH_LOW, FLOCK_LENGTH_HIGH,119&ov);120break;121122default:123_set_errno(EINVAL);124return -1;125}126127if (!rv) {128switch (GetLastError()) {129case ERROR_SHARING_VIOLATION:130case ERROR_LOCK_VIOLATION:131case ERROR_IO_PENDING:132_set_errno(EWOULDBLOCK);133break;134135case ERROR_ACCESS_DENIED:136_set_errno(EACCES);137break;138139default:140_set_errno(ENOLCK);141}142return -1;143}144145return 0;146147#else148return -1;149#endif150}151152#endif153154155156