* 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:
Corinna Vinschen 2008-03-24 14:48:58 +00:00
parent 88f0dc31d1
commit a998dd7055
12 changed files with 1431 additions and 163 deletions

View File

@ -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> 2008-03-22 Christopher Faylor <me+cygwin@cgf.cx>
* dtable.cc (handle_to_fn): Modify to return true if handle represents * dtable.cc (handle_to_fn): Modify to return true if handle represents

View File

@ -295,6 +295,9 @@ struct init_cygheap
size_t sthreads; size_t sthreads;
pid_t pid; /* my pid */ pid_t pid; /* my pid */
HANDLE pid_handle; /* handle for 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; hook_chain hooks;
void close_ctty (); void close_ctty ();
int manage_console_count (const char *, int, bool = false) __attribute__ ((regparm (3))); int manage_console_count (const char *, int, bool = false) __attribute__ ((regparm (3)));

View File

@ -874,6 +874,7 @@ localtime SIGFE
_localtime = localtime SIGFE _localtime = localtime SIGFE
localtime_r SIGFE localtime_r SIGFE
_localtime_r = localtime_r SIGFE _localtime_r = localtime_r SIGFE
lockf SIGFE
log NOSIGFE log NOSIGFE
_log = log NOSIGFE _log = log NOSIGFE
log10 NOSIGFE log10 NOSIGFE

View File

@ -657,6 +657,7 @@ child_info_fork::handle_fork ()
void void
child_info_spawn::handle_spawn () child_info_spawn::handle_spawn ()
{ {
extern void fixup_lockf_after_exec ();
HANDLE h; HANDLE h;
cygheap_fixup_in_child (true); cygheap_fixup_in_child (true);
memory_init (); memory_init ();
@ -689,6 +690,7 @@ child_info_spawn::handle_spawn ()
old_title = strcpy (title_buf, moreinfo->old_title); old_title = strcpy (title_buf, moreinfo->old_title);
cfree (moreinfo->old_title); cfree (moreinfo->old_title);
} }
fixup_lockf_after_exec ();
} }
void __stdcall void __stdcall

View File

@ -82,6 +82,7 @@ public:
void delete_archetype (fhandler_base *); void delete_archetype (fhandler_base *);
friend void dtable_init (); friend void dtable_init ();
friend void __stdcall close_all_files (bool); friend void __stdcall close_all_files (bool);
friend class fhandler_disk_file;
friend class cygheap_fdmanip; friend class cygheap_fdmanip;
friend class cygheap_fdget; friend class cygheap_fdget;
friend class cygheap_fdnew; friend class cygheap_fdnew;

View File

@ -1004,9 +1004,13 @@ fhandler_base::pwrite (void *, size_t, _off64_t)
int int
fhandler_base::close () fhandler_base::close ()
{ {
extern void del_my_locks (inode_t *);
int res = -1; int res = -1;
syscall_printf ("closing '%s' handle %p", get_name (), get_handle ()); 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 ())) if (nohandle () || CloseHandle (get_handle ()))
res = 0; res = 0;
else else
@ -1135,7 +1139,6 @@ fhandler_base::dup (fhandler_base *child)
} }
if (get_overlapped ()) if (get_overlapped ())
child->setup_overlapped (); child->setup_overlapped ();
set_flags (child->get_flags ());
return 0; return 0;
} }
@ -1265,6 +1268,7 @@ fhandler_base::fhandler_base () :
raixget (0), raixget (0),
raixput (0), raixput (0),
rabuflen (0), rabuflen (0),
node (NULL),
fs_flags (0), fs_flags (0),
archetype (NULL), archetype (NULL),
usecount (0) usecount (0)
@ -1336,6 +1340,10 @@ fhandler_base::fixup_after_fork (HANDLE parent)
fork_fixup (parent, io_handle, "io_handle"); fork_fixup (parent, io_handle, "io_handle");
if (get_overlapped ()) if (get_overlapped ())
setup_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 void

View File

@ -38,6 +38,7 @@ extern const int proc_len;
class select_record; class select_record;
class fhandler_disk_file; class fhandler_disk_file;
class inode_t;
typedef struct __DIR DIR; typedef struct __DIR DIR;
struct dirent; struct dirent;
struct iovec; struct iovec;
@ -136,6 +137,8 @@ class fhandler_base
size_t raixput; size_t raixput;
size_t rabuflen; size_t rabuflen;
inode_t *node; /* Used for advisory file locking. See flock.cc. */
DWORD fs_flags; DWORD fs_flags;
HANDLE read_state; HANDLE read_state;
int wait_overlapped (bool&, bool, DWORD *) __attribute__ ((regparm (3))); int wait_overlapped (bool&, bool, DWORD *) __attribute__ ((regparm (3)));

View File

