Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <errno.h>
- #include <fcntl.h>
- #include <mlvalues.h>
- #include <fail.h>
- #include "unixsupport.h"
- #include <stdio.h>
- #ifndef INVALID_SET_FILE_POINTER
- #define INVALID_SET_FILE_POINTER (-1)
- #endif
- /* Sets handle h to a position based on gohere */
- /* output, if set, is changed to the new location */
- static void set_file_pointer(HANDLE h, LARGE_INTEGER gohere, PLARGE_INTEGER output, DWORD method)
- {
- LONG high = gohere.HighPart;
- DWORD ret = SetFilePointer(h, gohere.LowPart, &high, method);
- if(ret == INVALID_SET_FILE_POINTER)
- {
- DWORD err = GetLastError();
- if(err != NO_ERROR)
- {
- win32_maperr(err);
- uerror("lockf", Nothing);
- }
- }
- if(output != NULL) {
- output->LowPart = ret;
- output->HighPart = high;
- }
- }
- CAMLprim void unix_lockf(value fd, value cmd, value span)
- {
- CAMLparam3(fd, cmd, span);
- int lock_ret;
- OVERLAPPED overlap;
- long l_len;
- HANDLE h;
- OSVERSIONINFO version;
- LARGE_INTEGER cur_position;
- LARGE_INTEGER beg_position;
- LARGE_INTEGER zero;
- LARGE_INTEGER lock_len;
- version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if(GetVersionEx(&version) == 0)
- {
- invalid_argument("lockf only supported on WIN32_NT platforms: could not determine current platform.");
- }
- if(version.dwPlatformId != VER_PLATFORM_WIN32_NT)
- {
- invalid_argument("lockf only supported on WIN32_NT platforms");
- }
- h = Handle_val(fd);
- l_len = Long_val(span);
- cur_position.HighPart = 0;
- cur_position.LowPart = 0;
- beg_position.HighPart = 0;
- beg_position.LowPart = 0;
- zero.HighPart = 0;
- zero.LowPart = 0;
- lock_len.HighPart = 0;
- lock_len.LowPart = 0;
- /* No matter what, we need the current position in the file */
- set_file_pointer(h, zero, &cur_position, FILE_CURRENT);
- if(l_len == 0)
- {
- /* Lock from cur to infinity */
- lock_len.HighPart = 4294967295;
- lock_len.LowPart = 4294967295;
- overlap.OffsetHigh = cur_position.HighPart;
- overlap.Offset = cur_position.LowPart ;
- overlap.hEvent = 0;
- }
- else if(l_len > 0)
- {
- /* positive file offset */
- lock_len.HighPart = 0;
- lock_len.LowPart = l_len;
- overlap.OffsetHigh = cur_position.HighPart;
- overlap.Offset = cur_position.LowPart ;
- }
- else
- {
- /* Negative file offset */
- lock_len.LowPart = -l_len;
- if(l_len > cur_position.LowPart && cur_position.HighPart == 0) {
- errno = EINVAL;
- uerror("lockf", Nothing);
- }
- beg_position.QuadPart = cur_position.QuadPart - lock_len.QuadPart;
- overlap.OffsetHigh = beg_position.HighPart;
- overlap.Offset = beg_position.LowPart ;
- }
- switch(Int_val(cmd))
- {
- case 0: /* F_ULOCK - unlock */
- lock_ret = UnlockFileEx(h, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
- if(lock_ret == 0)
- errno = EACCES;
- break;
- case 1: /* F_LOCK - blocking write lock */
- enter_blocking_section();
- lock_ret = LockFileEx(h, LOCKFILE_EXCLUSIVE_LOCK, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
- leave_blocking_section();
- if(lock_ret == 0)
- errno = EACCES;
- break;
- case 2: /* F_TLOCK - non-blocking write lock */
- lock_ret = LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
- if(lock_ret == 0)
- errno = EACCES;
- break;
- case 3: /* F_TEST - check whether a write lock can be obtained */
- lock_ret = LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
- if(lock_ret == 0)
- errno = EACCES;
- else
- UnlockFileEx(h, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
- break;
- case 4: /* F_RLOCK - blocking read lock */
- enter_blocking_section();
- lock_ret = LockFileEx(h, 0, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
- leave_blocking_section();
- if(lock_ret == 0)
- errno = EACCES;
- break;
- case 5: /* F_TRLOCK - non-blocking read lock */
- lock_ret = LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
- if(lock_ret == 0)
- errno = EACCES;
- break;
- default:
- errno = EINVAL;
- }
- if(lock_ret == 0)
- uerror("lockf", Nothing);
- CAMLreturn0;
- }
Add Comment
Please, Sign In to add comment