* flock.cc (FLOCK_PARENT_DIR_ACCESS): Define.
(FLOCK_INODE_DIR_ACCESS): Define. (FLOCK_MUTANT_ACCESS): Define. (FLOCK_EVENT_ACCESS): Define. (SD_MIN_SIZE): Define. (everyone_sd): Define to simplify calling _everyone_sd. (_everyone_sd): Replace everyone_sync_sd. Take SECURITY_DESCRIPTOR as argument and allow to specify access mask. (get_lock_parent_dir): Open/Create parent dir with FLOCK_PARENT_DIR_ACCESS. Add text to api_fatal message. (inode_t::inode_t): Open/Create dir with FLOCK_INODE_DIR_ACCESS. Open/Create mutant with FLOCK_MUTANT_ACCESS. Add text to api_fatal message. (lockf_t::create_lock_obj): Create event with FLOCK_EVENT_ACCESS. Add text to api_fatal message. (lockf_t::open_lock_obj): Open event with FLOCK_EVENT_ACCESS. On failure, just return NULL pointer instead of calling api_fatal. (lockf_t::get_lock_obj_handle_count): Replace call to small_printf with call to debug_printf. (lf_setlock): Handle a failure to open the lock event object as EDEADLK. Call system_printf if opening sync objects fail. * ntdll.h (DIRECTORY_TRAVERSE): Define. (DIRECTORY_CREATE_OBJECT): Define. (DIRECTORY_CREATE_SUBDIRECTORY): Define. (EVENT_QUERY_STATE): Define.
This commit is contained in:
parent
b5f9c24f7e
commit
c46d7be9a6
|
@ -1,3 +1,31 @@
|
||||||
|
2008-03-27 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* flock.cc (FLOCK_PARENT_DIR_ACCESS): Define.
|
||||||
|
(FLOCK_INODE_DIR_ACCESS): Define.
|
||||||
|
(FLOCK_MUTANT_ACCESS): Define.
|
||||||
|
(FLOCK_EVENT_ACCESS): Define.
|
||||||
|
(SD_MIN_SIZE): Define.
|
||||||
|
(everyone_sd): Define to simplify calling _everyone_sd.
|
||||||
|
(_everyone_sd): Replace everyone_sync_sd. Take SECURITY_DESCRIPTOR as
|
||||||
|
argument and allow to specify access mask.
|
||||||
|
(get_lock_parent_dir): Open/Create parent dir with
|
||||||
|
FLOCK_PARENT_DIR_ACCESS. Add text to api_fatal message.
|
||||||
|
(inode_t::inode_t): Open/Create dir with FLOCK_INODE_DIR_ACCESS.
|
||||||
|
Open/Create mutant with FLOCK_MUTANT_ACCESS. Add text to api_fatal
|
||||||
|
message.
|
||||||
|
(lockf_t::create_lock_obj): Create event with FLOCK_EVENT_ACCESS.
|
||||||
|
Add text to api_fatal message.
|
||||||
|
(lockf_t::open_lock_obj): Open event with FLOCK_EVENT_ACCESS.
|
||||||
|
On failure, just return NULL pointer instead of calling api_fatal.
|
||||||
|
(lockf_t::get_lock_obj_handle_count): Replace call to small_printf
|
||||||
|
with call to debug_printf.
|
||||||
|
(lf_setlock): Handle a failure to open the lock event object as
|
||||||
|
EDEADLK. Call system_printf if opening sync objects fail.
|
||||||
|
* ntdll.h (DIRECTORY_TRAVERSE): Define.
|
||||||
|
(DIRECTORY_CREATE_OBJECT): Define.
|
||||||
|
(DIRECTORY_CREATE_SUBDIRECTORY): Define.
|
||||||
|
(EVENT_QUERY_STATE): Define.
|
||||||
|
|
||||||
2008-03-27 Corinna Vinschen <corinna@vinschen.de>
|
2008-03-27 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* syscalls.cc (rename): Fix setting errno in case of trailing "/."
|
* syscalls.cc (rename): Fix setting errno in case of trailing "/."
|
||||||
|
|
|
@ -216,23 +216,42 @@ allow_others_to_sync ()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function to create an event security descriptor which only allows
|
/* Helper function to create an event security descriptor which only allows
|
||||||
SYNCHRONIZE access to everyone. Only the creating process has all access
|
specific access to everyone. Only the creating process has all access
|
||||||
rights. */
|
rights. */
|
||||||
static PSECURITY_DESCRIPTOR
|
|
||||||
everyone_sync_sd ()
|
|
||||||
{
|
|
||||||
static PSECURITY_DESCRIPTOR psd;
|
|
||||||
|
|
||||||
if (!psd)
|
#define FLOCK_PARENT_DIR_ACCESS (DIRECTORY_QUERY \
|
||||||
|
| DIRECTORY_TRAVERSE \
|
||||||
|
| DIRECTORY_CREATE_SUBDIRECTORY \
|
||||||
|
| READ_CONTROL)
|
||||||
|
|
||||||
|
#define FLOCK_INODE_DIR_ACCESS (DIRECTORY_QUERY \
|
||||||
|
| DIRECTORY_TRAVERSE \
|
||||||
|
| DIRECTORY_CREATE_OBJECT \
|
||||||
|
| READ_CONTROL)
|
||||||
|
|
||||||
|
#define FLOCK_MUTANT_ACCESS (MUTANT_QUERY_STATE \
|
||||||
|
| SYNCHRONIZE \
|
||||||
|
| READ_CONTROL)
|
||||||
|
|
||||||
|
#define FLOCK_EVENT_ACCESS (EVENT_QUERY_STATE \
|
||||||
|
| SYNCHRONIZE \
|
||||||
|
| READ_CONTROL)
|
||||||
|
|
||||||
|
#define SD_MIN_SIZE (sizeof (SECURITY_DESCRIPTOR) + MAX_DACL_LEN (1))
|
||||||
|
|
||||||
|
#define everyone_sd(access) (_everyone_sd (alloca (SD_MIN_SIZE), (access)))
|
||||||
|
|
||||||
|
PSECURITY_DESCRIPTOR
|
||||||
|
_everyone_sd (void *buf, ACCESS_MASK access)
|
||||||
|
{
|
||||||
|
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) buf;
|
||||||
|
|
||||||
|
if (psd)
|
||||||
{
|
{
|
||||||
const size_t acl_len = sizeof (ACL) +
|
|
||||||
sizeof (ACCESS_ALLOWED_ACE) + MAX_SID_LEN;
|
|
||||||
psd = (PSECURITY_DESCRIPTOR)
|
|
||||||
malloc (sizeof (SECURITY_DESCRIPTOR) + acl_len);
|
|
||||||
InitializeSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION);
|
InitializeSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION);
|
||||||
PACL dacl = (PACL) (psd + 1);
|
PACL dacl = (PACL) (psd + 1);
|
||||||
InitializeAcl (dacl, acl_len, ACL_REVISION);
|
InitializeAcl (dacl, MAX_DACL_LEN (1), ACL_REVISION);
|
||||||
if (!AddAccessAllowedAce (dacl, ACL_REVISION, SYNCHRONIZE,
|
if (!AddAccessAllowedAce (dacl, ACL_REVISION, access,
|
||||||
well_known_world_sid))
|
well_known_world_sid))
|
||||||
{
|
{
|
||||||
debug_printf ("AddAccessAllowedAce: %lu", GetLastError ());
|
debug_printf ("AddAccessAllowedAce: %lu", GetLastError ());
|
||||||
|
@ -265,13 +284,14 @@ get_lock_parent_dir ()
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString (&uname, L"\\BaseNamedObjects\\cygwin-fcntl-lk");
|
RtlInitUnicodeString (&uname, L"\\BaseNamedObjects\\cygwin-fcntl-lk");
|
||||||
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, NULL,
|
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, NULL,
|
||||||
sec_all.lpSecurityDescriptor);
|
everyone_sd (FLOCK_PARENT_DIR_ACCESS));
|
||||||
status = NtOpenDirectoryObject (&dir, DIRECTORY_ALL_ACCESS, &attr);
|
status = NtOpenDirectoryObject (&dir, FLOCK_PARENT_DIR_ACCESS, &attr);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
status = NtCreateDirectoryObject (&dir, DIRECTORY_ALL_ACCESS, &attr);
|
status = NtCreateDirectoryObject (&dir, FLOCK_PARENT_DIR_ACCESS,
|
||||||
|
&attr);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
api_fatal ("NtCreateDirectoryObject: %p", status);
|
api_fatal ("NtCreateDirectoryObject(parent): %p", status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
INODE_LIST_UNLOCK ();
|
INODE_LIST_UNLOCK ();
|
||||||
|
@ -446,25 +466,25 @@ inode_t::inode_t (dev_t dev, ino_t ino)
|
||||||
int len = __small_swprintf (name, L"%08x-%016X", dev, ino);
|
int len = __small_swprintf (name, L"%08x-%016X", dev, ino);
|
||||||
RtlInitCountedUnicodeString (&uname, name, len * sizeof (WCHAR));
|
RtlInitCountedUnicodeString (&uname, name, len * sizeof (WCHAR));
|
||||||
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, parent_dir,
|
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, parent_dir,
|
||||||
sec_all.lpSecurityDescriptor);
|
everyone_sd (FLOCK_INODE_DIR_ACCESS));
|
||||||
status = NtOpenDirectoryObject (&i_dir, DIRECTORY_ALL_ACCESS, &attr);
|
status = NtOpenDirectoryObject (&i_dir, FLOCK_INODE_DIR_ACCESS, &attr);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
status = NtCreateDirectoryObject (&i_dir, DIRECTORY_ALL_ACCESS, &attr);
|
status = NtCreateDirectoryObject (&i_dir, FLOCK_INODE_DIR_ACCESS, &attr);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
api_fatal ("NtCreateDirectoryObject: %p", status);
|
api_fatal ("NtCreateDirectoryObject(inode): %p", status);
|
||||||
}
|
}
|
||||||
/* Create a mutex object in the file specific dir, which is used for
|
/* Create a mutex object in the file specific dir, which is used for
|
||||||
access synchronization on the dir and its objects. */
|
access synchronization on the dir and its objects. */
|
||||||
RtlInitUnicodeString (&uname, L"mtx");
|
RtlInitUnicodeString (&uname, L"mtx");
|
||||||
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, i_dir,
|
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, i_dir,
|
||||||
sec_all.lpSecurityDescriptor);
|
everyone_sd (FLOCK_MUTANT_ACCESS));
|
||||||
status = NtOpenMutant (&i_mtx, MUTANT_ALL_ACCESS, &attr);
|
status = NtOpenMutant (&i_mtx, FLOCK_MUTANT_ACCESS, &attr);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
status = NtCreateMutant (&i_mtx, MUTANT_ALL_ACCESS, &attr, FALSE);
|
status = NtCreateMutant (&i_mtx, FLOCK_MUTANT_ACCESS, &attr, FALSE);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
api_fatal ("NtCreateMutant: %p", status);
|
api_fatal ("NtCreateMutant(inode): %p", status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,11 +573,11 @@ lockf_t::create_lock_obj ()
|
||||||
RtlInitCountedUnicodeString (&uname, name,
|
RtlInitCountedUnicodeString (&uname, name,
|
||||||
LOCK_OBJ_NAME_LEN * sizeof (WCHAR));
|
LOCK_OBJ_NAME_LEN * sizeof (WCHAR));
|
||||||
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, lf_inode->i_dir,
|
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, lf_inode->i_dir,
|
||||||
everyone_sync_sd ());
|
everyone_sd (FLOCK_EVENT_ACCESS));
|
||||||
status = NtCreateEvent (&lf_obj, EVENT_ALL_ACCESS, &attr,
|
status = NtCreateEvent (&lf_obj, EVENT_ALL_ACCESS, &attr,
|
||||||
NotificationEvent, FALSE);
|
NotificationEvent, FALSE);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
api_fatal ("NtCreateEvent: %p", status);
|
api_fatal ("NtCreateEvent(lock): %p", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open a lock event object for SYNCHRONIZE access (to wait for it). */
|
/* Open a lock event object for SYNCHRONIZE access (to wait for it). */
|
||||||
|
@ -577,9 +597,12 @@ lockf_t::open_lock_obj () const
|
||||||
LOCK_OBJ_NAME_LEN * sizeof (WCHAR));
|
LOCK_OBJ_NAME_LEN * sizeof (WCHAR));
|
||||||
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, lf_inode->i_dir,
|
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, lf_inode->i_dir,
|
||||||
NULL);
|
NULL);
|
||||||
status = NtOpenEvent (&obj, SYNCHRONIZE, &attr);
|
status = NtOpenEvent (&obj, FLOCK_EVENT_ACCESS, &attr);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
api_fatal ("NtOpenEvent: %p", status);
|
{
|
||||||
|
SetLastError (RtlNtStatusToDosError (status));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,7 +619,7 @@ lockf_t::get_lock_obj_handle_count () const
|
||||||
status = NtQueryObject (lf_obj, ObjectBasicInformation,
|
status = NtQueryObject (lf_obj, ObjectBasicInformation,
|
||||||
&obi, sizeof obi, NULL);
|
&obi, sizeof obi, NULL);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
small_printf ("NtQueryObject: %p\n", status);
|
debug_printf ("NtQueryObject: %p\n", status);
|
||||||
else
|
else
|
||||||
hdl_cnt = obi.HandleCount;
|
hdl_cnt = obi.HandleCount;
|
||||||
}
|
}
|
||||||
|
@ -892,13 +915,23 @@ lf_setlock (lockf_t *lock, inode_t *node, lockf_t **clean)
|
||||||
|
|
||||||
/* Wait for the blocking object and its holding process. */
|
/* Wait for the blocking object and its holding process. */
|
||||||
HANDLE obj = block->open_lock_obj ();
|
HANDLE obj = block->open_lock_obj ();
|
||||||
|
if (!obj)
|
||||||
|
{
|
||||||
|
/* We can't synchronize on the lock event object.
|
||||||
|
Treat this as a deadlock-like situation for now. */
|
||||||
|
system_printf ("Can't sync with lock object hold by "
|
||||||
|
"Win32 pid %lu: %E", block->lf_wid);
|
||||||
|
NtClose (obj);
|
||||||
|
return EDEADLK;
|
||||||
|
}
|
||||||
HANDLE proc = OpenProcess (SYNCHRONIZE, FALSE, block->lf_wid);
|
HANDLE proc = OpenProcess (SYNCHRONIZE, FALSE, block->lf_wid);
|
||||||
if (!proc)
|
if (!proc)
|
||||||
{
|
{
|
||||||
/* If we can't synchronize on the process holding the lock,
|
/* If we can't synchronize on the process holding the lock,
|
||||||
we will never recognize when the lock has been abandoned.
|
we will never recognize when the lock has been abandoned.
|
||||||
Treat this as a deadlock-like situation for now. */
|
Treat this as a deadlock-like situation for now. */
|
||||||
debug_printf ("OpenProcess: %E");
|
system_printf ("Can't sync with process holding a lock "
|
||||||
|
"(Win32 pid %lu): %E", block->lf_wid);
|
||||||
NtClose (obj);
|
NtClose (obj);
|
||||||
return EDEADLK;
|
return EDEADLK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* ntdll.h. Contains ntdll specific stuff not defined elsewhere.
|
/* ntdll.h. Contains ntdll specific stuff not defined elsewhere.
|
||||||
|
|
||||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
|
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -189,8 +189,13 @@ 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_TRAVERSE 2
|
||||||
|
#define DIRECTORY_CREATE_OBJECT 4
|
||||||
|
#define DIRECTORY_CREATE_SUBDIRECTORY 8
|
||||||
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x0f)
|
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x0f)
|
||||||
|
|
||||||
|
#define EVENT_QUERY_STATE 1
|
||||||
|
|
||||||
typedef ULONG KAFFINITY;
|
typedef ULONG KAFFINITY;
|
||||||
|
|
||||||
typedef enum _SYSTEM_INFORMATION_CLASS
|
typedef enum _SYSTEM_INFORMATION_CLASS
|
||||||
|
|
Loading…
Reference in New Issue