@ -1317,147 +1317,6 @@ fhandler_disk_file::pwrite (void *buf, size_t count, _off64_t offset)
return res; 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 int
fhandler_disk_file::mkdir (mode_t mode) fhandler_disk_file::mkdir (mode_t mode)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -173,6 +173,7 @@ int __stdcall
frok::child (volatile char * volatile here) frok::child (volatile char * volatile here)
{ {
HANDLE& hParent = ch.parent; HANDLE& hParent = ch.parent;
extern void fixup_lockf_after_fork ();
extern void fixup_hooks_after_fork (); extern void fixup_hooks_after_fork ();
extern void fixup_timers_after_fork (); extern void fixup_timers_after_fork ();
debug_printf ("child is running. pid %d, ppid %d, stack here %p", debug_printf ("child is running. pid %d, ppid %d, stack here %p",
@ -253,6 +254,7 @@ frok::child (volatile char * volatile here)
ld_preload (); ld_preload ();
fixup_hooks_after_fork (); fixup_hooks_after_fork ();
_my_tls.fixup_after_fork (); _my_tls.fixup_after_fork ();
fixup_lockf_after_fork ();
wait_for_sigthread (true); wait_for_sigthread (true);
cygwin_finished_initializing = true; cygwin_finished_initializing = true;
return 0; return 0;

View File

@ -324,12 +324,13 @@ details. */
flistxattr, setxattr, lsetxattr, fsetxattr, removexattr, flistxattr, setxattr, lsetxattr, fsetxattr, removexattr,
lremovexattr, fremovexattr. lremovexattr, fremovexattr.
181: Export cygwin_conv_path, cygwin_create_path, cygwin_conv_path_list. 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 */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0 #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 /* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible shared memory regions. It is incremented when incompatible

View File

@ -183,6 +183,7 @@ typedef struct _FILE_ID_BOTH_DIR_INFORMATION
#define LOCK_VM_IN_RAM 2 #define LOCK_VM_IN_RAM 2
#define DIRECTORY_QUERY 1 #define DIRECTORY_QUERY 1
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x0f)
typedef ULONG KAFFINITY; typedef ULONG KAFFINITY;
@ -741,6 +742,21 @@ typedef enum _OBJECT_INFORMATION_CLASS
// and many more // and many more
} OBJECT_INFORMATION_CLASS; } 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 typedef struct _OBJECT_NAME_INFORMATION
{ {
UNICODE_STRING Name; 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 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 /* Function declarations for ntdll.dll. These don't appear in any
standard Win32 header. */ standard Win32 header. */
extern "C" extern "C"
@ -783,12 +805,18 @@ extern "C"
NTSTATUS NTAPI NtAdjustPrivilegesToken (HANDLE, BOOLEAN, PTOKEN_PRIVILEGES, NTSTATUS NTAPI NtAdjustPrivilegesToken (HANDLE, BOOLEAN, PTOKEN_PRIVILEGES,
ULONG, PTOKEN_PRIVILEGES, PULONG); ULONG, PTOKEN_PRIVILEGES, PULONG);
NTSTATUS NTAPI NtClose (HANDLE); 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, NTSTATUS NTAPI NtCreateFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG,
ULONG, ULONG, PVOID, ULONG); ULONG, ULONG, PVOID, ULONG);
NTSTATUS NTAPI NtCreateMailslotFile(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, NTSTATUS NTAPI NtCreateMailslotFile(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK, ULONG, ULONG, ULONG, PIO_STATUS_BLOCK, ULONG, ULONG, ULONG,
PLARGE_INTEGER); PLARGE_INTEGER);
NTSTATUS NTAPI NtCreateMutant (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
BOOLEAN);
NTSTATUS NTAPI NtCreateSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, NTSTATUS NTAPI NtCreateSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PLARGE_INTEGER, ULONG, ULONG, HANDLE); PLARGE_INTEGER, ULONG, ULONG, HANDLE);
NTSTATUS NTAPI NtCreateToken (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, NTSTATUS NTAPI NtCreateToken (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
@ -809,8 +837,10 @@ extern "C"
ULONG, BOOLEAN); ULONG, BOOLEAN);
NTSTATUS NTAPI NtOpenDirectoryObject (PHANDLE, ACCESS_MASK, NTSTATUS NTAPI NtOpenDirectoryObject (PHANDLE, ACCESS_MASK,
POBJECT_ATTRIBUTES); POBJECT_ATTRIBUTES);
NTSTATUS NTAPI NtOpenEvent (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK, ULONG, ULONG); PIO_STATUS_BLOCK, ULONG, ULONG);
NTSTATUS NTAPI NtOpenMutant (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
/* WARNING! Don't rely on the timestamp information returned by /* WARNING! Don't rely on the timestamp information returned by
NtQueryAttributesFile. Only the DOS file attribute info is reliable. */ NtQueryAttributesFile. Only the DOS file attribute info is reliable. */