Guest User

Untitled

a guest
Feb 17th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.10 KB | None | 0 0
  1. #include <errno.h>
  2. #include <fcntl.h>
  3. #include <mlvalues.h>
  4. #include <fail.h>
  5. #include "unixsupport.h"
  6. #include <stdio.h>
  7.  
  8. #ifndef INVALID_SET_FILE_POINTER
  9. #define INVALID_SET_FILE_POINTER (-1)
  10. #endif
  11.  
  12. /* Sets handle h to a position based on gohere */
  13. /* output, if set, is changed to the new location */
  14. static void set_file_pointer(HANDLE h, LARGE_INTEGER gohere, PLARGE_INTEGER output, DWORD method)
  15. {
  16. LONG high = gohere.HighPart;
  17. DWORD ret = SetFilePointer(h, gohere.LowPart, &high, method);
  18. if(ret == INVALID_SET_FILE_POINTER)
  19. {
  20. DWORD err = GetLastError();
  21. if(err != NO_ERROR)
  22. {
  23. win32_maperr(err);
  24. uerror("lockf", Nothing);
  25. }
  26. }
  27. if(output != NULL) {
  28. output->LowPart = ret;
  29. output->HighPart = high;
  30. }
  31. }
  32.  
  33. CAMLprim void unix_lockf(value fd, value cmd, value span)
  34. {
  35. CAMLparam3(fd, cmd, span);
  36. int lock_ret;
  37. OVERLAPPED overlap;
  38. long l_len;
  39. HANDLE h;
  40. OSVERSIONINFO version;
  41. LARGE_INTEGER cur_position;
  42. LARGE_INTEGER beg_position;
  43. LARGE_INTEGER zero;
  44. LARGE_INTEGER lock_len;
  45.  
  46. version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  47. if(GetVersionEx(&version) == 0)
  48. {
  49. invalid_argument("lockf only supported on WIN32_NT platforms: could not determine current platform.");
  50. }
  51. if(version.dwPlatformId != VER_PLATFORM_WIN32_NT)
  52. {
  53. invalid_argument("lockf only supported on WIN32_NT platforms");
  54. }
  55.  
  56. h = Handle_val(fd);
  57.  
  58. l_len = Long_val(span);
  59.  
  60. cur_position.HighPart = 0;
  61. cur_position.LowPart = 0;
  62. beg_position.HighPart = 0;
  63. beg_position.LowPart = 0;
  64. zero.HighPart = 0;
  65. zero.LowPart = 0;
  66. lock_len.HighPart = 0;
  67. lock_len.LowPart = 0;
  68.  
  69. /* No matter what, we need the current position in the file */
  70. set_file_pointer(h, zero, &cur_position, FILE_CURRENT);
  71.  
  72. if(l_len == 0)
  73. {
  74. /* Lock from cur to infinity */
  75. lock_len.HighPart = 4294967295;
  76. lock_len.LowPart = 4294967295;
  77.  
  78. overlap.OffsetHigh = cur_position.HighPart;
  79. overlap.Offset = cur_position.LowPart ;
  80. overlap.hEvent = 0;
  81. }
  82. else if(l_len > 0)
  83. {
  84. /* positive file offset */
  85. lock_len.HighPart = 0;
  86. lock_len.LowPart = l_len;
  87. overlap.OffsetHigh = cur_position.HighPart;
  88. overlap.Offset = cur_position.LowPart ;
  89. }
  90. else
  91. {
  92. /* Negative file offset */
  93. lock_len.LowPart = -l_len;
  94. if(l_len > cur_position.LowPart && cur_position.HighPart == 0) {
  95. errno = EINVAL;
  96. uerror("lockf", Nothing);
  97. }
  98. beg_position.QuadPart = cur_position.QuadPart - lock_len.QuadPart;
  99.  
  100. overlap.OffsetHigh = beg_position.HighPart;
  101. overlap.Offset = beg_position.LowPart ;
  102. }
  103.  
  104. switch(Int_val(cmd))
  105. {
  106. case 0: /* F_ULOCK - unlock */
  107. lock_ret = UnlockFileEx(h, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
  108. if(lock_ret == 0)
  109. errno = EACCES;
  110. break;
  111. case 1: /* F_LOCK - blocking write lock */
  112. enter_blocking_section();
  113. lock_ret = LockFileEx(h, LOCKFILE_EXCLUSIVE_LOCK, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
  114. leave_blocking_section();
  115. if(lock_ret == 0)
  116. errno = EACCES;
  117. break;
  118. case 2: /* F_TLOCK - non-blocking write lock */
  119. lock_ret = LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
  120. if(lock_ret == 0)
  121. errno = EACCES;
  122. break;
  123. case 3: /* F_TEST - check whether a write lock can be obtained */
  124. lock_ret = LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
  125. if(lock_ret == 0)
  126. errno = EACCES;
  127. else
  128. UnlockFileEx(h, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
  129. break;
  130. case 4: /* F_RLOCK - blocking read lock */
  131. enter_blocking_section();
  132. lock_ret = LockFileEx(h, 0, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
  133. leave_blocking_section();
  134. if(lock_ret == 0)
  135. errno = EACCES;
  136. break;
  137. case 5: /* F_TRLOCK - non-blocking read lock */
  138. lock_ret = LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
  139. if(lock_ret == 0)
  140. errno = EACCES;
  141. break;
  142. default:
  143. errno = EINVAL;
  144. }
  145. if(lock_ret == 0)
  146. uerror("lockf", Nothing);
  147. CAMLreturn0;
  148. }
Add Comment
Please, Sign In to add comment