diff options
Diffstat (limited to 'lib/shell.c')
-rw-r--r-- | lib/shell.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/lib/shell.c b/lib/shell.c new file mode 100644 index 0000000..9a38b40 --- /dev/null +++ b/lib/shell.c @@ -0,0 +1,59 @@ +#include "lslib.h" + +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +void setup_environment(const char *shell, bool new_env, bool clear_env, const struct passwd *pw) { + if (!shell || !shell[0]) + shell = DEFAULT_SHELL; + + if (clear_env) { + const char* term; + term = getenv("TERM"); + clearenv(); + if (term) + xsetenv("TERM", term); + xsetenv("PATH", DEFAULT_PATH); + } + + if (new_env) { + xsetenv("USER", pw->pw_name); + xsetenv("LOGNAME", pw->pw_name); + xsetenv("HOME", pw->pw_dir); + xsetenv("SHELL", shell); + } +} + +void exec_shell(const char *shell, bool loginshell, const char **additional_args) { + + const char** args; + + args = additional_args; + while (args && *args) + args++; + + args = xzalloc(sizeof(args[0]) * (2 + (args - additional_args))); + + if (!shell || !shell[0]) + shell = DEFAULT_SHELL; + + args[0] = get_last_component(shell); + + if (loginshell) { + size_t len = strlen(shell) + 2; + char* arg = xalloc(len); + arg[0] = '-'; + memcpy(&arg[1], shell, len - 1); + args[0] = arg; + } + + if (additional_args) { + int count = 0; + while (*additional_args) + args[++count] = *additional_args++; + } + + execv(shell, (char**) args); + error("cannot execute '%s'", shell); +} |