+}
+
+
+/* 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, {%lu, %lu}) 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;
+
+ execvp (av[0], av); /* shouldn't return. */
+
+ {
+ char buf [512];
+ sprintf (buf, "%s: could not execute \"%s\"", blurb(), av[0]);
+ perror (buf);
+
+ if (errno == ENOENT &&
+ (token = getenv("PATH")))
+ {
+# ifndef PATH_MAX
+# ifdef MAXPATHLEN
+# define PATH_MAX MAXPATHLEN
+# else
+# define PATH_MAX 2048
+# endif
+# endif
+ char path[PATH_MAX];
+ fprintf (stderr, "\n");
+ *path = 0;
+# if defined(HAVE_GETCWD)
+ getcwd (path, sizeof(path));
+# elif defined(HAVE_GETWD)
+ getwd (path);
+# endif
+ if (*path)
+ fprintf (stderr, " Current directory is: %s\n", path);
+ fprintf (stderr, " PATH is:\n");
+ token = strtok (strdup(token), ":");
+ while (token)
+ {
+ fprintf (stderr, " %s\n", token);
+ token = strtok(0, ":");
+ }
+ fprintf (stderr, "\n");
+ }
+ }
+ fflush(stderr);
+ fflush(stdout);
+ exit (1); /* Note that this only exits a child fork. */
+}
+
+
+static void
+exec_complex_command (const char *shell, const char *command)