David Walter <[EMAIL PROTECTED]> writes: > I have added a run-daemon program that takes its arguments as a > program to run and wait on, if the program dies it restarts it and > waits again.
I follow up with the run-daemon program I am using to restart the console vga client at boot, or on console client death. (c+a+bksp) Please notice that this doesn't work with a console -d ncursesw because the run daemon is redirecting stdio, and (until I understand how to support attaching a terminal to one of the console clients vt's w/o a getty on it) there is a getty running on this. The issues with how to capture the console are still open, if someone has suggestions I'd be happy to read them. This copies the /dev/klog to tty10, if you have this active in /etc/ttys you will see the boot log on tty10. (a+f10) This is now working without a getty in /etc/ttys for /dev/tty10 For now run-system is assumed to be in /libexec. --- runsystem.orig Mon Sep 23 22:16:05 2002 +++ runsystem Mon Sep 23 22:18:00 2002 @@ -129,6 +129,20 @@ # This program reads /etc/ttys and starts the programs it says to. ${RUNTTYS} & runttys_pid=$! + CONSOLE_LOG=/dev/tty10 + ( + # clear the extra console & copy the boot info to $CONSOLE_LOG + ( sleep 10; tput clear >$CONSOLE_LOG; cat /dev/klog > $CONSOLE_LOG & + CAT=$!; sleep 5; kill $CAT; )& + sleep 10; # wait for run ttys to become available + /libexec/run-daemon --console-log=$CONSOLE_LOG -- \ + /bin/console -D /lib/hurd/console \ + -d vga \ + -d pc_kbd \ + -d generic_speaker /dev/vcs + # > $CONSOLE_LOG 2>&1 + # exec 1>$CONSOLE_LOG 2>&1 || exit 3 + )& # Wait for runttys to die, meanwhile handling trapped signals. wait /* run-daemon: run command with args, restart it on death Copyright (C) 2002 Free Software Foundation Written by David Walter <[EMAIL PROTECTED]> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define _GNU_SOURCE 1 #include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <error.h> #include <errno.h> #include <sys/wait.h> #include <argp.h> // extern const char* const doc; static const char doc[] = "run-daemon: execute and monitor a program, " "when it dies restart it.\n\n" "Example use:\n\n" "/libexec/run-daemon \\\n" " --console-log=/dev/vt10 -- \\\n" " /bin/console -D /lib/hurd/console \\\n" " -d vga -d pc_kbd -d generic_speaker \\\n" " /dev/vcs\n\n"; static const char *argp_program_version = "0.1"; static const struct argp_option startup_options[] = { {"console-log", 'c', "CONSOLE_LOG_DEVICE", 0, "where to write console log information (default /dev/vt10)"}, {0, '-', 0, 0, "end of args (command line follows)"}, {0, 0} }; char* console_log; int next = 0; static error_t parse_startup_opt (int key, char *arg, struct argp_state *state) { switch (key) { case '-': /* eoa (end of args) */ if (!next) next = state->next; return ARGP_ERR_UNKNOWN; break; case 'c': console_log = arg; next = state->next; break; default: return ARGP_ERR_UNKNOWN; } return 0; } const struct argp startup_argp = { startup_options, parse_startup_opt, 0, (const char * const )doc }; #define ERROR (-1) int main(int argc, char**argv) { int next_arg; char**command_line; argp_parse (&startup_argp, argc, argv, 0, &next_arg, 0); argc = argc - (int) (argv - &argv[next_arg]); command_line = &argv[next_arg]; static pid_t run (char **argv) { pid_t pid; pid = fork (); if (pid < 0) { error (0, errno, "fork"); return 0; } if (pid > 0) return pid; else { errno = 0; char**s = argv; while (*s) { printf("%s ", *s); s++; } printf("\n"); execv (argv[0], argv); error (127, errno, "%s", argv[0]); } /* NOTREACHED */ return -1; } void* daemon_process(void * ignore) { static first = 1; if (first) { run(command_line); first = 0; } do { error_t waiterr; pid_t pid = waitpid (WAIT_ANY, NULL, WUNTRACED); waiterr = errno; /* Elicit a SIGLOST now if the console (on our stderr, i.e. fd 2) has died. That way, the next error message emitted will actually make it out to the console if it can be made it work at all. */ write (2, "", 0); /* If a SIGTERM or SIGHUP arrived recently, it set a flag and broke us out of being blocked in waitpid. */ if (pid < 0) { if (waiterr == EINTR) /* A signal woke us. */ continue; /* we must be done running our child, return to the world. */ fprintf (stderr, "%s program has terminated\n", *command_line); sleep (5); run(command_line); } } while (1); } int pid = 0; if ((pid = fork())) { int fd; if (!console_log) console_log = "/dev/vt10"; if ((fd = open (console_log, O_RDWR, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)))) { #define success(x) (x?"success":"fail") fprintf (stdout, "Duplicated stdout:%s\n", success(dup2 (fd, STDOUT_FILENO) != -1)); fprintf (stderr, "Duplicated stderr:%s\n", success(dup2 (fd, STDERR_FILENO) != -1)); fprintf (stdin, "Duplicated stdout:%s\n", success(dup2 (fd, STDIN_FILENO) != -1)); } setsid (); daemon_process (0); } if (pid ==ERROR) perror ("fork"); else error (0, 0, "Daemon process running"); return (errno); } -- /^\ \ / ASCII RIBBON CAMPAIGN X AGAINST HTML MAIL / \ _______________________________________________ Bug-hurd mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-hurd