+2024-05-21 Collin Funk <collin.funk1@gmail.com>
+
+ 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 <eggert@cs.ucla.edu>
boot-time: port to Alpine 3.20.0_rc2
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.
#endif
#include <stdlib.h>
+#include <string.h>
#include <ctype.h>
#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",
static char *line = NULL;
/* Number of bytes allocated for 'line'. */
-static idx_t line_size = 0;
+static size_t line_size = 0;
\f
/* Return an entry from the shells file, ignoring comment lines.
If the file doesn't exist, use the list in DEFAULT_SHELLS (above).
}
}
- 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. */
}
}
-/* 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)