http://ftp.x.org/contrib/applications/xscreensaver-2.23.tar.gz
[xscreensaver] / driver / subprocs.c
index ce3661e2a3b2a662c24e61706bd14dba56e50950..b2b341a8fde7e2af2f00e1dd423367e1f4cba260 100644 (file)
@@ -1,5 +1,5 @@
 /* subprocs.c --- choosing, spawning, and killing screenhacks.
- * xscreensaver, Copyright (c) 1991, 1992, 1993, 1995, 1997
+ * xscreensaver, Copyright (c) 1991, 1992, 1993, 1995, 1997, 1998
  *  Jamie Zawinski <jwz@netscape.com>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -76,7 +76,7 @@ extern int kill (pid_t, int);         /* signal() is in sys/signal.h... */
 
 extern saver_info *global_si_kludge;   /* I hate C so much... */
 
-static void hack_environment (saver_screen_info *ssi);
+static void hack_subproc_environment (saver_screen_info *ssi);
 
 
 static void
@@ -301,8 +301,8 @@ struct screenhack_job {
 
 static struct screenhack_job *jobs = 0;
 
-#ifdef DEBUG
-static void
+/* for debugging -- nothing calls this, but it's useful to invoke from gdb. */
+void
 show_job_list (void)
 {
   struct screenhack_job *job;
@@ -317,7 +317,6 @@ show_job_list (void)
             job->name);
   fprintf (stderr, "\n");
 }
-#endif
 
 
 static void clean_job_list (void);
@@ -427,12 +426,12 @@ static int block_sigchld_handler = 0;
 static void
 block_sigchld (void)
 {
-#ifdef USE_SIGACTION
+#ifdef HAVE_SIGACTION
   sigset_t child_set;
   sigemptyset (&child_set);
   sigaddset (&child_set, SIGCHLD);
   sigprocmask (SIG_BLOCK, &child_set, 0);
-#endif /* USE_SIGACTION */
+#endif /* HAVE_SIGACTION */
 
   block_sigchld_handler++;
 }
@@ -440,12 +439,13 @@ block_sigchld (void)
 static void
 unblock_sigchld (void)
 {
-#ifdef USE_SIGACTION
+#ifdef HAVE_SIGACTION
   sigset_t child_set;
   sigemptyset(&child_set);
   sigaddset(&child_set, SIGCHLD);
   sigprocmask(SIG_UNBLOCK, &child_set, 0);
-#endif /* USE_SIGACTION */
+#endif /* HAVE_SIGACTION */
+
   block_sigchld_handler--;
 }
 
@@ -532,11 +532,9 @@ sigchld_handler (int sig)
 {
   saver_info *si = global_si_kludge;   /* I hate C so much... */
 
-#ifdef DEBUG
   if (si->prefs.debug_p)
     fprintf(stderr, "%s: got SIGCHLD%s\n", progname,
            (block_sigchld_handler ? " (blocked)" : ""));
-#endif
 
   if (block_sigchld_handler < 0)
     abort();
@@ -549,7 +547,7 @@ sigchld_handler (int sig)
 
   init_sigchld();
 }
-#endif
+#endif /* SIGCHLD */
 
 
 #ifndef VMS
@@ -563,14 +561,16 @@ await_dying_children (saver_info *si)
 
       errno = 0;
       kid = waitpid (-1, &wait_status, WNOHANG|WUNTRACED);
-#ifdef DEBUG
+
       if (si->prefs.debug_p)
-       if (kid < 0 && errno)
-         fprintf (stderr, "%s: waitpid(-1) ==> %ld (%d)\n", progname,
-                  (long) kid, errno);
-      else
-         fprintf (stderr, "%s: waitpid(-1) ==> %ld\n", progname, (long) kid);
-#endif
+       {
+         if (kid < 0 && errno)
+           fprintf (stderr, "%s: waitpid(-1) ==> %ld (%d)\n", progname,
+                    (long) kid, errno);
+         else
+           fprintf (stderr, "%s: waitpid(-1) ==> %ld\n", progname,
+                    (long) kid);
+       }
 
       /* 0 means no more children to reap.
         -1 means error -- except "interrupted system call" isn't a "real"
@@ -670,7 +670,7 @@ init_sigchld (void)
 {
 #ifdef SIGCHLD
 
-# ifdef USE_SIGACTION  /* Thanks to Tom Kelly <tom@ancilla.toronto.on.ca> */
+# ifdef HAVE_SIGACTION /* Thanks to Tom Kelly <tom@ancilla.toronto.on.ca> */
 
   static Bool sigchld_initialized_p = 0;
   if (!sigchld_initialized_p)
@@ -690,7 +690,7 @@ init_sigchld (void)
       sigchld_initialized_p = True;
     }
 
