From ec2dfaa244775649c6b6b5eebc60d5af7d5ee4dd Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 24 Mar 2012 17:45:16 +0100 Subject: [PATCH] pty: add --login option Allow to specify a separate login-program that is executed instead of the default. All arguments specified after --login are considered argv[] of the new process and not parsed by the library. Signed-off-by: David Herrmann --- src/conf.c | 40 +++++++++++++++++++++++++++++++--------- src/conf.h | 5 +++++ src/pty.c | 9 ++------- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/conf.c b/src/conf.c index 7899ffe..c203f81 100644 --- a/src/conf.c +++ b/src/conf.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -47,14 +48,23 @@ static void print_help() "Usage:\n" "\t%1$s [options]\n" "\t%1$s [options] -h\n" + "\t%1$s [options] -l /bin/sh [sh-arguments]\n" + "\n" "General Options:\n" "\t-h, --help Print this help and exit\n" "\t-v, --verbose Print verbose messages\n" "\t --debug Enable debug mode\n" "\t --silent Suppress notices and warnings\n" "\t-s, --switchvt Automatically switch to VT\n" + "\n" + "Login Process Options:\n" + "\t-l, --login Start the given login process instead\n" + "\t of the default process; all following\n" + "\t arguments are passed as argv to this\n" + "\t process\n" + "\n" "Input Device Options:\n" - "\t-l, --xkb-layout Set XkbLayout for input devices\n" + "\t --xkb-layout Set XkbLayout for input devices\n" "\t --xkb-variant Set XkbVariant for input devices\n" "\t --xkb-options Set XkbOptions for input devices\n", "kmscon"); @@ -70,9 +80,10 @@ int conf_parse_argv(int argc, char **argv) { "debug", no_argument, &conf_global.debug, 1 }, { "silent", no_argument, &conf_global.silent, 1 }, { "switchvt", no_argument, NULL, 's' }, - { "xkb-layout", required_argument, NULL, 'l' }, - { "xkb-variant", required_argument, NULL, -1 }, - { "xkb-options", required_argument, NULL, -2 }, + { "xkb-layout", required_argument, NULL, -1 }, + { "xkb-variant", required_argument, NULL, -2 }, + { "xkb-options", required_argument, NULL, -3 }, + { "login", required_argument, NULL, 'l' }, { NULL, 0, NULL, 0 }, }; int idx; @@ -99,15 +110,19 @@ int conf_parse_argv(int argc, char **argv) case 's': conf_global.switchvt = 1; break; - case 'l': + case -1: conf_global.xkb_layout = optarg; break; - case -1: + case -2: conf_global.xkb_variant = optarg; break; - case -2: + case -3: conf_global.xkb_options = optarg; break; + case 'l': + conf_global.login = optarg; + --optind; + goto done; case ':': fprintf(stderr, "Missing argument for option -%c\n", optopt); @@ -123,8 +138,15 @@ int conf_parse_argv(int argc, char **argv) } } - if (optind != argc) - fprintf(stderr, "Unparsed remaining arguments\n"); +done: + if (conf_global.login) { + conf_global.argv = &argv[optind]; + } else { + conf_global.login = getenv("SHELL") ? : _PATH_BSHELL; + conf_global.argv = (char*[]){ conf_global.login, "-i", NULL }; + if (optind != argc) + fprintf(stderr, "Unparsed remaining arguments\n"); + } if (conf_global.debug) conf_global.verbose = 1; diff --git a/src/conf.h b/src/conf.h index 9e71894..ed69845 100644 --- a/src/conf.h +++ b/src/conf.h @@ -58,6 +58,11 @@ struct conf_obj { const char *xkb_layout; const char *xkb_variant; const char *xkb_options; + + /* login process */ + char *login; + /* argv for login process */ + char **argv; }; extern struct conf_obj conf_global; diff --git a/src/pty.c b/src/pty.c index 9d3710c..a596d78 100644 --- a/src/pty.c +++ b/src/pty.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -33,7 +32,7 @@ #include #include #include - +#include "conf.h" #include "eloop.h" #include "log.h" #include "misc.h" @@ -120,12 +119,8 @@ void kmscon_pty_unref(struct kmscon_pty *pty) static void __attribute__((noreturn)) exec_child(int pty_master) { - const char *sh; - setenv("TERM", "linux", 1); - - sh = getenv("SHELL") ?: _PATH_BSHELL; - execlp(sh, sh, "-i", NULL); + execvp(conf_global.login, conf_global.argv); log_err("failed to exec child: %m");