diff --git a/src/exec.c b/src/exec.c index 49fb95a1..a0b7ca24 100644 --- a/src/exec.c +++ b/src/exec.c @@ -27,6 +27,7 @@ #include /* isdigit() */ #include #include +#include #include #include #include @@ -238,10 +239,63 @@ pid_t run_getty(char *tty, char *speed, char *term, int noclear, int console) return pid; } + +pid_t run_getty2(char *tty, char *cmd, char *args[], int console) +{ + pid_t pid; + + pid = fork(); + if (!pid) { + int i, fd; + struct sigaction sa; + /* Reset signal handlers that were set by the parent process */ + for (i = 1; i < NSIG; i++) + DFLSIG(sa, i, 0); + /* Detach from initial controlling TTY */ + vhangup(); + close(STDERR_FILENO); + close(STDOUT_FILENO); + close(STDIN_FILENO); + /* Attach TTY to console */ + fd = open(tty, O_RDWR); + if (fd != STDIN_FILENO) + exit(1); + + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + + prepare_tty(tty, "getty", console); + + if (ioctl(STDIN_FILENO, TIOCSCTTY, 1) < 0) + _pe("Failed TIOCSCTTY"); + + while (!fexist(SYNC_SHUTDOWN)) { + char c; + static const char msg[] = "\nPlease press Enter to activate this console."; + + if (fexist(SYNC_STOPPED)) { + sleep(1); + continue; + } + + (void)write(STDERR_FILENO, msg, sizeof(msg)); + while (read(STDIN_FILENO, &c, 1) == 1 && c != '\n') + continue; + + if (fexist(SYNC_STOPPED)) + continue; + + execv(cmd, args); + } + + close(fd); + vhangup(); + exit(0); } return pid; diff --git a/src/helpers.h b/src/helpers.h index 4c762850..cb06d81c 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -64,6 +64,7 @@ int complete (char *cmd, int pid); int run (char *cmd); int run_interactive (char *cmd, char *fmt, ...); pid_t run_getty (char *tty, char *speed, char *term, int noclear, int console); +pid_t run_getty2 (char *tty, char *cmd, char *args[], int console); int run_parts (char *dir, char *cmd); static inline void create(char *path, mode_t mode, uid_t uid, gid_t gid)