* fhandler.cc (fhandler_base::dup): Drop setting flags in the parent.
Implement advisory file locking. * cygheap.h (struct init_cygheap): Add inode_list member. * cygwin.din (lockf): Export. * dcrt0.cc (child_info_spawn::handle_spawn): Call fixup_lockf_after_exec. * dtable.h (class dtable): Add fhandler_disk_file as friend class. * fhandler.cc (fhandler_base::close): Call del_my_locks if node is set. (fhandler_base::fhandler_base): Initialize node to NULL. (fhandler_base::fixup_after_fork): Ditto. * fhandler.h (class fhandler_base): Add member node. * fhandler_disk_file.cc (fhandler_disk_file::lock): Delete. * flock.cc: Implement all advisory file locking here. (fhandler_disk_file::lock): Implement here. (flock): Call fcntl with F_FLOCK bit set. Remove test main function. (lockf): New function. * fork.cc (frok::child): Call fixup_lockf_after_fork. * ntdll.h (DIRECTORY_ALL_ACCESS): Define. (struct _OBJECT_BASIC_INFORMATION): Define. (enum _EVENT_TYPE): Define. (NtCreateDirectoryObject): Declare. (NtCreateEvent): Declare. (NtCreateMutant): Declare. (NtOpenEvent): Declare. (NtOpenMutant): Declare. * include/cygwin/version.h: Bump API minor number.
This commit is contained in:
@@ -1317,147 +1317,6 @@ fhandler_disk_file::pwrite (void *buf, size_t count, _off64_t offset)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* FIXME: The correct way to do this to get POSIX locking semantics is to
|
||||
keep a linked list of posix lock requests and map them into Win32 locks.
|
||||
he problem is that Win32 does not deal correctly with overlapping lock
|
||||
requests. */
|
||||
|
||||
int
|
||||
fhandler_disk_file::lock (int cmd, struct __flock64 *fl)
|
||||
{
|
||||
_off64_t win32_start;
|
||||
_off64_t win32_len;
|
||||
_off64_t startpos;
|
||||
|
||||
/*
|
||||
* We don't do getlck calls yet.
|
||||
*/
|
||||
|
||||
if (cmd == F_GETLK)
|
||||
{
|
||||
set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate where in the file to start from,
|
||||
* then adjust this by fl->l_start.
|
||||
*/
|
||||
|
||||
switch (fl->l_whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
startpos = 0;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
if ((startpos = lseek (0, SEEK_CUR)) == ILLEGAL_SEEK)
|
||||
return -1;
|
||||
break;
|
||||
case SEEK_END:
|
||||
{
|
||||
BY_HANDLE_FILE_INFORMATION finfo;
|
||||
if (GetFileInformationByHandle (get_handle (), &finfo) == 0)
|
||||
{
|
||||
__seterrno ();
|
||||
return -1;
|
||||
}
|
||||
startpos = ((_off64_t)finfo.nFileSizeHigh << 32)
|
||||
+ finfo.nFileSizeLow;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now the fun starts. Adjust the start and length
|
||||
* fields until they make sense.
|
||||
*/
|
||||
|
||||
win32_start = startpos + fl->l_start;
|
||||
if (fl->l_len < 0)
|
||||
{
|
||||
win32_start -= fl->l_len;
|
||||
win32_len = -fl->l_len;
|
||||
}
|
||||
else
|
||||
win32_len = fl->l_len;
|
||||
|
||||
if (win32_start < 0)
|
||||
{
|
||||
/* watch the signs! */
|
||||
win32_len -= -win32_start;
|
||||
if (win32_len <= 0)
|
||||
{
|
||||
/* Failure ! */
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
win32_start = 0;
|
||||
}
|
||||
|
||||
DWORD off_high, off_low, len_high, len_low;
|
||||
|
||||
off_low = (DWORD)(win32_start & UINT32_MAX);
|
||||
off_high = (DWORD)(win32_start >> 32);
|
||||
if (win32_len == 0)
|
||||
{
|
||||
/* Special case if len == 0 for POSIX means lock to the end of
|
||||
the entire file (and all future extensions). */
|
||||
len_low = len_high = UINT32_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
len_low = (DWORD)(win32_len & UINT32_MAX);
|
||||
len_high = (DWORD)(win32_len >> 32);
|
||||
}
|
||||
|
||||
BOOL res;
|
||||
|
||||
DWORD lock_flags = (cmd == F_SETLK) ? LOCKFILE_FAIL_IMMEDIATELY : 0;
|
||||
lock_flags |= (fl->l_type == F_WRLCK) ? LOCKFILE_EXCLUSIVE_LOCK : 0;
|
||||
|
||||
OVERLAPPED ov;
|
||||
|
||||
ov.Internal = 0;
|
||||
ov.InternalHigh = 0;
|
||||
ov.Offset = off_low;
|
||||
ov.OffsetHigh = off_high;
|
||||
ov.hEvent = (HANDLE) 0;
|
||||
|
||||
if (fl->l_type == F_UNLCK)
|
||||
{
|
||||
res = UnlockFileEx (get_handle (), 0, len_low, len_high, &ov);
|
||||
if (res == 0 && GetLastError () == ERROR_NOT_LOCKED)
|
||||
res = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = LockFileEx (get_handle (), lock_flags, 0,
|
||||
len_low, len_high, &ov);
|
||||
/* Deal with the fail immediately case. */
|
||||
/*
|
||||
* FIXME !! I think this is the right error to check for
|
||||
* but I must admit I haven't checked....
|
||||
*/
|
||||
if ((res == 0) && (lock_flags & LOCKFILE_FAIL_IMMEDIATELY) &&
|
||||
(GetLastError () == ERROR_LOCK_FAILED))
|
||||
{
|
||||
set_errno (EAGAIN);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (res == 0)
|
||||
{
|
||||
__seterrno ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_disk_file::mkdir (mode_t mode)
|
||||
{
|
||||
|
Reference in New Issue
Block a user