int make_console_stdio(void) { int fd, r; /* Make /dev/console the controlling terminal and stdin/stdout/stderr */ fd = acquire_terminal("/dev/console", false, true, true, USEC_INFINITY); if (fd < 0) return log_error_errno(fd, "Failed to acquire terminal: %m"); r = make_stdio(fd); if (r < 0) return log_error_errno(r, "Failed to duplicate terminal fd: %m"); return 0; }
static int pivot_to_new_root(void) { int fd; chdir("/run/initramfs"); /* In case some evil process made "/" MS_SHARED It works for pivot_root, but the ref count for the root device is not decreasing :-/ */ if (mount(NULL, "/", NULL, MS_PRIVATE, NULL) < 0) { log_error("Failed to make \"/\" private mount %m"); return -errno; } if (pivot_root(".", "oldroot") < 0) { log_error("pivot failed: %m"); /* only chroot if pivot root succeded */ return -errno; } chroot("."); log_info("Successfully changed into root pivot."); fd = open("/dev/console", O_RDWR); if (fd < 0) log_error("Failed to open /dev/console: %m"); else { make_stdio(fd); /* Initialize the controlling terminal */ setsid(); ioctl(STDIN_FILENO, TIOCSCTTY, NULL); } return 0; }
main() { #ifdef ALONE /* If no inetd */ int sockt, client, length; struct sockaddr_in from; extern int reaper(); disassoc(); /* fd 0-2 should be open and point to / now. */ #ifdef SYSLOG #ifdef BSD_42 openlog("nntpd", LOG_PID); /* fd 3 */ #else openlog("nntpd", LOG_PID, SYSLOG); /* fd 3 */ #endif #endif #ifdef FASTFORK num_groups = read_groups(); /* Read active file now (fd 4) */ /* and then do it every */ set_timer(); /* so often later */ #endif #ifndef EXCELAN sockt = get_socket(); /* should be fd 4 or 5 */ #endif #ifndef USG (void) signal(SIGCHLD, reaper); #endif #ifndef EXCELAN if (listen(sockt, SOMAXCONN) < 0) { #ifdef SYSLOG syslog(LOG_ERR, "main: listen: %m"); #endif exit(1); } #endif for (;;) { #ifdef EXCELAN int status; sockt = get_socket(); if (sockt < 0) continue; client = accept(sockt, &from); #else length = sizeof (from); client = accept(sockt, &from, &length); #endif EXCELAN if (client < 0) { #ifdef SYSLOG if (errno != EINTR) syslog(LOG_ERR, "accept: %m\n"); #endif #ifdef EXCELAN close(sockt); sleep(1); #endif continue; } switch (fork()) { case -1: #ifdef SYSLOG syslog(LOG_ERR, "fork: %m\n"); #endif #ifdef EXCELAN (void) close(sockt); #endif (void) close(client); break; case 0: #ifdef EXCELAN if (fork()) exit(0); bcopy(&from,¤t_peer,sizeof(from)); make_stdio(sockt); #else (void) close(sockt); make_stdio(client); #endif serve(); break; default: #ifdef EXCELAN (void) close(sockt); (void) wait(&status); #else (void) close(client); #endif break; } } #else /* We have inetd */ serve(); #endif }