diff options
author | Karel Zak | 2006-12-07 00:25:48 +0100 |
---|---|---|
committer | Karel Zak | 2006-12-07 00:25:48 +0100 |
commit | 364cda4857f7dd5e2b4e2eb7583a2eaa279ef4ed (patch) | |
tree | c60dfad813ca42bf619fe2ac8ce893d2331e508f /login-utils/simpleinit.c | |
parent | Imported from util-linux-2.11b tarball. (diff) | |
download | kernel-qcow2-util-linux-364cda4857f7dd5e2b4e2eb7583a2eaa279ef4ed.tar.gz kernel-qcow2-util-linux-364cda4857f7dd5e2b4e2eb7583a2eaa279ef4ed.tar.xz kernel-qcow2-util-linux-364cda4857f7dd5e2b4e2eb7583a2eaa279ef4ed.zip |
Imported from util-linux-2.11f tarball.
Diffstat (limited to 'login-utils/simpleinit.c')
-rw-r--r-- | login-utils/simpleinit.c | 99 |
1 files changed, 60 insertions, 39 deletions
diff --git a/login-utils/simpleinit.c b/login-utils/simpleinit.c index 56f10455a..9c08a03a6 100644 --- a/login-utils/simpleinit.c +++ b/login-utils/simpleinit.c @@ -1,5 +1,5 @@ /* simpleinit.c - poe@daimi.aau.dk */ -/* Version 2.0.1 */ +/* Version 2.0.2 */ /* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL> * - added Native Language Support @@ -9,6 +9,10 @@ * - fixed race when reading from pipe and reaping children * 2001-02-18 sam@quux.dropbear.id.au * - fixed bug in <get_path>: multiple INIT_PATH components did not work + * 2001-02-21 Richard Gooch <rgooch@atnf.csiro.au> + * - block signals in handlers, so that longjmp() doesn't kill context + * 2001-02-25 Richard Gooch <rgooch@atnf.csiro.au> + * - make default INIT_PATH the boot_prog (if it is a directory) - YECCH */ #include <sys/types.h> @@ -76,6 +80,8 @@ static char script_prefix[PATH_SIZE] = "\0"; static char final_prog[PATH_SIZE] = "\0"; static char init_path[PATH_SIZE] = "\0"; static int caught_sigint = 0; +static int no_reboot = 0; +static pid_t rc_child = -1; static const char *initctl_name = "/dev/initctl"; static int initctl_fd = -1; static volatile int do_longjmp = 0; @@ -89,9 +95,9 @@ static int process_path (const char *path, int (*func) (const char *path), static int preload_file (const char *path); static int run_file (const char *path); static void spawn (int i), read_inittab (void); -static void hup_handler (int sig); +static void sighup_handler (int sig); static void sigtstp_handler (int sig); -static void int_handler (int sig); +static void sigint_handler (int sig); static void sigchild_handler (int sig); static void sigquit_handler (int sig); static void sigterm_handler (int sig); @@ -134,7 +140,7 @@ static void enter_single (void) int main(int argc, char *argv[]) { - int vec,i; + int vec, i; int want_single = 0; pid_t pid; struct sigaction sa; @@ -143,8 +149,10 @@ int main(int argc, char *argv[]) #ifdef SET_TZ set_tz(); #endif - signal (SIGINT, int_handler); - sigemptyset (&sa.sa_mask); + sigfillset (&sa.sa_mask); /* longjmp and nested signals don't mix */ + sa.sa_flags = SA_ONESHOT; + sa.sa_handler = sigint_handler; + sigaction (SIGINT, &sa, NULL); sa.sa_flags = 0; sa.sa_handler = sigtstp_handler; sigaction (SIGTSTP, &sa, NULL); @@ -166,6 +174,7 @@ int main(int argc, char *argv[]) read_inittab (); for (i = 1; i < argc; i++) { if (strcmp (argv[i], "single") == 0) want_single = 1; + else if (strcmp (argv[i], "-noreboot") == 0) no_reboot = 1; else { char path[PATH_SIZE]; @@ -175,6 +184,17 @@ int main(int argc, char *argv[]) strcpy (boot_prog, path); } } + if (init_path[0] == '\0') + { + struct stat statbuf; + + if ( (stat (boot_prog, &statbuf) == 0) && S_ISDIR (statbuf.st_mode) ) + { + strcpy (init_path, boot_prog); + i = strlen (init_path); + if (init_path[i - 1] == '/') init_path[i - 1] = '\0'; + } + } if ( ( initctl_fd = open (initctl_name, O_RDWR, 0) ) < 0 ) { mkfifo (initctl_name, S_IRUSR | S_IWUSR); @@ -185,12 +205,12 @@ int main(int argc, char *argv[]) if ( want_single || (access (_PATH_SINGLE, R_OK) == 0) ) do_single (); /*If we get a SIGTSTP before multi-user mode, do nothing*/ - while(stopped) + while (stopped) pause(); if ( do_rc_tty (boot_prog) ) do_single (); - while(stopped) /*Also if /etc/rc fails & we get SIGTSTP*/ + while (stopped) /* Also if /etc/rc fails & we get SIGTSTP */ pause(); write_wtmp(); /* write boottime record */ @@ -204,7 +224,7 @@ int main(int argc, char *argv[]) } exit(0); #endif - signal(SIGHUP, hup_handler); + signal (SIGHUP, sighup_handler); /* Better semantics with signal(2) */ for (i = 0; i < getdtablesize (); i++) if (i != initctl_fd) close (i); @@ -326,14 +346,14 @@ static void do_single (void) static int do_rc_tty (const char *path) { int status; - pid_t pid, child; + pid_t pid; sigset_t ss; if (caught_sigint) return 0; process_path (path, preload_file, 0); /* Launch off a subprocess to start a new session (required for frobbing the TTY) and capture control-C */ - switch ( child = fork () ) + switch ( rc_child = fork () ) { case 0: /* Child */ for (status = 1; status < NSIG; status++) signal (status, SIG_DFL); @@ -355,12 +375,12 @@ static int do_rc_tty (const char *path) process_path (path, run_file, 0); while (1) { - if ( ( pid = mywait (&status) ) == child ) + if ( ( pid = mywait (&status) ) == rc_child ) return (WTERMSIG (status) == SIGINT) ? 0 : 1; if (pid < 0) break; } - kill (child, SIGKILL); - while (waitpid (child, NULL, 0) != child) /* Nothing */; + kill (rc_child, SIGKILL); + while (waitpid (rc_child, NULL, 0) != rc_child) /* Nothing */; return 0; } /* End Function do_rc_tty */ @@ -601,17 +621,16 @@ static void read_inittab (void) if (access (path, R_OK | X_OK) == 0) strcpy (boot_prog, path); } -} +} /* End Function read_inittab */ -static void hup_handler (int sig) +static void sighup_handler (int sig) { int i,j; int oldnum; struct initline savetab[NUMCMD]; int had_already; - (void) signal(SIGHUP, SIG_IGN); - + signal (SIGHUP, SIG_IGN); memcpy(savetab, inittab, NUMCMD * sizeof(struct initline)); oldnum = numcmd; read_inittab (); @@ -625,16 +644,15 @@ static void hup_handler (int sig) spawn(i); } } - if(!had_already) spawn(i); + if (!had_already) spawn (i); } - - (void) signal(SIGHUP, hup_handler); -} + signal (SIGHUP, sighup_handler); +} /* End Function sighup_handler */ static void sigtstp_handler (int sig) { stopped = ~stopped; - if (!stopped) hup_handler (sig); + if (!stopped) sighup_handler (sig); } /* End Function sigtstp_handler */ static void sigterm_handler (int sig) @@ -645,22 +663,23 @@ static void sigterm_handler (int sig) if (inittab[i].pid > 0) kill (inittab[i].pid, SIGTERM); } /* End Function sigterm_handler */ -static void int_handler (int sig) +static void sigint_handler (int sig) { - pid_t pid; - - caught_sigint = 1; - sync(); - sync(); - pid = fork(); - if (pid > 0) - return; - if (pid == 0) /* reboot properly... */ - execl(_PATH_REBOOT, _PATH_REBOOT, (char *)0); + pid_t pid; - /* fork or exec failed, try the hard way... */ - my_reboot(LINUX_REBOOT_CMD_RESTART); -} + caught_sigint = 1; + kill (rc_child, SIGKILL); + if (no_reboot) _exit (1) /*kill (0, SIGKILL)*/; + sync (); + sync (); + pid = fork (); + if (pid > 0) return; /* Parent */ + if (pid == 0) /* Child: reboot properly... */ + execl (_PATH_REBOOT, _PATH_REBOOT, (char *) 0); + + /* fork or exec failed, try the hard way... */ + my_reboot (LINUX_REBOOT_CMD_RESTART); +} /* End Function sigint_handler */ static void sigchild_handler (int sig) { @@ -708,7 +727,7 @@ static void write_wtmp (void) flock(lf, LOCK_UN|LOCK_NB); close(lf); } -} +} /* End Function write_wtmp */ struct needer_struct @@ -885,7 +904,9 @@ static void process_command (const struct command_struct *command) dup2 (1, 2); execlp (get_path (victim->first_service->name), victim->first_service->name, "stop", NULL); - err ( _("error running programme\n") ); + sprintf (txt, _("error stopping service: \"%s\""), + victim->first_service->name); + err (txt); _exit (SIG_NOT_STOPPED); } else if (pid == -1) break; /* Error */ |