From 1b61bf152b3972c6afd3f938d7654c7738b1c2bc Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 21 Aug 2007 12:37:40 +0000 Subject: * ntdll.h (NtNotifyChangeDirectoryFile): Declare. (NtQueryAttributesFile): Move to maintain alphabetical order of declarations. Add comment to note that timestamp information returned by NtQueryAttributesFile is unreliable. * path.h (etc::changed_h): Move here. (etc::fn): Change type to OBJECT_ATTRIBUTES. (etc::last_modified): Change type to LARGE_INTEGER. (etc::init): Take PUNICODE_STRING as second argument. * path.cc: Accomodate above changes. (etc::test_file_change): Use NT native functions. (etc::dir_changed): Ditto. * uinfo.cc (pwdgrp::load): Call etc::init with NT native path. --- winsup/cygwin/path.cc | 86 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 23 deletions(-) (limited to 'winsup/cygwin/path.cc') diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index e3377a069..8dcccc847 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -4456,11 +4456,11 @@ out: int etc::curr_ix = 0; /* Note that the first elements of the below arrays are unused */ bool etc::change_possible[MAX_ETC_FILES + 1]; -const char *etc::fn[MAX_ETC_FILES + 1]; -FILETIME etc::last_modified[MAX_ETC_FILES + 1]; +OBJECT_ATTRIBUTES etc::fn[MAX_ETC_FILES + 1]; +LARGE_INTEGER etc::last_modified[MAX_ETC_FILES + 1]; int -etc::init (int n, const char *etc_fn) +etc::init (int n, PUNICODE_STRING etc_fn) { if (n > 0) /* ok */; @@ -4469,35 +4469,36 @@ etc::init (int n, const char *etc_fn) else api_fatal ("internal error"); - fn[n] = etc_fn; + InitializeObjectAttributes (&fn[n], etc_fn, OBJ_CASE_INSENSITIVE, NULL, NULL); change_possible[n] = false; test_file_change (n); - paranoid_printf ("fn[%d] %s, curr_ix %d", n, fn[n], curr_ix); + paranoid_printf ("fn[%d] %S, curr_ix %d", n, fn[n].ObjectName, curr_ix); return n; } bool etc::test_file_change (int n) { - HANDLE h; - WIN32_FIND_DATA data; + NTSTATUS status; + FILE_NETWORK_OPEN_INFORMATION fnoi; bool res; - if ((h = FindFirstFile (fn[n], &data)) == INVALID_HANDLE_VALUE) + status = NtQueryFullAttributesFile (&fn[n], &fnoi); + if (!NT_SUCCESS (status)) { res = true; memset (last_modified + n, 0, sizeof (last_modified[n])); - debug_printf ("FindFirstFile failed, %E"); + debug_printf ("NtQueryFullAttributesFile (%S) failed, %p", + fn[n].ObjectName, status); } else { - FindClose (h); - res = CompareFileTime (&data.ftLastWriteTime, last_modified + n) > 0; - last_modified[n] = data.ftLastWriteTime; - debug_printf ("FindFirstFile succeeded"); + res = CompareFileTime ((FILETIME *) &fnoi.LastWriteTime, + (FILETIME *) last_modified + n) > 0; + last_modified[n].QuadPart = fnoi.LastWriteTime.QuadPart; } - paranoid_printf ("fn[%d] %s res %d", n, fn[n], res); + paranoid_printf ("fn[%d] %S res %d", n, fn[n].ObjectName, res); return res; } @@ -4507,17 +4508,42 @@ etc::dir_changed (int n) if (!change_possible[n]) { static HANDLE changed_h NO_COPY; + NTSTATUS status; + IO_STATUS_BLOCK io; if (!changed_h) { - path_conv pwd ("/etc"); - changed_h = FindFirstChangeNotification (pwd.get_win32 (), FALSE, - FILE_NOTIFY_CHANGE_LAST_WRITE - | FILE_NOTIFY_CHANGE_FILE_NAME); + OBJECT_ATTRIBUTES attr; + + path_conv dir ("/etc"); + status = NtOpenFile (&changed_h, SYNCHRONIZE | FILE_LIST_DIRECTORY, + dir.get_object_attr (attr, sec_none_nih), &io, + FILE_SHARE_VALID_FLAGS, FILE_DIRECTORY_FILE); + if (!NT_SUCCESS (status)) + { +#ifdef DEBUGGING + system_printf ("NtOpenFile (%S) failed, %p", + dir.get_nt_native_path (), status); +#endif + changed_h = INVALID_HANDLE_VALUE; + } + else + { + status = NtNotifyChangeDirectoryFile (changed_h, NULL, NULL, + NULL, &io, NULL, 0, + FILE_NOTIFY_CHANGE_LAST_WRITE + | FILE_NOTIFY_CHANGE_FILE_NAME, + FALSE); + if (!NT_SUCCESS (status)) + { #ifdef DEBUGGING - if (changed_h == INVALID_HANDLE_VALUE) - system_printf ("Can't open %s for checking, %E", (char *) pwd); + system_printf ("NtNotifyChangeDirectoryFile (1) failed, %p", + status); #endif + NtClose (changed_h); + changed_h = INVALID_HANDLE_VALUE; + } + } memset (change_possible, true, sizeof (change_possible)); } @@ -4525,12 +4551,26 @@ etc::dir_changed (int n) change_possible[n] = true; else if (WaitForSingleObject (changed_h, 0) == WAIT_OBJECT_0) { - FindNextChangeNotification (changed_h); + status = NtNotifyChangeDirectoryFile (changed_h, NULL, NULL, + NULL, &io, NULL, 0, + FILE_NOTIFY_CHANGE_LAST_WRITE + | FILE_NOTIFY_CHANGE_FILE_NAME, + FALSE); + if (!NT_SUCCESS (status)) + { +#ifdef DEBUGGING + system_printf ("NtNotifyChangeDirectoryFile (2) failed, %p", + status); +#endif + NtClose (changed_h); + changed_h = INVALID_HANDLE_VALUE; + } memset (change_possible, true, sizeof change_possible); } } - paranoid_printf ("fn[%d] %s change_possible %d", n, fn[n], change_possible[n]); + paranoid_printf ("fn[%d] %S change_possible %d", + n, fn[n].ObjectName, change_possible[n]); return change_possible[n]; } @@ -4541,7 +4581,7 @@ etc::file_changed (int n) if (dir_changed (n) && test_file_change (n)) res = true; change_possible[n] = false; /* Change is no longer possible */ - paranoid_printf ("fn[%d] %s res %d", n, fn[n], res); + paranoid_printf ("fn[%d] %S res %d", n, fn[n].ObjectName, res); return res; } -- cgit v1.2.3