bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: looking for testers of new console


From: David Walter
Subject: Re: looking for testers of new console
Date: Mon, 23 Sep 2002 22:45:25 -0400
User-agent: Gnus/5.090007 (Oort Gnus v0.07) XEmacs/21.4 (Honest Recruiter, hurd-i386-debian)

David Walter <dwalter@syr.edu> 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 <dwalter@syr.edu>

   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
/ \




reply via email to

[Prev in Thread] Current Thread [Next in Thread]