summaryrefslogtreecommitdiff
path: root/lib/shell.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/shell.c')
-rw-r--r--lib/shell.c59
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);
+}