ALT Linux Bugzilla
– Attachment 4559 Details for
Bug 17338
[FR] Перезагружать по <Enter> при обратном отсчете по окончании установки
New bug
|
Search
|
[?]
|
Help
Register
|
Log In
[x]
|
Forgot Password
Login:
[x]
|
EN
|
RU
'press any key to reboot' at the end of install
install2-init_press_key_reboot.c (text/plain), 12.15 KB, created by
Радюк Михаил
on 2010-09-25 03:26:47 MSD
(
hide
)
Description:
'press any key to reboot' at the end of install
Filename:
MIME Type:
Creator:
Радюк Михаил
Created:
2010-09-25 03:26:47 MSD
Size:
12.15 KB
patch
obsolete
>#define _GNU_SOURCE > > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > #include <unistd.h> > #include <signal.h> > #include <time.h> > #include <fcntl.h> > #include <mntent.h> > #include <termios.h> > > #include <sys/reboot.h> > #include <sys/mount.h> > #include <sys/stat.h> > #include <sys/types.h> > #include <sys/wait.h> > #include <sys/syscall.h> > #include <sys/sysmacros.h> > #include <sys/ioctl.h> > > #include <linux/reboot.h> > #include <linux/loop.h> > > #include <errno.h> > #include <error.h> > > /* Set a signal handler. */ > #define SETSIG(sa, sig, fun, flags) \ > do { \ > sa.sa_handler = fun; \ > sa.sa_flags = flags; \ > sigemptyset(&sa.sa_mask); \ > sigaction(sig, &sa, NULL); \ > } while(0) > > #define REBOOT_TIMEOUT 20 > #define ECHILD_TIMEOUT 5 > > const char *install_prog[] = { "/usr/sbin/install2", (char *) 0 }; > const char *shell_prog[] = { "/bin/sh", (char *) 0 }; > > static sig_atomic_t got_ECHILD; > > static void > chld_handler(int sig __attribute__ ((__unused__))) > { > int rc, status; > int saved_errno = errno; > > while ((rc = waitpid(-1, &status, WNOHANG))) > { > if (rc < 0 && errno == ECHILD) > { > got_ECHILD = 1; > break; > } > } > > errno = saved_errno; > } > > static pid_t > run(const char *cmd[]) > { > const char *exe = cmd[0]; > pid_t pid; > > #ifdef DEBUG > error(0, 0, "Executing %s", exe); > #endif > if ((pid = fork()) == -1) > { > error(0, errno, "fork"); > return -1; > } > if (pid == 0) > { > execv(exe, (char *const *) cmd); > error(0, errno, "%s: execv:", exe); > _exit(EXIT_FAILURE); > } > return pid; > } > > static int > run_wait(const char *prog[]) > { > int status = 0; > pid_t pid = run(prog); > > if (pid == -1) > return EXIT_FAILURE; > > if (waitpid(pid, &status, 0) == -1) > { > error(0, errno, "waitpid"); > return EXIT_FAILURE; > } > > if (!status) > return EXIT_SUCCESS; > > if (WIFEXITED(status)) > error(0, 0, "%s: terminated with exit code %d", > prog[0], WEXITSTATUS(status)); > else if (WIFSIGNALED(status)) > error(0, 0, "%s: terminated by signal %d", > prog[0], WEXITSTATUS(status)); > else > error(0, 0, "%s: terminated, status=%d", prog[0], status); > > return EXIT_FAILURE; > } > > static int > is_cdrom_method(void) > { > const char *method = getenv("METHOD"); > > return method && !strcmp(method, "cdrom"); > } > > static void > rsleep(unsigned int sec) > { > struct timespec req = { sec, 0 }, rem; > > for (; (req.tv_sec || req.tv_nsec) && !got_ECHILD; req = rem) > if (!nanosleep(&req, &rem)) > break; > } > > int > linux_kbhit(void) > { > struct termios oldstuff; > struct termios newstuff; > struct timeval tv = {0,1}; /* set one microsecond timeout */ > fd_set rdfds; > int fd = fileno(stdin); /* is usually zero */ > int retval; > > FD_ZERO(&rdfds); > FD_SET(fd, &rdfds); > > tcgetattr(fd, &oldstuff); > newstuff = oldstuff; /* save old attributes */ > > newstuff.c_lflag &= ~(ICANON | ECHO | IGNBRK); > > tcsetattr(fd, TCSANOW, &newstuff); /* set new attributes */ > > if (select(fd + 1, &rdfds, NULL, NULL, &tv) == -1) { > perror("select"); > exit(1); > } > if (FD_ISSET(fd, &rdfds)) { > retval = 1; > } > else { > retval = 0; > } > > tcsetattr(fd, TCSANOW, &oldstuff); /* restore old attributes */ > > return retval; > } > > static void > countdown(void) > { > int i; > > fprintf(stderr, "%s", "\nYou may safely reboot your system\n"); > fprintf(stderr, "%s", "Press any key to reboot\n"); > fflush(stderr); > > /* Set countdown when METHOD = cdrom */ > if (is_cdrom_method()) > { > for (i = REBOOT_TIMEOUT; i > 0; --i) > { > if (linux_kbhit()) > break; > > fprintf(stderr, > "\rAutomatic reboot after %d seconds... ", i); > fflush(stderr); > sleep(1); > } > } > fprintf(stderr, "\r\033[K%s\n", "Automatic reboot in progress."); > fflush(stderr); > } > > > > static void > killall(void) > { > int i; > > got_ECHILD = 0; > fprintf(stderr, "Asking all remaining processes to terminate\n"); > (void) kill(-1, SIGTERM); > rsleep(1); > > fprintf(stderr, "Killing all remaining processes"); > (void) kill(-1, SIGKILL); > chld_handler(0); > > for (i = 0; i < ECHILD_TIMEOUT && !got_ECHILD; ++i) > { > rsleep(1); > fputc('.', stderr); > } > fputc('\n', stderr); > } > > static void __attribute__ ((noreturn)) sysreboot(void) > { > countdown(); > > if ((reboot(LINUX_REBOOT_CMD_RESTART)) == -1) > error(EXIT_FAILURE, errno, "reboot"); > > for (;;) pause(); > } > > static void > mount_fs(void) > { > if (mount("proc", "/proc", "proc", 0UL, NULL) || > mount("sysfs", "/sys", "sysfs", 0UL, NULL) || > mount("tmpfs", "/tmp", "tmpfs", 0UL, NULL) || > mount("tmpfs", "/mnt", "tmpfs", 0UL, NULL) || > mkdir("/mnt/destination", 0700)) > error(EXIT_FAILURE, errno, "mount failed"); > } > > static int > umount_once(void) > { > int unmounted = 0; > FILE *f; > struct mntent *e; > > if (!(f = fopen("/proc/mounts", "r"))) > return 0; > > while ((e = getmntent(f))) > { > if (!strcmp(e->mnt_dir, "/")) > continue; > > if (!umount2(e->mnt_dir, 0)) > { > ++unmounted; > fprintf(stderr, "Unmounted: %s\n", e->mnt_dir); > break; > } > } > > fclose(f); > return unmounted; > } > > static void > list_mounted(void) > { > FILE *f; > struct mntent *e; > > if (!(f = fopen("/proc/mounts", "r"))) > return; > > while ((e = getmntent(f))) > if (strcmp(e->mnt_dir, "/")) > fprintf(stderr, "Remains mounted: %s\n", e->mnt_dir); > > fclose(f); > } > > static void > umount_fs(void) > { > while (umount_once()) > ; > } > > static void > loop_change_fd(const char *device_path, const char *storage_path) > { > int device_fd = -1; > int storage_fd = -1; > > do > { > if ((device_fd = open(device_path, O_RDONLY)) < 0) > { > error(0, errno, "open: %s", device_path); > break; > } > > if ((storage_fd = open(storage_path, O_RDONLY)) < 0) > { > error(0, errno, "open: %s", storage_path); > break; > } > > if (ioctl(device_fd, (unsigned long int) LOOP_CHANGE_FD, > storage_fd) < 0) > error(0, errno, "ioctl: LOOP_CHANGE_FD"); > } while (0); > > close(device_fd); > close(storage_fd); > } > > static int > copy_file(const char *src, const char *dst) > { > char rbuf[BUFSIZ]; > char *wbuf; > int ifd = -1, ofd = -1, rc = -1; > ssize_t rlen, wlen; > > if ((ifd = open(src, O_RDONLY)) < 0) > { > error(0, errno, "open: %s", src); > goto copy_file_exit; > } > if ((ofd = open(dst, O_CREAT | O_WRONLY, 0755)) < 0) > { > error(0, errno, "open: %s", dst); > goto copy_file_exit; > } > > while ((rlen = TEMP_FAILURE_RETRY(read(ifd, rbuf, sizeof rbuf))) > 0) > { > wlen = rlen; > wbuf = rbuf; > > while (wlen > 0) > { > ssize_t len; > > len = TEMP_FAILURE_RETRY(write(ofd, wbuf, (size_t) wlen)); > if (len < 0) > { > error(0, errno, "write: %s", dst); > goto copy_file_exit; > } > wlen -= len; > wbuf += len; > } > } > if (rlen < 0) > { > error(0, errno, "read: %s", src); > goto copy_file_exit; > } > > if (fchmod(ofd, 0500)) > { > error(0, errno, "fchmod: %s", dst); > goto copy_file_exit; > } > > rc = 0; > copy_file_exit: > close(ofd); > close(ifd); > return rc; > } > > static void > reexec_self(const char *path) > { > const char *args[] = { path, (const char *) 0 }; > > if (copy_file("/proc/self/exe", path)) > return; > if (execv(path, (char *const *) args)) > error(0, errno, "execv: %s", path); > } > > static void > do_install(const char *path) > { > int run_shell; > > #ifdef DEBUG > run_shell = 1; > #else > run_shell = 0; > #endif > mount_fs(); > > if (run_wait(install_prog)) > run_shell = 1; > > if (run_shell) > { > fprintf(stderr, > "This shell remains here for debug purposes. Press Ctrl-D to exit.\n"); > (void) run_wait(shell_prog); > } > > killall(); > reexec_self(path); > } > > static void > move_fs(const char *src, const char *dst) > { > if (mkdir(dst, 0700) || mount(src, dst, NULL, MS_MOVE, NULL)) > error(0, errno, "move_fs: %s -> %s", src, dst); > } > > #define pivot_root(new_root,put_old) syscall(SYS_pivot_root,new_root,put_old) > > static void > switch_root(void) > { > const char *old_root = "/mnt/oldroot"; > > move_fs("/proc", "/mnt/proc"); > move_fs("/sys", "/mnt/sys"); > move_fs("/dev", "/mnt/dev"); > if (mkdir(old_root, 0700) || > pivot_root("/mnt", old_root) || chdir("/")) > error(0, errno, "switch_root"); > } > > int > main(int ac, const char *av[]) > { > const char *tmp_init = "/mnt/init"; > struct sigaction sa; > > if (geteuid() != 0) > error(EXIT_FAILURE, EPERM, "init"); > > SETSIG(sa, SIGINT, SIG_IGN, SA_RESTART); > SETSIG(sa, SIGTSTP, SIG_IGN, SA_RESTART); > SETSIG(sa, SIGQUIT, SIG_IGN, SA_RESTART); > SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART); > > if (ac < 1 || strcmp(av[0], tmp_init)) > do_install(tmp_init); > > switch_root(); > umount_fs(); > loop_change_fd("/dev/loop0", "/altinst"); > umount_fs(); > list_mounted(); > sysreboot(); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 17338
:
4559
|
4761