diff options
author | Jan Dubois <jand@activestate.com> | 2009-11-12 18:38:08 -0800 |
---|---|---|
committer | Jan Dubois <jand@activestate.com> | 2009-11-12 18:38:08 -0800 |
commit | 97b33cac18e30b878b151b5f3fcbf9c32cb7b037 (patch) | |
tree | 661f5c3f198bdf2bc1caa1a2b10ec1b4f8e91745 /win32/win32.c | |
parent | fd9e8b45c89ee5d36539a3655dae7737fb78c21e (diff) | |
download | perl-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.c | 31 |
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 /* |