--- makeboot.c +++ makeboot.c 2011-04-19 13:45:33.532428242 +0000 @@ -320,6 +320,7 @@ static void filter_files(const char *dir t = lookup_target(dirlist[i]->d_name + 3); if (t) { t->status = 1; + t->filter_prefix = filter_prefix; if (asprintf(&t->arg0, "%s/%s", path, dirlist[i]->d_name) < 0) t->arg0 = (char*)0; } @@ -407,6 +408,7 @@ void check_run_files(const char *action, */ #ifndef USE_BLOGD # define bootlog(arg...) +# define closeblog() #endif /* @@ -437,7 +439,7 @@ struct makenode *pickup_task(void) close(fd); } #endif - bootlog(B_NOTICE, "service %s %s", best->name, (filter_prefix == 'K') ? "stop" : "start"); + bootlog(B_NOTICE, "service %s %s", best->name, (best->filter_prefix == 'K') ? "stop" : "start"); best->status = T_RUNNING; } return best; --- makeboot.h +++ makeboot.h 2011-04-19 13:45:22.304426128 +0000 @@ -35,6 +35,7 @@ struct makenode { struct makenode *next; int interactive; int importance; + int filter_prefix; }; /* dependency and selection list nodes */ --- proc.c +++ proc.c 2011-03-11 16:00:04.000000000 +0000 @@ -94,3 +94,74 @@ int read_proc(unsigned long int * const return 0; } +struct console { + char * tty; + int tlock; + struct termios ltio, otio; + struct console *restrict next; +}; +static struct console *restrict consoles; +static dev_t comparedev; +static char* scandev(DIR *dir) +{ + char *name = (char*)0; + struct dirent *dent; + int fd; + + fd = dirfd(dir); + rewinddir(dir); + while ((dent = readdir(dir))) { + char path[PATH_MAX]; + struct stat st; + if (fstatat(fd, dent->d_name, &st, 0) < 0) + continue; + if (!S_ISCHR(st.st_mode)) + continue; + if (comparedev != st.st_rdev) + continue; + if ((size_t)snprintf(path, sizeof(path), "/dev/%s", dent->d_name) >= sizeof(path)) + continue; + name = realpath(path, NULL); + break; + } + return name; +} + +void detect_consoles(void) +{ + FILE *fc; + if ((fc = fopen("/proc/consoles", "r"))) { + char fbuf[16]; + int maj, min; + DIR *dir; + dir = opendir("/dev"); + if (!dir) + goto out; + while ((fscanf(fc, "%*s %*s (%[^)]) %d:%d", &fbuf[0], &maj, &min) == 3)) { + struct console *restrict tail; + char * name; + + if (!strchr(fbuf, 'E')) + continue; + comparedev = makedev(maj, min); + name = scandev(dir); + + if (!name) + continue; + + if (posix_memalign((void*)&tail, sizeof(void*), alignof(typeof(struct console))) != 0) + perror("memory allocation"); + + tail->next = (struct console*)0; + tail->tty = name; + + if (!consoles) + consoles = tail; + else + consoles->next = tail; + } + closedir(dir); + out: + fclose(fc); + } +} --- proc.h +++ proc.h 2010-09-30 12:41:35.000000000 +0000 @@ -19,5 +19,3 @@ extern int read_proc(unsigned long int *prcs_run, unsigned long int *prcs_blked); extern void detect_consoles(void); -extern void unraw_consoles(void); -extern void raw_consoles(void); --- startpar.c +++ startpar.c 2011-04-20 11:13:07.375925983 +0000 @@ -52,6 +52,12 @@ #include #include #include +#ifdef USE_BLOGD +# include +#else +# define bootlog(arg...) +# define closeblog() +#endif #include "makeboot.h" #include "proc.h" @@ -197,6 +203,7 @@ void closeall(void) for (s = 0; s < par; s++) if (prgs[s].fd) close(prgs[s].fd); + closeblog(); } void callsplash(int n, const char *path, char *action) @@ -241,14 +248,7 @@ void callsplash(int n, const char *path, return; } - (void)sigemptyset(&nmask); - (void)sigaddset(&nmask, SIGINT); - (void)sigaddset(&nmask, SIGHUP); - (void)sigaddset(&nmask, SIGQUIT); - (void)sigaddset(&nmask, SIGSEGV); - (void)sigaddset(&nmask, SIGTERM); - (void)sigaddset(&nmask, SIGCHLD); - (void)sigaddset(&nmask, SIGTTIN); + (void)sigfillset(&nmask); sigprocmask(SIG_UNBLOCK, &nmask, NULL); (void)signal(SIGINT, SIG_DFL); @@ -258,6 +258,7 @@ void callsplash(int n, const char *path, (void)signal(SIGTERM, SIG_DFL); (void)signal(SIGCHLD, SIG_DFL); (void)signal(SIGTTIN, SIG_DFL); + (void)signal(SIGTTOU, SIG_DFL); TEMP_FAILURE_RETRY(dup2(2, 1)); closeall(); @@ -456,14 +457,7 @@ void run(struct prg *p) return; } - (void)sigemptyset(&nmask); - (void)sigaddset(&nmask, SIGINT); - (void)sigaddset(&nmask, SIGHUP); - (void)sigaddset(&nmask, SIGQUIT); - (void)sigaddset(&nmask, SIGSEGV); - (void)sigaddset(&nmask, SIGTERM); - (void)sigaddset(&nmask, SIGCHLD); - (void)sigaddset(&nmask, SIGTTIN); + (void)sigfillset(&nmask); sigprocmask(SIG_UNBLOCK, &nmask, NULL); (void)signal(SIGINT, SIG_DFL); @@ -473,12 +467,14 @@ void run(struct prg *p) (void)signal(SIGTERM, SIG_DFL); (void)signal(SIGCHLD, SIG_DFL); (void)signal(SIGTTIN, SIG_DFL); + (void)signal(SIGTTOU, SIG_DFL); if (setpgid(0, 0)) perror("setpgid"); if (m && p->fd) { + sigset_t smask, omask; TEMP_FAILURE_RETRY(close(1)); if (open(m, O_RDWR) != 1) { @@ -486,8 +482,12 @@ void run(struct prg *p) _exit(1); } TEMP_FAILURE_RETRY(dup2(1, 2)); - if (tcsetattr(1, TCSANOW, &tio)) + sigemptyset(&smask); + sigaddset(&smask, SIGTTOU); + sigprocmask(SIG_BLOCK, &smask, &omask); + if (tcsetattr(1, TCSANOW, &tio) && errno != ENOTTY) perror("tcsetattr"); + sigprocmask(SIG_SETMASK, &omask, NULL); if (wzok) ioctl(1, TIOCSWINSZ, &wz); putenv(sz.env_row); @@ -582,14 +582,7 @@ int run_single(const char *prg, const ch { sigset_t nmask; - (void)sigemptyset(&nmask); - (void)sigaddset(&nmask, SIGINT); - (void)sigaddset(&nmask, SIGHUP); - (void)sigaddset(&nmask, SIGQUIT); - (void)sigaddset(&nmask, SIGSEGV); - (void)sigaddset(&nmask, SIGTERM); - (void)sigaddset(&nmask, SIGCHLD); - (void)sigaddset(&nmask, SIGTTIN); + (void)sigfillset(&nmask); sigprocmask(SIG_UNBLOCK, &nmask, NULL); (void)signal(SIGINT, SIG_DFL); @@ -599,6 +592,7 @@ int run_single(const char *prg, const ch (void)signal(SIGTERM, SIG_DFL); (void)signal(SIGCHLD, SIG_DFL); (void)signal(SIGTTIN, SIG_DFL); + (void)signal(SIGTTOU, SIG_DFL); TEMP_FAILURE_RETRY(dup2(2, 1)); closeall(); @@ -632,19 +626,20 @@ void do_forward(void) { if (errno == EINTR) continue; +#if defined(DEBUG) && (DEBUG > 0) perror("\n\rstartpar: forward read"); +#endif break; } b = buf; while (r > 0) { rr = write(1, b, r); - if (rr == -1) + if (rr < 0) { if (errno == EINTR) continue; perror("\n\rstartpar: forward write"); - break; rr = r; } r -= rr; @@ -730,9 +725,23 @@ void detach(struct prg *p, const int sto { if ((pid = fork()) == 0) { + sigset_t nmask; + (void)sigfillset(&nmask); + sigprocmask(SIG_UNBLOCK, &nmask, NULL); + + (void)signal(SIGINT, SIG_DFL); + (void)signal(SIGHUP, SIG_DFL); + (void)signal(SIGQUIT, SIG_DFL); + (void)signal(SIGSEGV, SIG_DFL); + (void)signal(SIGTERM, SIG_DFL); + (void)signal(SIGCHLD, SIG_DFL); + (void)signal(SIGTTIN, SIG_DFL); + (void)signal(SIGTTOU, SIG_DFL); + TEMP_FAILURE_RETRY(dup2(p->fd, 0)); TEMP_FAILURE_RETRY(dup2(2, 1)); closeall(); + execlp(myname, myname, "-f", "--", p->name, NULL); do_forward(); } @@ -833,6 +842,8 @@ int main(int argc, char **argv) char *splashopt = 0; sigset_t nmask, omask, smask; + detect_consoles(); + (void)sigemptyset(&nmask); (void)sigaddset(&nmask, SIGHUP); sigprocmask(SIG_UNBLOCK, &nmask, NULL); @@ -1015,10 +1026,15 @@ int main(int argc, char **argv) if (tcgetattr(0, &tio)) { - perror("tcgetattr"); + if (errno != ENOTTY) + perror("tcgetattr"); tcgetattr(2, &tio); } cfmakeraw(&tio); + tio.c_lflag &= ~ECHO; + tio.c_lflag |= ISIG; + tio.c_cc[VTIME] = 0; + tio.c_cc[VMIN] = CMIN; if (ioctl(0, TIOCGWINSZ, &wz) == 0) wzok = 1;