From: Collin Funk Date: Tue, 21 May 2024 23:35:09 +0000 (-0700) Subject: getusershell: Split file by lines instead of spaces. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=4b3be1402af74cfcffe7fa3a77d3887bffb22e66;p=gnulib.git getusershell: Split file by lines instead of spaces. * lib/getusershell.c: Include string.h and filename.h (GNULIB_GETUSERSHELL_SINGLE_THREAD): Remove conditional to include unlocked stdio functions that are no longer used. (readname): Remove function. (getusershell): Use getline and process the string instead of using readname. Return the first absolute file name. * modules/getusershell (Depends-on): Remove unlocked-io-internal. Add getline and filename. * doc/multithread.texi (Multithreading Optimizations): Don't mention GNULIB_GETUSERSHELL_SINGLE_THREAD. --- diff --git a/ChangeLog b/ChangeLog index 0baff3aecc..f94a39a2bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2024-05-21 Collin Funk + + getusershell: Split file by lines instead of spaces. + * lib/getusershell.c: Include string.h and filename.h + (GNULIB_GETUSERSHELL_SINGLE_THREAD): Remove conditional to include + unlocked stdio functions that are no longer used. + (readname): Remove function. + (getusershell): Use getline and process the string instead of using + readname. Return the first absolute file name. + * modules/getusershell (Depends-on): Remove unlocked-io-internal. + Add getline and filename. + * doc/multithread.texi (Multithreading Optimizations): Don't mention + GNULIB_GETUSERSHELL_SINGLE_THREAD. + 2024-05-21 Paul Eggert boot-time: port to Alpine 3.20.0_rc2 diff --git a/doc/multithread.texi b/doc/multithread.texi index 7d8126e8f3..424e1d2a75 100644 --- a/doc/multithread.texi +++ b/doc/multithread.texi @@ -293,10 +293,6 @@ This macro optimizes the functions @code{mbrtowc}, @code{mbrtoc32}, and You can get this macro defined by including the Gnulib module @code{wchar-single}. @item -You may define the C macro @code{GNULIB_GETUSERSHELL_SINGLE_THREAD}, if all the -programs in your package invoke the functions @code{setusershell}, -@code{getusershell}, @code{endusershell} only from a single thread. -@item You may define the C macro @code{GNULIB_EXCLUDE_SINGLE_THREAD}, if all the programs in your package invoke the functions of the @code{exclude} module only from a single thread. diff --git a/lib/getusershell.c b/lib/getusershell.c index 4da5bff37f..356b8023d5 100644 --- a/lib/getusershell.c +++ b/lib/getusershell.c @@ -34,17 +34,13 @@ #endif #include +#include #include #include "stdio--.h" +#include "filename.h" #include "xalloc.h" -#if GNULIB_GETUSERSHELL_SINGLE_THREAD -# include "unlocked-io.h" -#endif - -static idx_t readname (char **, idx_t *, FILE *); - #if ! defined ADDITIONAL_DEFAULT_SHELLS && defined __MSDOS__ # define ADDITIONAL_DEFAULT_SHELLS \ "c:/dos/command.com", "c:/windows/command.com", "c:/command.com", @@ -70,7 +66,7 @@ static FILE *shellstream = NULL; static char *line = NULL; /* Number of bytes allocated for 'line'. */ -static idx_t line_size = 0; +static size_t line_size = 0; /* Return an entry from the shells file, ignoring comment lines. If the file doesn't exist, use the list in DEFAULT_SHELLS (above). @@ -99,12 +95,46 @@ getusershell (void) } } - while (readname (&line, &line_size, shellstream)) + for (;;) { - if (*line != '#') - return line; + ssize_t nread = getline (&line, &line_size, shellstream); + + /* End of file. */ + if (nread == -1) + return NULL; + /* Skip empty lines. */ + else if (nread > 1) + { + char *start = line; + char *comment = strchr (start, '#'); + char *end; + + if (comment != NULL) + { + /* Trim the comment mark. */ + comment = '\0'; + end = comment; + } + else + { + /* Trim the newline. */ + end = start + nread; + if (end[-1] == '\n') + *--end = '\0'; + } + + /* Skip leading whitespace. */ + while (start < end && isspace ((unsigned char) start[0])) + start++; + /* Trim trailing whitespace. */ + while (start < end && isspace ((unsigned char) end[-1])) + *--end = '\0'; + + /* Only return absolute file names. */ + if (start < end && IS_ABSOLUTE_FILE_NAME (start)) + return start; + } } - return NULL; /* End of file. */ } /* Rewind the shells file. */ @@ -129,37 +159,6 @@ endusershell (void) } } -/* Read a line from STREAM, removing any newline at the end. - Place the result in *NAME, which is malloc'd - and/or realloc'd as necessary and can start out NULL, - and whose size is passed and returned in *SIZE. - - Return the number of bytes placed in *NAME - if some nonempty sequence was found, otherwise 0. */ - -static idx_t -readname (char **name, idx_t *size, FILE *stream) -{ - int c; - size_t name_index = 0; - - /* Skip blank space. */ - while ((c = getc (stream)) != EOF && isspace (c)) - /* Do nothing. */ ; - - for (;;) - { - if (*size <= name_index) - *name = xpalloc (*name, size, 1, -1, sizeof **name); - if (c == EOF || isspace (c)) - break; - (*name)[name_index++] = c; - c = getc (stream); - } - (*name)[name_index] = '\0'; - return name_index; -} - #ifdef TEST int main (void) diff --git a/modules/getusershell b/modules/getusershell index 2f47c62e3d..a4a40852ac 100644 --- a/modules/getusershell +++ b/modules/getusershell @@ -9,7 +9,8 @@ Depends-on: unistd extensions fopen-safer [test $HAVE_GETUSERSHELL = 0 || test $REPLACE_GETUSERSHELL = 1] -unlocked-io-internal [test $HAVE_GETUSERSHELL = 0 || test $REPLACE_GETUSERSHELL = 1] +getline [test $HAVE_GETUSERSHELL = 0 || test $REPLACE_GETUSERSHELL = 1] +filename [test $HAVE_GETUSERSHELL = 0 || test $REPLACE_GETUSERSHELL = 1] xalloc [test $HAVE_GETUSERSHELL = 0 || test $REPLACE_GETUSERSHELL = 1] configure.ac: