-\f
-/* Subprocess.
- (This bit mostly cribbed from phosphor.c)
- */
-
-static void drain_input (sws_configuration *sc);
-
-static void
-subproc_cb (XtPointer closure, int *source, XtInputId *id)
-{
- sws_configuration *sc = (sws_configuration *) closure;
- drain_input (sc);
-}
-
-
-static void
-launch_text_generator (sws_configuration *sc)
-{
- char *oprogram = get_string_resource ("program", "Program");
- char *program;
-
- if (!strcasecmp(oprogram, "(default)"))
- {
- oprogram = FORTUNE_PROGRAM;
-
-#if defined(__linux__) && defined(HAVE_UNAME)
- {
- static int done_once = 0;
- if (!done_once)
- {
- struct utsname uts;
- struct stat st;
- done_once = 1;
- if (uname (&uts) == 0)
- {
- static char cmd[200];
- char *s;
- /* strip version at the first non-digit-dash-dot, to
- lose any "SMP" crap at the end. */
- for (s = uts.release; *s; s++)
- if (!isdigit(*s) && *s != '.' && *s != '-')
- *s = 0;
- sprintf (cmd, "cat /usr/src/linux-%s/README", uts.release);
- if (!stat (cmd+4, &st))
- oprogram = cmd;
- else
- {
- /* kernel source not installed? try X... */
- strcpy (cmd, "cat /usr/X11R6/lib/X11/doc/README");
- if (!stat (cmd+4, &st))
- oprogram = cmd;
- }
- }
- }
- }
-#endif /* __linux__ && HAVE_UNAME */
-
-#ifdef __APPLE__ /* MacOS X + XDarwin */
- {
- static int done_once = 0;
- if (!done_once)
- {
- struct stat st;
- static char *cmd = "cat /usr/X11R6/README";
- if (!stat (cmd+4, &st))
- oprogram = cmd;
- }
- }
-#endif /* __APPLE__ */
- }
-
- program = (char *) malloc (strlen (oprogram) + 10);
- strcpy (program, "( ");
- strcat (program, oprogram);
- strcat (program, " ) 2>&1");
-
- if ((sc->pipe = popen (program, "r")))
- {
- sc->pipe_id =
- XtAppAddInput (app, fileno (sc->pipe),
- (XtPointer) (XtInputReadMask | XtInputExceptMask),
- subproc_cb, (XtPointer) sc);
- }
- else
- {
- perror (program);
- }
-}
-
-
-static void
-relaunch_generator_timer (XtPointer closure, XtIntervalId *id)
-{
- sws_configuration *sc = (sws_configuration *) closure;
- launch_text_generator (sc);
-}
-
-
-/* When the subprocess has generated some output, this reads as much as it
- can into sc->buf at sc->buf_tail.
- */
-static void
-drain_input (sws_configuration *sc)
-{
- if (sc->buf_tail < sizeof(sc->buf) - 2)
- {
- int target = sizeof(sc->buf) - sc->buf_tail - 2;
- int n = read (fileno (sc->pipe),
- (void *) (sc->buf + sc->buf_tail),
- target);
- if (n > 0)
- {
- sc->buf_tail += n;
- sc->buf[sc->buf_tail] = 0;
- }
- else
- {
- XtRemoveInput (sc->pipe_id);
- sc->pipe_id = 0;
- pclose (sc->pipe);
- sc->pipe = 0;
-
- /* If the process didn't print a terminating newline, add one. */
- if (sc->buf_tail > 1 &&
- sc->buf[sc->buf_tail-1] != '\n')
- {
- sc->buf[sc->buf_tail++] = '\n';
- sc->buf[sc->buf_tail] = 0;
- }
-
- /* Then add one more, just for giggles. */
- sc->buf[sc->buf_tail++] = '\n';
- sc->buf[sc->buf_tail] = 0;
-
- /* Set up a timer to re-launch the subproc in a bit. */
- XtAppAddTimeOut (app, sc->subproc_relaunch_delay,
- relaunch_generator_timer,
- (XtPointer) sc);
- }
- }
-}
-