summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/path.cc
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2003-01-20 02:57:54 +0000
committerChristopher Faylor <me@cgf.cx>2003-01-20 02:57:54 +0000
commit7905c4f158c479c3d08e112c55f91be38aa70dae (patch)
tree9fcc54ea43fa128e60ecf3b52373ed25f77b382b /winsup/cygwin/path.cc
parent6f2480fbf706f944d20f8db3f17733ee8978987e (diff)
downloadcygnal-7905c4f158c479c3d08e112c55f91be38aa70dae.tar.gz
cygnal-7905c4f158c479c3d08e112c55f91be38aa70dae.tar.bz2
cygnal-7905c4f158c479c3d08e112c55f91be38aa70dae.zip
* pwdgrp.h (etc): Move to path.h.
(pwdgrp::max_lines): New field. (pwdgrp::curr_lines): New field. (pwdgrp::pwdgrp_buf): Ditto. (pwdgrp_buf_elem_size): Ditto. (pwdgrp_parse): Ditto. (pwdgrp::gets): Just declare here. (pwdgrp::load): Ditto. Just take one argument. (pwdgrp::load): Define overloaded function accepting passwd buf. (pwdgrp::load): Define overloaded function accepting group buf. * grp.cc: Use pwdgrp elements rather than standalone static variables throughout. (curr_lines): Eliminate. (max_lines): Ditto. (add_grp_line): Ditto. (parse_grp): Define as returning boolean. Accept void * arg and line count. Coerce first argument into __group32 buf reference. Increment curr_line as appropriate. (read_etc_group): Pass pwdgrp buffer to gr.load. * passwd.cc: Use pwdgrp elements rather than standalone static variables throughout. (curr_lines): Eliminate. (max_lines): Ditto. (add_grp_line): Ditto. (parse_passwd): Define as returning boolean. Accept void * arg and line count. Coerce first argument into passwd buf reference. Increment curr_line as appropriate. (read_etc_group): Pass pwdgrp buffer to pr.load. * path.cc (etc::fn): Extend buffer size to allow index by 1 rather than zero. (etc::last_modified): Ditto. (etc::change_possible): Ditto. Renamed from sawchange. Change to signed char since elements are now tri-state. (etc::init): Assume "handle" is 1 based rather than 0. (etc::test_file_change): New function. Sets change_possible based on file date comparison. (etc::dir_changed): Check file states immediately after changed_h is initialized to avoid a race. (etc::file_changed): Use test_file_change to detect if file needs to be updated. * path.h (etc): Move class here from pwdgrp.h. * uinfo.cc: Move etc:: functions to path.cc. Move pwdgrp functions here. (pwdgrp::gets): Eliminate buf checks. Just check eptr and set lptr. (pwdgrp::add_line): New function. (pwdgrp::load): Call generic add_line function which will call correct parser.
Diffstat (limited to 'winsup/cygwin/path.cc')
-rw-r--r--winsup/cygwin/path.cc101
1 files changed, 101 insertions, 0 deletions
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index aeeea9d87..835fa9838 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -3753,3 +3753,104 @@ out:
MALLOC_CHECK;
return buf;
}
+
+int etc::curr_ix = 0;
+/* Note that the first elements of the below arrays are unused */
+signed char etc::change_possible[MAX_ETC_FILES + 1];
+const char *etc::fn[MAX_ETC_FILES + 1];
+FILETIME etc::last_modified[MAX_ETC_FILES + 1];
+
+int
+etc::init (int n, const char *etc_fn)
+{
+ if (n > 0)
+ /* ok */;
+ else if (++curr_ix <= MAX_ETC_FILES)
+ n = curr_ix;
+ else
+ api_fatal ("internal error");
+
+ fn[n] = etc_fn;
+ change_possible[n] = false;
+ (void) test_file_change (n);
+ paranoid_printf ("fn[%d] %s, curr_ix %d", n, fn[n], curr_ix);
+ return n;
+}
+
+bool
+etc::test_file_change (int n)
+{
+ HANDLE h;
+ WIN32_FIND_DATA data;
+ bool res;
+
+ if (change_possible[n] < 0)
+ {
+ res = true;
+ paranoid_printf ("fn[%d] %s, already marked changed", n, fn[n]);
+ }
+ else if ((h = FindFirstFile (fn[n], &data)) == INVALID_HANDLE_VALUE)
+ {
+ res = true;
+ memset (last_modified + n, 0, sizeof (last_modified[n]));
+ debug_printf ("FindFirstFile failed, %E");
+ }
+ else
+ {
+ FindClose (h);
+ res = CompareFileTime (&data.ftLastWriteTime, last_modified + n) > 0;
+ last_modified[n] = data.ftLastWriteTime;
+ change_possible[n] = -res;
+ debug_printf ("FindFirstFile succeeded");
+ }
+
+ paranoid_printf ("fn[%d] %s res %d", n, fn[n], res);
+ return res;
+}
+
+bool
+etc::dir_changed (int n)
+{
+ if (!change_possible[n])
+ {
+ static HANDLE changed_h NO_COPY;
+
+ if (!changed_h)
+ {
+ path_conv pwd ("/etc");
+ changed_h = FindFirstChangeNotification (pwd, FALSE,
+ FILE_NOTIFY_CHANGE_LAST_WRITE);
+#ifdef DEBUGGING
+ if (changed_h == INVALID_HANDLE_VALUE)
+ system_printf ("Can't open /etc for checking, %E", (char *) pwd,
+ changed_h);
+#endif
+ for (int i = 1; i <= curr_ix; i++)
+ (void) test_file_change (i);
+ }
+
+ if (changed_h == INVALID_HANDLE_VALUE)
+ (void) test_file_change (n); /* semi-brute-force way */
+ else if (WaitForSingleObject (changed_h, 0) == WAIT_OBJECT_0)
+ {
+ (void) FindNextChangeNotification (changed_h);
+ memset (change_possible, 1, sizeof change_possible);
+ }
+ }
+
+ paranoid_printf ("fn[%d] %s change_possible %d", n, fn[n], change_possible[n]);
+ return change_possible[n];
+}
+
+bool
+etc::file_changed (int n)
+{
+ bool res = false;
+ if (!fn[n])
+ res = true;
+ else if (dir_changed (n) && test_file_change (n))
+ res = true;
+ change_possible[n] = 0;
+ paranoid_printf ("fn[%d] %s res %d", n, fn[n], res);
+ return res;
+}