* 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:
parent
88f0dc31d1
commit
a998dd7055
|
@ -1,3 +1,33 @@
|
|||
2008-03-24 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* 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.
|
||||
|
||||
2008-03-22 Christopher Faylor <me+cygwin@cgf.cx>
|
||||
|
||||
* dtable.cc (handle_to_fn): Modify to return true if handle represents
|
||||
|
|
|
@ -295,6 +295,9 @@ struct init_cygheap
|
|||
size_t sthreads;
|
||||
pid_t pid; /* my pid */
|
||||
HANDLE pid_handle; /* handle for my pid */
|
||||
struct { /* Equivalent to using LIST_HEAD. */
|
||||
struct inode_t *lh_first;
|
||||
} inode_list; /* Global inode pointer for adv. locking. */
|
||||
hook_chain hooks;
|
||||
void close_ctty ();
|
||||
int manage_console_count (const char *, int, bool = false) __attribute__ ((regparm (3)));
|
||||
|
|
|
@ -874,6 +874,7 @@ localtime SIGFE
|
|||
_localtime = localtime SIGFE
|
||||
localtime_r SIGFE
|
||||
_localtime_r = localtime_r SIGFE
|
||||
lockf SIGFE
|
||||
log NOSIGFE
|
||||
_log = log NOSIGFE
|
||||
log10 NOSIGFE
|
||||
|
|
|
@ -657,6 +657,7 @@ child_info_fork::handle_fork ()
|
|||
void
|
||||
child_info_spawn::handle_spawn ()
|
||||
{
|
||||
extern void fixup_lockf_after_exec ();
|
||||
HANDLE h;
|
||||
cygheap_fixup_in_child (true);
|
||||
memory_init ();
|
||||
|
@ -689,6 +690,7 @@ child_info_spawn::handle_spawn ()
|
|||
old_title = strcpy (title_buf, moreinfo->old_title);
|
||||
cfree (moreinfo->old_title);
|
||||
}
|
||||
fixup_lockf_after_exec ();
|
||||
}
|
||||
|
||||
void __stdcall
|
||||
|
|
|
@ -82,6 +82,7 @@ public:
|
|||
void delete_archetype (fhandler_base *);
|
||||
friend void dtable_init ();
|
||||
friend void __stdcall close_all_files (bool);
|
||||
friend class fhandler_disk_file;
|
||||
friend class cygheap_fdmanip;
|
||||
friend class cygheap_fdget;
|
||||
friend class cygheap_fdnew;
|
||||
|
|
|
@ -1004,9 +1004,13 @@ fhandler_base::pwrite (void *, size_t, _off64_t)
|
|||
int
|
||||
fhandler_base::close ()
|
||||
{
|
||||
extern void del_my_locks (inode_t *);
|
||||
int res = -1;
|
||||
|
||||
syscall_printf ("closing '%s' handle %p", get_name (), get_handle ());
|
||||
/* Delete all POSIX locks on the file. */
|
||||
if (node)
|
||||
del_my_locks (node);
|
||||
if (nohandle () || CloseHandle (get_handle ()))
|
||||
res = 0;
|
||||
else
|
||||
|
@ -1135,7 +1139,6 @@ fhandler_base::dup (fhandler_base *child)
|
|||
}
|
||||
if (get_overlapped ())
|
||||
child->setup_overlapped ();
|
||||
set_flags (child->get_flags ());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1265,6 +1268,7 @@ fhandler_base::fhandler_base () :
|
|||
raixget (0),
|
||||
raixput (0),
|
||||
rabuflen (0),
|
||||
node (NULL),
|
||||
fs_flags (0),
|
||||
archetype (NULL),
|
||||
usecount (0)
|
||||
|
@ -1336,6 +1340,10 @@ fhandler_base::fixup_after_fork (HANDLE parent)
|
|||
fork_fixup (parent, io_handle, "io_handle");
|
||||
if (get_overlapped ())
|
||||
setup_overlapped ();
|
||||
/* POSIX locks are not inherited across fork. The lock structures
|
||||
are deleted globally in fixup_lockf_after_fork. Here we just
|
||||
have to reset the pointer. */
|
||||
node = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -38,6 +38,7 @@ extern const int proc_len;
|
|||
|
||||
class select_record;
|
||||
class fhandler_disk_file;
|
||||
class inode_t;
|
||||
typedef struct __DIR DIR;
|
||||
struct dirent;
|
||||
struct iovec;
|
||||
|
@ -136,6 +137,8 @@ class fhandler_base
|
|||
size_t raixput;
|
||||
size_t rabuflen;
|
||||
|
||||
inode_t *node; /* Used for advisory file locking. See flock.cc. */
|
||||
|
||||
DWORD fs_flags;
|
||||
HANDLE read_state;
|
||||
int wait_overlapped (bool&, bool, DWORD *) __attribute__ ((regparm (3)));
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -173,6 +173,7 @@ int __stdcall
|
|||
frok::child (volatile char * volatile here)
|
||||
{
|
||||
HANDLE& hParent = ch.parent;
|
||||
extern void fixup_lockf_after_fork ();
|
||||
extern void fixup_hooks_after_fork ();
|
||||
extern void fixup_timers_after_fork ();
|
||||
debug_printf ("child is running. pid %d, ppid %d, stack here %p",
|
||||
|
@ -253,6 +254,7 @@ frok::child (volatile char * volatile here)
|
|||
ld_preload ();
|
||||
fixup_hooks_after_fork ();
|
||||
_my_tls.fixup_after_fork ();
|
||||
fixup_lockf_after_fork ();
|
||||
wait_for_sigthread (true);
|
||||
cygwin_finished_initializing = true;
|
||||
return 0;
|
||||
|
|
|
@ -324,12 +324,13 @@ details. */
|
|||
flistxattr, setxattr, lsetxattr, fsetxattr, removexattr,
|
||||
lremovexattr, fremovexattr.
|
||||
181: Export cygwin_conv_path, cygwin_create_path, cygwin_conv_path_list.
|
||||
182: Export lockf.
|
||||
*/
|
||||
|
||||
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
|
||||
|
||||
#define CYGWIN_VERSION_API_MAJOR 0
|
||||
#define CYGWIN_VERSION_API_MINOR 181
|
||||
#define CYGWIN_VERSION_API_MINOR 182
|
||||
|
||||
/* There is also a compatibity version number associated with the
|
||||
shared memory regions. It is incremented when incompatible
|
||||
|
|
|
@ -183,6 +183,7 @@ typedef struct _FILE_ID_BOTH_DIR_INFORMATION
|
|||
#define LOCK_VM_IN_RAM 2
|
||||
|
||||
#define DIRECTORY_QUERY 1
|
||||
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x0f)
|
||||
|
||||
typedef ULONG KAFFINITY;
|
||||
|
||||
|
@ -741,6 +742,21 @@ typedef enum _OBJECT_INFORMATION_CLASS
|
|||
// and many more
|
||||
} OBJECT_INFORMATION_CLASS;
|
||||
|
||||
typedef struct _OBJECT_BASIC_INFORMATION
|
||||
{
|
||||
ULONG Attributes;
|
||||
ACCESS_MASK GrantedAccess;
|
||||
ULONG HandleCount;
|
||||
ULONG PointerCount;
|
||||
ULONG PagedPoolUsage;
|
||||
ULONG NonPagedPoolUsage;
|
||||
ULONG Reserved[3];
|
||||
ULONG NameInformationLength;
|
||||
ULONG TypeInformationLength;
|
||||
ULONG SecurityDescriptorLength;
|
||||
LARGE_INTEGER CreateTime;
|
||||
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;
|
||||
|
||||
typedef struct _OBJECT_NAME_INFORMATION
|
||||
{
|
||||
UNICODE_STRING Name;
|
||||
|
@ -776,6 +792,12 @@ typedef struct _FILE_MAILSLOT_SET_INFORMATION
|
|||
|
||||
typedef VOID NTAPI (*PIO_APC_ROUTINE)(PVOID, PIO_STATUS_BLOCK, ULONG);
|
||||
|
||||
typedef enum _EVENT_TYPE
|
||||
{
|
||||
NotificationEvent = 0,
|
||||
SynchronizationEvent
|
||||
} EVENT_TYPE, *PEVENT_TYPE;
|
||||
|
||||
/* Function declarations for ntdll.dll. These don't appear in any
|
||||
standard Win32 header. */
|
||||
extern "C"
|
||||
|
@ -783,12 +805,18 @@ extern "C"
|
|||
NTSTATUS NTAPI NtAdjustPrivilegesToken (HANDLE, BOOLEAN, PTOKEN_PRIVILEGES,
|
||||
ULONG, PTOKEN_PRIVILEGES, PULONG);
|
||||
NTSTATUS NTAPI NtClose (HANDLE);
|
||||
NTSTATUS NTAPI NtCreateDirectoryObject (PHANDLE, ACCESS_MASK,
|
||||
POBJECT_ATTRIBUTES);
|
||||
NTSTATUS NTAPI NtCreateEvent (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
|
||||
EVENT_TYPE, BOOLEAN);
|
||||
NTSTATUS NTAPI NtCreateFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
|
||||
PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG,
|
||||
ULONG, ULONG, PVOID, ULONG);
|
||||
NTSTATUS NTAPI NtCreateMailslotFile(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
|
||||
PIO_STATUS_BLOCK, ULONG, ULONG, ULONG,
|
||||
PLARGE_INTEGER);
|
||||
NTSTATUS NTAPI NtCreateMutant (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
|
||||
BOOLEAN);
|
||||
NTSTATUS NTAPI NtCreateSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
|
||||
PLARGE_INTEGER, ULONG, ULONG, HANDLE);
|
||||
NTSTATUS NTAPI NtCreateToken (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
|
||||
|
@ -809,8 +837,10 @@ extern "C"
|
|||
ULONG, BOOLEAN);
|
||||
NTSTATUS NTAPI NtOpenDirectoryObject (PHANDLE, ACCESS_MASK,
|
||||
POBJECT_ATTRIBUTES);
|
||||
NTSTATUS NTAPI NtOpenEvent (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
|
||||
NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
|
||||
PIO_STATUS_BLOCK, ULONG, ULONG);
|
||||
NTSTATUS NTAPI NtOpenMutant (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
|
||||
NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
|
||||
/* WARNING! Don't rely on the timestamp information returned by
|
||||
NtQueryAttributesFile. Only the DOS file attribute info is reliable. */
|
||||
|
|
Loading…
Reference in New Issue