-# else  /* !USE_SIGACTION */
+# else  /* !HAVE_SIGACTION */
 
   if (((long) signal (SIGCHLD, sigchld_handler)) == -1L)
     {
@@ -698,8 +698,8 @@ init_sigchld (void)
       sprintf (buf, "%s: couldn't catch SIGCHLD", progname);
       perror (buf);
     }
-# endif /* !USE_SIGACTION */
-#endif
+# endif /* !HAVE_SIGACTION */
+#endif /* SIGCHLD */
 }
 
 
@@ -831,7 +831,7 @@ spawn_screenhack_1 (saver_screen_info *ssi, Bool first_time_p)
        case 0:
          close (ConnectionNumber (si->dpy));   /* close display fd */
          nice_subproc (p->nice_inferior);      /* change process priority */
-         hack_environment (ssi);               /* set $DISPLAY */
+         hack_subproc_environment (ssi);       /* set $DISPLAY */
          exec_screenhack (si, hack);           /* this does not return */
          abort();
          break;
@@ -849,6 +849,15 @@ void
 spawn_screenhack (saver_info *si, Bool first_time_p)
 {
   int i;
+
+  if (!monitor_powered_on_p (si))
+    {
+      if (si->prefs.verbose_p)
+       printf ("%s: server reports that monitor has powered down; "
+               "not launching a new hack.\n", progname);
+      return;
+    }
+
   for (i = 0; i < si->nscreens; i++)
     {
       saver_screen_info *ssi = &si->screens[i];
@@ -893,7 +902,7 @@ emergency_kill_subproc (saver_info *si)
   int i;
 #ifdef SIGCHLD
   signal (SIGCHLD, SIG_IGN);
-#endif
+#endif /* SIGCHLD */
 
   for (i = 0; i < si->nscreens; i++)
     {
@@ -959,8 +968,8 @@ demo_mode_restart_process (saver_info *si)
 {
   int i;
   for (i = 0; saved_argv [i]; i++);
-  /* add the -demo switch; save_argv() left room for this. */
-  saved_argv [i] = "-demo";
+  /* add the -initial-demo-mode switch; save_argv() left room for this. */
+  saved_argv [i] = "-initial-demo-mode";
   saved_argv [i+1] = 0;
   restart_process (si);                /* shouldn't return */
   saved_argv [i] = 0;
@@ -968,7 +977,7 @@ demo_mode_restart_process (saver_info *si)
 }
 
 static void
-hack_environment (saver_screen_info *ssi)
+hack_subproc_environment (saver_screen_info *ssi)
 {
   /* Store $DISPLAY into the environment, so that the $DISPLAY variable that
      the spawned processes inherit is correct.  First, it must be on the same
@@ -1009,6 +1018,28 @@ hack_environment (saver_screen_info *ssi)
 #endif /* HAVE_PUTENV */
 }
 
+
+void
+hack_environment (saver_info *si)
+{
+#if defined(HAVE_PUTENV) && defined(DEFAULT_PATH_PREFIX)
+  static const char *def_path = DEFAULT_PATH_PREFIX;
+  if (def_path && *def_path)
+    {
+      const char *opath = getenv("PATH");
+      char *npath = (char *) malloc(strlen(def_path) + strlen(opath) + 20);
+      strcpy (npath, "PATH=");
+      strcat (npath, def_path);
+      strcat (npath, ":");
+      strcat (npath, opath);
+
+      if (putenv (npath))
+       abort ();
+    }
+#endif /* HAVE_PUTENV && DEFAULT_PATH_PREFIX */
+}
+
+
 \f
 /* Change the uid/gid of the screensaver process, so that it is safe for it
    to run setuid root (which it needs to do on some systems to read the 
@@ -1053,6 +1084,7 @@ hack_uid (saver_info *si)
       si->locking_disabled_p = True;
       si->nolock_reason = "running as root";
       p = getpwnam ("nobody");
+      if (! p) p = getpwnam ("noaccess");
       if (! p) p = getpwnam ("daemon");
       if (! p) p = getpwnam ("bin");
       if (! p) p = getpwnam ("sys");
@@ -1088,13 +1120,14 @@ hack_uid (saver_info *si)
            }
        }
     }
-#ifndef NO_LOCKING
+# ifndef NO_LOCKING
  else  /* disable locking if already being run as "someone else" */
    {
      struct passwd *p = getpwuid (getuid ());
      if (!p ||
         !strcmp (p->pw_name, "root") ||
         !strcmp (p->pw_name, "nobody") ||
+        !strcmp (p->pw_name, "noaccess") ||
         !strcmp (p->pw_name, "daemon") ||
         !strcmp (p->pw_name, "bin") ||
         !strcmp (p->pw_name, "sys"))
@@ -1104,7 +1137,7 @@ hack_uid (saver_info *si)
         sprintf (si->nolock_reason, "running as %s", p->pw_name);
        }
    }
-#endif /* NO_LOCKING */
+# endif /* !NO_LOCKING */
 }
 
 void