diff --git a/src/exec.c b/src/exec.c index 53deb0ab..c4c69061 100644 --- a/src/exec.c +++ b/src/exec.c @@ -423,6 +423,20 @@ pid_t run_getty2(char *tty, char *cmd, char *args[], int noclear, int nowait, st return pid; } +pid_t run_sh(char *tty, int noclear, int nowait, struct rlimit rlimit[]) +{ + pid_t pid; + + pid = fork(); + if (!pid) { + prepare_tty(tty, B0, "finit-sh", rlimit); + if (activate_console(noclear, nowait)) + _exit(sh(tty)); + } + + return pid; +} + int run_parts(char *dir, char *cmd) { struct dirent **e; diff --git a/src/getty.c b/src/getty.c index e27a9daa..169b0fcc 100644 --- a/src/getty.c +++ b/src/getty.c @@ -243,6 +243,48 @@ int getty(char *tty, speed_t speed, char *term, char *user) return do_login(name); } +int sh(char *tty) +{ + int fd; + char *arg0; + char *args[2] = { + NULL, + NULL + }; + size_t len; + + /* Detach from initial controlling TTY */ + vhangup(); + + fd = open(tty, O_RDWR); + if (fd < 0) + err(1, "Failed opening %s", tty); + + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + + if (ioctl(STDIN_FILENO, TIOCSCTTY, 1) < 0) + warn("Failed TIOCSCTTY"); + + /* The getty process is usually responsible for the UTMP login record */ + utmp_set_login(tty, NULL); + + /* Set up TTY, re-enabling ISIG et al. */ + stty(fd, B0); + close(fd); + + /* Start /bin/sh as a login shell, i.e. with a prefix '-' */ + len = strlen(_PATH_BSHELL) + 2; + arg0 = malloc(len); + if (!arg0) + err(1, "Failed allocating memory"); + snprintf(arg0, len, "-%s", _PATH_BSHELL); + args[0] = arg0; + + return execv(_PATH_BSHELL, args); +} + /** * Local Variables: * indent-tabs-mode: t diff --git a/src/helpers.h b/src/helpers.h index d4378482..a3fd0c69 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -52,6 +52,7 @@ struct fstab *getfsent (void); char *strip_line (char *line); int getty (char *tty, speed_t speed, char *term, char *user); +int sh (char *tty); int stty (int fd, speed_t speed); speed_t stty_parse_speed(char *baud); @@ -74,6 +75,7 @@ int run_interactive (char *cmd, char *fmt, ...); int exec_runtask (char *cmd, char *args[]); pid_t run_getty (char *tty, char *baud, char *term, int noclear, int nowait, struct rlimit rlimit[]); pid_t run_getty2 (char *tty, char *cmd, char *args[], int noclear, int nowait, struct rlimit rlimit[]); +pid_t run_sh (char *tty, int noclear, int nowait, struct rlimit rlimit[]); int run_parts (char *dir, char *cmd); static inline void create(char *path, mode_t mode, uid_t uid, gid_t gid) diff --git a/src/tty.c b/src/tty.c index 47be0a46..e22c2459 100644 --- a/src/tty.c +++ b/src/tty.c @@ -137,7 +137,7 @@ void tty_sweep(void) int tty_register(char *line, struct rlimit rlimit[], char *file) { tty_node_t *entry; - int insert = 0, noclear = 0, nowait = 0; + int insert = 0, noclear = 0, nowait = 0, nologin = 0; size_t i, num = 0; char *tok, *cmd = NULL, *args[TTY_MAX_ARGS]; char *dev = NULL, *baud = NULL; @@ -159,6 +159,8 @@ int tty_register(char *line, struct rlimit rlimit[], char *file) noclear = 1; else if (!strcmp(tok, "nowait")) nowait = 1; + else if (!strcmp(tok, "nologin")) + nologin = 1; else args[num++] = tok; @@ -241,6 +243,7 @@ int tty_register(char *line, struct rlimit rlimit[], char *file) entry->data.term = term ? strdup(term) : NULL; entry->data.noclear = noclear; entry->data.nowait = nowait; + entry->data.nologin = nologin; entry->data.runlevels = conf_parse_runlevels(runlevels); /* External getty */ @@ -392,6 +395,11 @@ void tty_start(finit_tty_t *tty) return; } + if (tty->nologin) { + tty->pid = run_sh(dev, tty->noclear, tty->nowait, tty->rlimit); + return; + } + if (!tty->cmd) tty->pid = run_getty(dev, tty->baud, tty->term, tty->noclear, tty->nowait, tty->rlimit); else diff --git a/src/tty.h b/src/tty.h index b739eaaa..1ed5d50b 100644 --- a/src/tty.h +++ b/src/tty.h @@ -38,6 +38,7 @@ typedef struct { char *term; int noclear; int nowait; + int nologin; int runlevels; char *cmd; /* NULL when running built-in getty */