diff options
Diffstat (limited to 'winsup/cygwin/grp.cc')
-rw-r--r-- | winsup/cygwin/grp.cc | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index 3e0ab3e88..600302c95 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -23,6 +23,7 @@ details. */ #include "security.h" #include "fhandler.h" #include "dtable.h" +#include "path.h" #include "cygheap.h" #include "cygerrno.h" @@ -51,7 +52,47 @@ enum grp_state { emulated, loaded }; -static grp_state group_state = uninitialized; +class grp_check { + grp_state state; + FILETIME last_modified; + char grp_w32[MAX_PATH]; + +public: + grp_check () : state (uninitialized) + { + last_modified.dwLowDateTime = last_modified.dwHighDateTime = 0; + grp_w32[0] = '\0'; + } + operator grp_state () + { + HANDLE h; + WIN32_FIND_DATA data; + + if (!grp_w32[0]) /* First call. */ + { + path_conv g ("/etc/group", PC_SYM_FOLLOW | PC_FULL); + if (!g.error) + strcpy (grp_w32, g.get_win32 ()); + } + + if ((h = FindFirstFile (grp_w32, &data)) != INVALID_HANDLE_VALUE) + { + if (CompareFileTime (&data.ftLastWriteTime, &last_modified) > 0) + { + state = uninitialized; + last_modified = data.ftLastWriteTime; + } + FindClose (h); + } + return state; + } + void operator = (grp_state nstate) + { + state = nstate; + } +}; + +static grp_check group_state; static int parse_grp (struct group &grp, const char *line) @@ -153,6 +194,16 @@ read_etc_group () if (group_state != initializing) { group_state = initializing; + if (max_lines) /* When rereading, free allocated memory first. */ + { + for (int i = 0; i < curr_lines; ++i) + { + free (group_buf[i].gr_name); + free (group_buf[i].gr_mem); + } + free (group_buf); + curr_lines = max_lines = 0; + } FILE *f = fopen (etc_group, "rt"); |