diff options
Diffstat (limited to 'mach-defpager/main.c')
-rw-r--r-- | mach-defpager/main.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/mach-defpager/main.c b/mach-defpager/main.c index 203aad21..a623f7d3 100644 --- a/mach-defpager/main.c +++ b/mach-defpager/main.c @@ -1,5 +1,5 @@ /* Main program for standalone Hurd version of Mach default pager. - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -30,6 +30,7 @@ #include <unistd.h> #include <stdarg.h> #include <error.h> +#include <signal.h> /* XXX */ #include <fcntl.h> @@ -74,6 +75,10 @@ printf_init (device_t master) int debug; +static void +nohandler (int sig) +{ } + int main (int argc, char **argv) { @@ -98,8 +103,34 @@ main (int argc, char **argv) if (MACH_PORT_VALID (defpager)) error (2, 0, "Another default memory manager is already running"); - if (!(argc == 2 && !strcmp (argv[1], "-d")) && daemon (0, 0) < 0) - error (1, errno, "cannot become daemon"); + if (!(argc == 2 && !strcmp (argv[1], "-d"))) + { + /* We don't use the `daemon' function because we might exit back to the + parent before the daemon has completed vm_set_default_memory_manager. + Instead, the parent waits for a SIGUSR1 from the child before + exitting, and the child sends that signal after it is set up. */ + sigset_t set; + signal (SIGUSR1, nohandler); + sigemptyset (&set); + sigaddset (&set, SIGUSR1); + sigprocmask (SIG_BLOCK, &set, 0); + switch (fork ()) + { + case -1: + error (1, errno, "cannot become daemon"); + case 0: + setsid (); + chdir ("/"); + close (0); + close (1); + close (2); + break; + default: + sigemptyset (&set); + sigsuspend (&set); + _exit (0); + } + } printf_init(bootstrap_master_device_port); @@ -127,6 +158,9 @@ main (int argc, char **argv) default_pager_initialize (bootstrap_master_host_port); + if (!(argc == 2 && !strcmp (argv[1], "-d"))) + kill (getppid (), SIGUSR1); + /* * Become the default pager */ |