X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fsubprocs.c;h=f7d8cc8f09aefdb6f72eb0ff579e62cecd2b2ba7;hb=bbd0773f2adde4927a6196361d4061e70bf48cd9;hp=910d5cc92912bacc819fcbad128faff93a237981;hpb=cccbddbc4140cf9a06d7d95cc5c0ca36eb5d6e28;p=xscreensaver diff --git a/driver/subprocs.c b/driver/subprocs.c index 910d5cc9..f7d8cc8f 100644 --- a/driver/subprocs.c +++ b/driver/subprocs.c @@ -1,5 +1,5 @@ /* subprocs.c --- choosing, spawning, and killing screenhacks. - * xscreensaver, Copyright (c) 1991-2001 Jamie Zawinski + * xscreensaver, Copyright (c) 1991-2003 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -88,6 +88,12 @@ extern saver_info *global_si_kludge; /* I hate C so much... */ 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; @@ -288,17 +294,28 @@ static void describe_dead_child (saver_info *, pid_t, int wait_status); 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 @@ -308,6 +325,7 @@ unblock_sigchld (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 */ @@ -365,12 +383,12 @@ kill_job (saver_info *si, pid_t pid, int signal) 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); } } @@ -661,6 +679,11 @@ spawn_screenhack_1 (saver_screen_info *ssi, Bool first_time_p) /* 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. */ @@ -765,8 +788,13 @@ spawn_screenhack_1 (saver_screen_info *ssi, Bool first_time_p) (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; @@ -906,10 +934,15 @@ hack_subproc_environment (saver_screen_info *ssi) 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="); @@ -921,14 +954,23 @@ hack_subproc_environment (saver_screen_info *ssi) 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 */ } @@ -1011,14 +1053,23 @@ get_best_gl_visual (saver_screen_info *ssi) /* 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