summaryrefslogtreecommitdiff
path: root/win32/win32.c
diff options
context:
space:
mode:
authorJan Dubois <jand@activestate.com>2009-11-12 18:38:08 -0800
committerJan Dubois <jand@activestate.com>2009-11-12 18:38:08 -0800
commit97b33cac18e30b878b151b5f3fcbf9c32cb7b037 (patch)
tree661f5c3f198bdf2bc1caa1a2b10ec1b4f8e91745 /win32/win32.c
parentfd9e8b45c89ee5d36539a3655dae7737fb78c21e (diff)
downloadperl-97b33cac18e30b878b151b5f3fcbf9c32cb7b037.tar.gz
flock() on Windows should set proper errno numbers.
It used to set errno to GetLastError(), which is from an incompatible set of error codes. That doesn't make any sense, especially since the GetLastError() value is also available at the Perl level via $^E. It is important for autodie.pm that flock() will set $! to WSAWOULDBLOCK when GetLastError() returns ERROR_LOCK_VIOLATION because that is the value POSIX.pm now returns for POSIX::EWOULDBLOCK.
Diffstat (limited to 'win32/win32.c')
-rw-r--r--win32/win32.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/win32/win32.c b/win32/win32.c
index e6674e1101..0302836ea7 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -2505,7 +2505,6 @@ my_open_osfhandle(intptr_t osfhandle, int flags)
/* simulate flock by locking a range on the file */
-#define LK_ERR(f,i) ((f) ? (i = 0) : (errno = GetLastError()))
#define LK_LEN 0xffff0000
DllExport int
@@ -2521,34 +2520,46 @@ win32_flock(int fd, int oper)
return -1;
}
fh = (HANDLE)_get_osfhandle(fd);
+ if (fh == (HANDLE)-1) /* _get_osfhandle() already sets errno to EBADF */
+ return -1;
+
memset(&o, 0, sizeof(o));
switch(oper) {
case LOCK_SH: /* shared lock */
- LK_ERR(LockFileEx(fh, 0, 0, LK_LEN, 0, &o),i);
+ if (LockFileEx(fh, 0, 0, LK_LEN, 0, &o))
+ i = 0;
break;
case LOCK_EX: /* exclusive lock */
- LK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, 0, &o),i);
+ if (LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, 0, &o))
+ i = 0;
break;
case LOCK_SH|LOCK_NB: /* non-blocking shared lock */
- LK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, 0, &o),i);
+ if (LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, 0, &o))
+ i = 0;
break;
case LOCK_EX|LOCK_NB: /* non-blocking exclusive lock */
- LK_ERR(LockFileEx(fh,
- LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
- 0, LK_LEN, 0, &o),i);
+ if (LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
+ 0, LK_LEN, 0, &o))
+ i = 0;
break;
case LOCK_UN: /* unlock lock */
- LK_ERR(UnlockFileEx(fh, 0, LK_LEN, 0, &o),i);
+ if (UnlockFileEx(fh, 0, LK_LEN, 0, &o))
+ i = 0;
break;
default: /* unknown */
errno = EINVAL;
- break;
+ return -1;
+ }
+ if (i == -1) {
+ if (GetLastError() == ERROR_LOCK_VIOLATION)
+ errno = WSAEWOULDBLOCK;
+ else
+ errno = EINVAL;
}
return i;
}
-#undef LK_ERR
#undef LK_LEN
/*