+#include "yarandom.h"
+#include "visual.h" /* for id_to_visual() */
+
+extern saver_info *global_si_kludge; /* I hate C so much... */
+
+static void
+nice_subproc (int nice_level)
+{
+ if (nice_level == 0)
+ return;
+
+#if defined(HAVE_NICE)
+ {
+ int old_nice = nice (0);
+ int n = nice_level - old_nice;
+ errno = 0;
+ if (nice (n) == -1 && errno != 0)
+ {
+ char buf [512];
+ sprintf (buf, "%s: nice(%d) failed", blurb(), n);
+ perror (buf);
+ }
+ }
+#elif defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)
+ if (setpriority (PRIO_PROCESS, getpid(), nice_level) != 0)
+ {
+ char buf [512];
+ sprintf (buf, "%s: setpriority(PRIO_PROCESS, %lu, %d) failed",
+ blurb(), (unsigned long) getpid(), nice_level);
+ perror (buf);
+ }
+#else
+ fprintf (stderr,
+ "%s: don't know how to change process priority on this system.\n",
+ blurb());
+
+#endif
+}
+
+
+/* RLIMIT_AS (called RLIMIT_VMEM on some systems) controls the maximum size
+ of a process's address space, i.e., the maximal brk(2) and mmap(2) values.
+ Setting this lets you put a cap on how much memory a process can allocate.
+ */
+#if defined(RLIMIT_VMEM) && !defined(RLIMIT_AS)
+# define RLIMIT_AS RLIMIT_VMEM
+#endif
+
+static void
+limit_subproc_memory (int address_space_limit, Bool verbose_p)
+{
+#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_AS)
+ struct rlimit r;
+
+ if (address_space_limit < 10 * 1024) /* let's not be crazy */
+ return;
+
+ if (getrlimit (RLIMIT_AS, &r) != 0)
+ {
+ char buf [512];
+ sprintf (buf, "%s: getrlimit(RLIMIT_AS) failed", blurb());
+ perror (buf);
+ return;
+ }
+
+ r.rlim_cur = address_space_limit;
+
+ if (setrlimit (RLIMIT_AS, &r) != 0)
+ {
+ char buf [512];
+ sprintf (buf, "%s: setrlimit(RLIMIT_AS, {%d, %d}) failed",
+ blurb(), r.rlim_cur, r.rlim_max);
+ perror (buf);
+ return;
+ }
+
+ if (verbose_p)
+ {
+ int i = address_space_limit;
+ char buf[100];
+ if (i >= (1<<30) && i == ((i >> 30) << 30))
+ sprintf(buf, "%dG", i >> 30);
+ else if (i >= (1<<20) && i == ((i >> 20) << 20))
+ sprintf(buf, "%dM", i >> 20);
+ else if (i >= (1<<10) && i == ((i >> 10) << 10))
+ sprintf(buf, "%dK", i >> 10);
+ else
+ sprintf(buf, "%d bytes", i);
+
+ fprintf (stderr, "%s: limited pid %lu address space to %s.\n",
+ blurb(), (unsigned long) getpid (), buf);
+ }
+
+#endif /* HAVE_SETRLIMIT && RLIMIT_AS */
+}
+
+
+
+#ifndef VMS
+
+static void
+exec_simple_command (const char *command)
+{
+ char *av[1024];
+ int ac = 0;
+ char *token = strtok (strdup(command), " \t");
+ while (token)
+ {
+ av[ac++] = token;
+ token = strtok(0, " \t");
+ }
+ av[ac] = 0;