openvt,getty,vfork_daemon_rexec,mount: tighten up fd cleanup code (will close all fd's > 2 on daemonization now) getty: fix "getty -" support, and also do not try to chown/chmod "-" telnetd: fix "lost ctty" bug Yet another attempt on saner function names: bb_sanitize_server_stdio(0/1) -> bb_sanitize
No binary (build failed)
—
(log yok)
| @@ -17,7 +17,6 @@ int openvt_main(int argc, char **argv) | |
| int fd; | |
| char vtname[sizeof(VC_FORMAT) + 2]; | |
| - | |
| if (argc < 3) { | |
| bb_show_usage(); | |
| } | |
| @@ -25,18 +24,16 @@ int openvt_main(int argc, char **argv) | |
| sprintf(vtname, VC_FORMAT, (int)xatoul_range(argv[1], 1, 63)); | |
| if (fork() == 0) { | |
| - | /* leave current vt */ |
| - | if (setsid() < 0) { |
| - | bb_perror_msg_and_die("setsid"); |
| - | } |
| - | close(0); /* so that new vt becomes stdin */ |
| - | |
| + | /* child */ |
| + | /* leave current vt (controlling tty) */ |
| + | setsid(); |
| /* and grab new one */ | |
| fd = xopen(vtname, O_RDWR); | |
| - | |
| - | /* Reassign stdout and sterr */ |
| + | /* Reassign stdin, stdout and sterr */ |
| + | dup2(fd, STDIN_FILENO); |
| dup2(fd, STDOUT_FILENO); | |
| dup2(fd, STDERR_FILENO); | |
| + | while (fd > 2) close(fd--); |
| execvp(argv[2], &argv[2]); | |
| _exit(1); | |
| @@ -291,8 +291,8 @@ int start_stop_daemon_main(int argc, char **argv) | |
| } | |
| *--argv = startas; | |
| if (opt & OPT_BACKGROUND) { | |
| - | xdaemon(0, 0); |
| setsid(); | |
| + | bb_daemonize(); |
| } | |
| if (opt & OPT_MAKEPID) { | |
| /* user wants _us_ to make the pidfile */ | |
| @@ -268,7 +268,9 @@ extern void xsetgid(gid_t gid); | |
| extern void xsetuid(uid_t uid); | |
| extern void xdaemon(int nochdir, int noclose); | |
| /* More clever/thorough xdaemon */ | |
| - | extern void bb_sanitize_server_stdio(int daemonize); |
| + | extern void bb_sanitize_stdio_maybe_daemonize(int daemonize); |
| + | extern void bb_sanitize_stdio(void); |
| + | extern void bb_daemonize(void); |
| extern void xchdir(const char *path); | |
| extern void xsetenv(const char *key, const char *value); | |
| extern int xopen(const char *pathname, int flags); | |
| @@ -35,8 +35,8 @@ void vfork_daemon_rexec(int nochdir, int noclose, | |
| dup2(fd, STDIN_FILENO); | |
| dup2(fd, STDOUT_FILENO); | |
| dup2(fd, STDERR_FILENO); | |
| - | if (fd > 2) |
| - | close(fd); |
| + | while (fd > 2) |
| + | close(fd--); |
| } | |
| vfork_args = xzalloc(sizeof(char *) * (argc + 3)); | |
| @@ -509,7 +509,7 @@ void xdaemon(int nochdir, int noclose) | |
| } | |
| #endif | |
| - | void bb_sanitize_server_stdio(int daemonize) |
| + | void bb_sanitize_stdio_maybe_daemonize(int daemonize) |
| { | |
| int fd; | |
| /* Mega-paranoid */ | |
| @@ -523,8 +523,8 @@ void bb_sanitize_server_stdio(int daemonize) | |
| if (pid) /* parent */ | |
| exit(0); | |
| /* child */ | |
| - | setsid(); |
| /* if daemonizing, make sure we detach from stdio */ | |
| + | setsid(); |
| dup2(fd, 0); | |
| dup2(fd, 1); | |
| dup2(fd, 2); | |
| @@ -532,6 +532,14 @@ void bb_sanitize_server_stdio(int daemonize) | |
| while (fd > 2) | |
| close(fd--); /* close everything after fd#2 */ | |
| } | |
| + | void bb_sanitize_stdio(void) |
| + | { |
| + | bb_sanitize_stdio_maybe_daemonize(0); |
| + | } |
| + | void bb_daemonize(void) |
| + | { |
| + | bb_sanitize_stdio_maybe_daemonize(1); |
| + | } |
| // Die with an error message if we can't open a new socket. | |
| int xsocket(int domain, int type, int protocol) | |
| @@ -211,7 +211,7 @@ static void parse_args(int argc, char **argv, struct options *op) | |
| bb_show_usage(); | |
| /* we loosen up a bit and accept both "baudrate tty" and "tty baudrate" */ | |
| - | if ('0' <= argv[0][0] && argv[0][0] <= '9') { |
| + | if (isdigit(argv[0][0])) { |
| /* a number first, assume it's a speed (BSD style) */ | |
| parse_speeds(op, argv[0]); /* baud rate(s) */ | |
| op->tty = argv[1]; /* tty name */ | |
| @@ -255,10 +255,8 @@ static void open_tty(char *tty, struct termios *tp, int local) | |
| debug("open(2)\n"); | |
| fd = xopen(tty, O_RDWR | O_NONBLOCK); | |
| - | if (fd) { |
| - | xdup2(fd, 0, tty); |
| - | close(fd); |
| - | } |
| + | xdup2(fd, 0, tty); |
| + | while (fd > 2) close(fd--); |
| } else { | |
| /* | |
| * Standard input should already be connected to an open port. Make | |
| @@ -327,8 +325,10 @@ static void open_tty(char *tty, struct termios *tp, int local) | |
| } | |
| } | |
| #else | |
| - | chown(tty, 0, 0); /* root, sys */ |
| - | chmod(tty, 0622); /* crw--w--w- */ |
| + | if (NOT_LONE_DASH(tty)) { |
| + | chown(tty, 0, 0); /* 0:0 */ |
| + | chmod(tty, 0622); /* crw--w--w- */ |
| + | } |
| #endif | |
| if (chdir_to_root) | |
| xchdir("/"); | |
| @@ -736,22 +736,14 @@ int getty_main(int argc, char **argv) | |
| /* Already too late because of theoretical | |
| * possibility of getty --help somehow triggered | |
| * inadvertently before we reach this. Oh well. */ | |
| - | close(0); |
| - | close(1); |
| - | close(2); |
| logmode = LOGMODE_NONE; | |
| - | #ifdef __linux__ |
| setsid(); | |
| - | #endif |
| - | /* Was "/dev/console". Why should we spam *system console* |
| - | * if there is a problem with getty on /dev/ttyS15?... */ |
| nullfd = xopen(bb_dev_null, O_RDWR); | |
| - | if (nullfd) { |
| - | dup2(nullfd, 0); |
| - | close(nullfd); |
| - | } |
| - | dup2(0, 1); |
| - | dup2(0, 2); |
| + | /* dup2(nullfd, 0); - no, because of possible "getty - 9600" */ |
| + | /* open_tty() will take care of fd# 0 anyway */ |
| + | dup2(nullfd, 1); |
| + | dup2(nullfd, 2); |
| + | while (nullfd > 2) close(nullfd--); |
| /* We want special flavor of error_msg_and_die */ | |
| die_sleep = 10; | |
| msg_eol = "\r\n"; | |
| @@ -15,9 +15,6 @@ | |
| */ | |
| #include "busybox.h" | |
| - | #include <stdio.h> |
| - | #include <unistd.h> |
| - | #include <stdlib.h> |
| int setsid_main(int argc, char *argv[]) | |
| { | |
| @@ -25,7 +22,7 @@ int setsid_main(int argc, char *argv[]) | |
| bb_show_usage(); | |
| if (getpgrp() == getpid()) { | |
| - | switch (fork()){ |
| + | switch (fork()) { |
| case -1: | |
| bb_perror_msg_and_die("fork"); | |
| case 0: | |
| @@ -33,8 +30,8 @@ int setsid_main(int argc, char *argv[]) | |
| default: /* parent */ | |
| exit(0); | |
| } | |
| - | /* child falls through */ |
| } | |
| + | /* child */ |
| setsid(); /* no error possible */ | |
| @@ -1,3 +1,5 @@ | |
| + | /* NB: this file is to be removed soon. See isrv_identd.c */ |
| + | |
| /* vi: set sw=4 ts=4: */ | |
| /* | |
| * A fake identd server | |
| @@ -1292,9 +1292,9 @@ inetd_main(int argc, char *argv[]) | |
| /* reexec for vfork() do continue parent */ | |
| vfork_daemon_rexec(0, 0, argc, argv, "-f"); | |
| } | |
| - | bb_sanitize_server_stdio(0); |
| + | bb_sanitize_stdio(); |
| #else | |
| - | bb_sanitize_server_stdio(!(opt & 2)); |
| + | bb_sanitize_stdio_maybe_daemonize(!(opt & 2)); |
| #endif | |
| openlog(applet_name, LOG_PID | LOG_NOWAIT, LOG_DAEMON); | |
| logmode = LOGMODE_SYSLOG; | |
| @@ -111,7 +111,7 @@ int fakeidentd_main(int argc, char **argv) | |
| bogouser = argv[optind]; | |
| /* Daemonize if no -f and no -i and no -w */ | |
| - | bb_sanitize_server_stdio(!(opt & OPT_fiw)); |
| + | bb_sanitize_stdio_maybe_daemonize(!(opt & OPT_fiw)); |
| /* Where to log in inetd modes? "Classic" inetd | |
| * probably has its stderr /dev/null'ed (we need log to syslog?), | |
| * but daemontools-like utilities usually expect that children | |
| @@ -283,15 +283,19 @@ make_new_session( | |
| /* child */ | |
| + | /* make new process group */ |
| + | setsid(); |
| + | tcsetpgrp(0, getpid()); |
| + | /* ^^^ strace says: "ioctl(0, TIOCSPGRP, [pid]) = -1 ENOTTY" -- ??! */ |
| + | |
| /* open the child's side of the tty. */ | |
| - | fd = xopen(tty_name, O_RDWR /*| O_NOCTTY*/); |
| + | /* NB: setsid() disconnects from any previous ctty's. Therefore |
| + | * we must open child's side of the tty AFTER setsid! */ |
| + | fd = xopen(tty_name, O_RDWR); /* becomes our ctty */ |
| dup2(fd, 0); | |
| dup2(fd, 1); | |
| dup2(fd, 2); | |
| while (fd > 2) close(fd--); | |
| - | /* make new process group */ |
| - | setsid(); |
| - | tcsetpgrp(0, getpid()); |
| /* The pseudo-terminal allocated to the client is configured to operate in | |
| * cooked mode, and with XTABS CRMOD enabled (see tty(4)). */ | |
| @@ -221,7 +221,8 @@ int zcip_main(int argc, char *argv[]) | |
| } | |
| if (opts & 4) { // -r n.n.n.n | |
| if (inet_aton(r_opt, &ip) == 0 | |
| - | || (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR) { |
| + | || (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR |
| + | ) { |
| bb_error_msg_and_die("invalid link address"); | |
| } | |
| } | |
| @@ -270,7 +271,7 @@ int zcip_main(int argc, char *argv[]) | |
| // daemonize now; don't delay system startup | |
| if (!FOREGROUND) { | |
| setsid(); | |
| - | xdaemon(0, 0); |
| + | bb_daemonize(); |
| bb_info_msg("start, interface %s", intf); | |
| } | |
| @@ -2634,8 +2634,8 @@ static void setup_job_control(void) | |
| /* Put ourselves in our own process group. */ | |
| setsid(); | |
| - | shell_pgrp = getpid (); |
| - | setpgid (shell_pgrp, shell_pgrp); |
| + | shell_pgrp = getpid(); |
| + | setpgid(shell_pgrp, shell_pgrp); |
| /* Grab control of the terminal. */ | |
| tcsetpgrp(shell_terminal, shell_pgrp); | |
| @@ -2665,7 +2665,7 @@ int hush_main(int argc, char **argv) | |
| /* Initialize some more globals to non-zero values */ | |
| set_cwd(); | |
| - | if (ENABLE_FEATURE_COMMAND_EDITING) cmdedit_set_initial_prompt(); |
| + | if (ENABLE_FEATURE_COMMAND_EDITING) cmdedit_set_initial_prompt(); |
| else PS1 = NULL; | |
| PS2 = "> "; | |
| @@ -1486,7 +1486,7 @@ static void setup_job_control(void) | |
| /* Put ourselves in our own process group. */ | |
| setsid(); | |
| - | shell_pgrp = getpid (); |
| + | shell_pgrp = getpid(); |
| setpgid(shell_pgrp, shell_pgrp); | |
| /* Grab control of the terminal. */ | |
| @@ -737,7 +737,7 @@ static int daemonize(void) | |
| dup2(fd, 0); | |
| dup2(fd, 1); | |
| dup2(fd, 2); | |
| - | if (fd > 2) close(fd); |
| + | while (fd > 2) close(fd--); |
| setsid(); | |
| openlog(applet_name, LOG_PID, LOG_DAEMON); | |
| logmode = LOGMODE_SYSLOG; | |