From: Alessandro Ratti Date: Sun, 23 Nov 2025 15:20:57 +0000 (+0100) Subject: lib: introduce ul_default_shell() for consistent shell resolution X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bd89462910f32042dbe1882044a5c076638a89b9;p=thirdparty%2Futil-linux.git lib: introduce ul_default_shell() for consistent shell resolution Add a new ul_default_shell() function to provide consistent shell resolution across util-linux tools. The function follows a priority order: $SHELL environment variable, user's shell from passwd database, and finally _PATH_BSHELL as fallback. The function supports flags to control its behavior: - UL_SHELL_NOENV: skip $SHELL environment variable check - UL_SHELL_NOPWD: skip passwd database lookup This addresses the issue where tools like script(1) would default to /bin/sh without respecting the user's configured shell, potentially causing data loss. Addresses: https://github.com/util-linux/util-linux/issues/3865 Suggested-by: Karel Zak Suggested-by: Thomas Weißschuh Signed-off-by: Alessandro Ratti --- diff --git a/include/shells.h b/include/shells.h index c770a13ba..7f2d2469c 100644 --- a/include/shells.h +++ b/include/shells.h @@ -4,7 +4,14 @@ #ifndef UTIL_LINUX_SHELLS_H #define UTIL_LINUX_SHELLS_H +#include + +#define UL_SHELL_NOENV (1 << 0) +#define UL_SHELL_NOPWD (1 << 1) + extern void print_shells(FILE *out, const char *format); extern int is_known_shell(const char *shell_name); +const char *ul_default_shell(int flags, const struct passwd *pw); + #endif /* UTIL_LINUX_SHELLS_H */ diff --git a/lib/Makemodule.am b/lib/Makemodule.am index a9da57734..1d598faa2 100644 --- a/lib/Makemodule.am +++ b/lib/Makemodule.am @@ -49,6 +49,7 @@ libcommon_la_SOURCES = \ if LINUX libcommon_la_SOURCES += \ lib/linux_version.c \ + lib/shells.c \ lib/loopdev.c endif diff --git a/lib/meson.build b/lib/meson.build index 0f94a9b99..cb35ecbd6 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -25,6 +25,7 @@ lib_common_sources = ''' randutils.c sha1.c sha256.c + shells.c signames.c strutils.c strv.c diff --git a/lib/shells.c b/lib/shells.c index 13f293c5e..ef2aecd0f 100644 --- a/lib/shells.c +++ b/lib/shells.c @@ -1,6 +1,11 @@ /* * SPDX-License-Identifier: GPL-2.0-or-later */ +#include +#include +#include +#include +#include #include #if defined (HAVE_LIBECONF) && defined (USE_VENDORDIR) #include @@ -116,3 +121,24 @@ extern int is_known_shell(const char *shell_name) #endif return ret; } + +const char *ul_default_shell(int flags, const struct passwd *pw) +{ + const char *shell = NULL; + + if (!(flags & UL_SHELL_NOENV)) { + shell = getenv("SHELL"); + if (shell && *shell) + return shell; + } + if (!(flags & UL_SHELL_NOPWD)) { + if (!pw) + pw = getpwuid(getuid()); + if (pw) + shell = pw->pw_shell; + if (shell && *shell) + return shell; + } + + return _PATH_BSHELL; +}