/* subprocs.c --- choosing, spawning, and killing screenhacks.
- * xscreensaver, Copyright (c) 1991-2001 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1991-2003 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
static void
limit_subproc_memory (int address_space_limit, Bool verbose_p)
{
+
+/* This has caused way more problems than it has solved...
+ Let's just completely ignore the "memoryLimit" option now.
+ */
+#undef HAVE_SETRLIMIT
+
#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_AS)
struct rlimit r;
static int block_sigchld_handler = 0;
-void
+#ifdef HAVE_SIGACTION
+ sigset_t
+#else /* !HAVE_SIGACTION */
+ int
+#endif /* !HAVE_SIGACTION */
block_sigchld (void)
{
#ifdef HAVE_SIGACTION
sigset_t child_set;
sigemptyset (&child_set);
sigaddset (&child_set, SIGCHLD);
+ sigaddset (&child_set, SIGPIPE);
sigprocmask (SIG_BLOCK, &child_set, 0);
#endif /* HAVE_SIGACTION */
block_sigchld_handler++;
+
+#ifdef HAVE_SIGACTION
+ return child_set;
+#else /* !HAVE_SIGACTION */
+ return 0;
+#endif /* !HAVE_SIGACTION */
}
void
sigset_t child_set;
sigemptyset(&child_set);
sigaddset(&child_set, SIGCHLD);
+ sigaddset(&child_set, SIGPIPE);
sigprocmask(SIG_UNBLOCK, &child_set, 0);
#endif /* HAVE_SIGACTION */
if (errno == ESRCH)
fprintf (stderr,
"%s: %d: child process %lu (%s) was already dead.\n",
- blurb(), job->screen, job->pid, job->name);
+ blurb(), job->screen, (unsigned long) job->pid, job->name);
else
{
char buf [1024];
sprintf (buf, "%s: %d: couldn't kill child process %lu (%s)",
- blurb(), job->screen, job->pid, job->name);
+ blurb(), job->screen, (unsigned long) job->pid, job->name);
perror (buf);
}
}
/* No hacks at all */
new_hack = -1;
}
+ else if (p->screenhacks_count == 1)
+ {
+ /* Exactly one hack in the list */
+ new_hack = 0;
+ }
else if (si->selection_mode == -1)
{
/* Select the next hack, wrapping. */
(unsigned long) getpid ());
exec_command (p->shell, hack->command, p->nice_inferior);
- /* If that returned, we were unable to exec the subprocess. */
- print_path_error (hack->command);
+
+ /* If that returned, we were unable to exec the subprocess.
+ Print an error message, if desired.
+ */
+ if (! p->ignore_uninstalled_p)
+ print_path_error (hack->command);
+
exit (1); /* exits child fork */
break;
be the screen on which this particular hack is running -- not the display
specification which the driver itself is using, since the driver ignores
its screen number and manages all existing screens.
+
+ Likewise, store a window ID in $XSCREENSAVER_WINDOW -- this will allow
+ us to (eventually) run multiple hacks in Xinerama mode, where each hack
+ has the same $DISPLAY but a different piece of glass.
*/
saver_info *si = ssi->global;
const char *odpy = DisplayString (si->dpy);
- char *ndpy = (char *) malloc(strlen(odpy) + 20);
+ char *ndpy = (char *) malloc (strlen(odpy) + 20);
+ char *nssw = (char *) malloc (40);
char *s;
strcpy (ndpy, "DISPLAY=");
while (isdigit(*s)) s++; /* skip over dpy number */
while (*s == '.') s++; /* skip over dot */
if (s[-1] != '.') *s++ = '.'; /* put on a dot */
- sprintf(s, "%d", ssi->number); /* put on screen number */
+ sprintf(s, "%d", ssi->real_screen_number); /* put on screen number */
+
+ sprintf (nssw, "XSCREENSAVER_WINDOW=0x%lX",
+ (unsigned long) ssi->screensaver_window);
/* Allegedly, BSD 4.3 didn't have putenv(), but nobody runs such systems
any more, right? It's not Posix, but everyone seems to have it. */
#ifdef HAVE_PUTENV
if (putenv (ndpy))
abort ();
- /* do not free(ndpy) -- see above. */
+ if (putenv (nssw))
+ abort ();
+
+ /* don't free ndpy/nssw -- some implementations of putenv (BSD 4.4,
+ glibc 2.0) copy the argument, but some (libc4,5, glibc 2.1.2)
+ do not. So we must leak it (and/or the previous setting). Yay.
+ */
#endif /* HAVE_PUTENV */
}
/* Wait for the child to die. */
waitpid (-1, &wait_status, 0);
- if (1 == sscanf (buf, "0x%x %c", &v, &c))
+ if (1 == sscanf (buf, "0x%lx %c", &v, &c))
result = (int) v;
if (result == 0)
{
if (si->prefs.verbose_p)
- fprintf (stderr, "%s: %s did not report a GL visual!\n",
- blurb(), av[0]);
+ {
+ int L = strlen(buf);
+ fprintf (stderr, "%s: %s did not report a GL visual!\n",
+ blurb(), av[0]);
+
+ if (L && buf[L-1] == '\n')
+ buf[--L] = 0;
+ if (*buf)
+ fprintf (stderr, "%s: %s said: \"%s\"\n",
+ blurb(), av[0], buf);
+ }
return 0;
}
else