summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--init/init.c270
1 files changed, 255 insertions, 15 deletions
diff --git a/init/init.c b/init/init.c
index 9936ebd2..403dff65 100644
--- a/init/init.c
+++ b/init/init.c
@@ -35,6 +35,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <hurd/msg.h>
#include <hurd/term.h>
#include <paths.h>
+#include <sys/wait.h>
#include "startup_reply_U.h"
#include "startup_S.h"
@@ -97,7 +98,8 @@ mach_port_t default_dtable[3];
char **global_argv;
-
+pid_t shell_pid; /* PID of single-user shell. */
+
/* Read a string from stdin into BUF. */
static int
getstring (char *buf, size_t bufsize)
@@ -366,16 +368,22 @@ run_for_real (char *filename, char *args, int arglen, mach_port_t ctty)
default_ports[INIT_PORT_CTTYID] = MACH_PORT_NULL;
}
mach_port_deallocate (mach_task_self (), file);
- return err ? MACH_PORT_NULL : task;
+ if (err)
+ {
+ fprintf (stderr, "Cannot execute %s: %s.\n", filename, strerror (err));
+ return MACH_PORT_NULL;
+ }
+ return task;
}
static int
demuxer (mach_msg_header_t *inp,
mach_msg_header_t *outp)
{
- extern int notify_server (), startup_server ();
+ extern int notify_server (), startup_server (), msg_server ();
return (notify_server (inp, outp) ||
+ msg_server (inp, outp) ||
startup_server (inp, outp));
}
@@ -601,7 +609,7 @@ launch_single_user ()
{
char shell[1024];
char terminal[] = "/hurd/term\0console\0/tmp/console";
- mach_port_t term, foo;
+ mach_port_t term, shelltask;
char *termname;
task_t termtask;
int fd;
@@ -673,17 +681,13 @@ launch_single_user ()
Otherwise, open fd's 0, 1, and 2. */
if (term != MACH_PORT_NULL)
{
- fd = open (termname, O_READ);
+ fd = open (termname, O_RDWR);
assert (fd != -1);
dup2 (fd, 0);
close (fd);
-
- fd = open (termname, O_WRITE);
- assert (fd != -1);
- dup2 (fd, 1);
- dup2 (fd, 2);
- close (fd);
-
+ dup2 (0, 1);
+ dup2 (0, 2);
+
fclose (stdin);
stdin = fdopen (0, "r");
@@ -705,10 +709,13 @@ launch_single_user ()
strcpy (shell, _PATH_BSHELL);
/* The shell needs a real controlling terminal, so set that up here. */
- foo = run_for_real (shell, shell, strlen (shell) + 1, term);
+ shelltask = run_for_real (shell, shell, strlen (shell) + 1, term);
mach_port_deallocate (mach_task_self (), term);
- if (foo != MACH_PORT_NULL)
- mach_port_deallocate (mach_task_self (), foo);
+ if (shelltask != MACH_PORT_NULL)
+ {
+ shell_pid = task2pid (shelltask);
+ mach_port_deallocate (mach_task_self (), shelltask);
+ }
printf (" shell.\n");
fflush (stdout);
}
@@ -900,6 +907,8 @@ S_startup_reboot (mach_port_t server,
for (;;);
}
+/* Stubs for unused notification RPCs. */
+
kern_return_t
do_mach_notify_port_destroyed (mach_port_t notify,
mach_port_t rights)
@@ -932,3 +941,234 @@ do_mach_notify_msg_accepted (mach_port_t notify,
{
return EOPNOTSUPP;
}
+
+/* msg server */
+
+kern_return_t
+S_sig_post (mach_port_t msgport,
+ mach_port_t reply, mach_msg_type_name_t reply_type,
+ int signo, mach_port_t refport)
+{
+ if (refport != mach_task_self ())
+ return EPERM;
+
+ switch (signo)
+ {
+ case SIGCHLD:
+ {
+ /* A child died. Find its status. */
+ int status;
+ pid_t pid = waitpid (WAIT_ANY, &status, WNOHANG);
+ if (pid < 0)
+ perror ("init: waitpid");
+ else if (pid == 0)
+ fprintf (stderr, "init: Spurious SIGCHLD.\n");
+ else if (pid == shell_pid)
+ {
+ fprintf (stderr,
+ "init: Single-user shell PID %d died (%d), restarting.\n",
+ pid, status);
+ launch_single_user ();
+ }
+ else
+ fprintf (stderr, "init: Random child PID %d died (%d).\n",
+ pid, status);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ mach_port_deallocate (mach_task_self (), refport);
+ return 0;
+}
+
+
+/* For the rest of the msg functions, just call the C library's
+ internal server stubs usually run in the signal thread. */
+
+kern_return_t
+S_proc_newids (mach_port_t process,
+ mach_port_t task,
+ pid_t ppid,
+ pid_t pgrp,
+ int orphaned)
+{ return _S_proc_newids (process, task, ppid, pgrp, orphaned); }
+
+
+kern_return_t
+S_add_auth (mach_port_t process,
+ auth_t auth)
+{ return _S_add_auth (process, auth); }
+
+
+kern_return_t
+S_del_auth (mach_port_t process,
+ mach_port_t task,
+ intarray_t uids,
+ mach_msg_type_number_t uidsCnt,
+ intarray_t gids,
+ mach_msg_type_number_t gidsCnt)
+{ return _S_del_auth (process, task, uids, uidsCnt, gids, gidsCnt); }
+
+
+kern_return_t
+S_get_init_port (mach_port_t process,
+ mach_port_t refport,
+ int which,
+ mach_port_t *port,
+ mach_msg_type_name_t *portPoly)
+{ return _S_get_init_port (process, refport, which, port, portPoly); }
+
+
+kern_return_t
+S_set_init_port (mach_port_t process,
+ mach_port_t refport,
+ int which,
+ mach_port_t port)
+{ return _S_set_init_port (process, refport, which, port); }
+
+
+kern_return_t
+S_get_init_ports (mach_port_t process,
+ mach_port_t refport,
+ portarray_t *ports,
+ mach_msg_type_name_t *portsPoly,
+ mach_msg_type_number_t *portsCnt)
+{ return _S_get_init_ports (process, refport, ports, portsPoly, portsCnt); }
+
+
+kern_return_t
+S_set_init_ports (mach_port_t process,
+ mach_port_t refport,
+ portarray_t ports,
+ mach_msg_type_number_t portsCnt)
+{ return _S_set_init_ports (process, refport, ports, portsCnt); }
+
+
+kern_return_t
+S_get_init_int (mach_port_t process,
+ mach_port_t refport,
+ int which,
+ int *value)
+{ return _S_get_init_int (process, refport, which, value); }
+
+
+kern_return_t
+S_set_init_int (mach_port_t process,
+ mach_port_t refport,
+ int which,
+ int value)
+{ return _S_set_init_int (process, refport, which, value); }
+
+
+kern_return_t
+S_get_init_ints (mach_port_t process,
+ mach_port_t refport,
+ intarray_t *values,
+ mach_msg_type_number_t *valuesCnt)
+{ return _S_get_init_ints (process, refport, values, valuesCnt); }
+
+
+kern_return_t
+S_set_init_ints (mach_port_t process,
+ mach_port_t refport,
+ intarray_t values,
+ mach_msg_type_number_t valuesCnt)
+{ return _S_set_init_ints (process, refport, values, valuesCnt); }
+
+
+kern_return_t
+S_get_dtable (mach_port_t process,
+ mach_port_t refport,
+ portarray_t *dtable,
+ mach_msg_type_name_t *dtablePoly,
+ mach_msg_type_number_t *dtableCnt)
+{ return _S_get_dtable (process, refport, dtable, dtablePoly, dtableCnt); }
+
+
+kern_return_t
+S_set_dtable (mach_port_t process,
+ mach_port_t refport,
+ portarray_t dtable,
+ mach_msg_type_number_t dtableCnt)
+{ return _S_set_dtable (process, refport, dtable, dtableCnt); }
+
+
+kern_return_t
+S_get_fd (mach_port_t process,
+ mach_port_t refport,
+ int fd,
+ mach_port_t *port,
+ mach_msg_type_name_t *portPoly)
+{ return _S_get_fd (process, refport, fd, port, portPoly); }
+
+
+kern_return_t
+S_set_fd (mach_port_t process,
+ mach_port_t refport,
+ int fd,
+ mach_port_t port)
+{ return _S_set_fd (process, refport, fd, port); }
+
+
+kern_return_t
+S_get_environment (mach_port_t process,
+ data_t *value,
+ mach_msg_type_number_t *valueCnt)
+{ return _S_get_environment (process, value, valueCnt); }
+
+
+kern_return_t
+S_set_environment (mach_port_t process,
+ mach_port_t refport,
+ data_t value,
+ mach_msg_type_number_t valueCnt)
+{ return _S_set_environment (process, refport, value, valueCnt); }
+
+
+kern_return_t
+S_get_env_variable (mach_port_t process,
+ string_t variable,
+ data_t *value,
+ mach_msg_type_number_t *valueCnt)
+{ return _S_get_env_variable (process, variable, value, valueCnt); }
+
+
+kern_return_t
+S_set_env_variable (mach_port_t process,
+ mach_port_t refport,
+ string_t variable,
+ string_t value,
+ boolean_t replace)
+{ return _S_set_env_variable (process, refport, variable, value, replace); }
+
+
+kern_return_t
+S_io_select_done (mach_port_t notify_port,
+ mach_msg_type_name_t notify_portPoly,
+ int select_result,
+ int id_tag)
+{ return _S_io_select_done (notify_port, notify_portPoly, select_result, id_tag); }
+
+
+kern_return_t
+S_startup_dosync (mach_port_t process)
+{ return _S_startup_dosync (process); }
+
+
+kern_return_t
+S_dir_changed (mach_port_t notify_port,
+ dir_changed_type_t change,
+ string_t name)
+{ return _S_dir_changed (notify_port, change, name); }
+
+
+kern_return_t
+S_file_changed (mach_port_t notify_port,
+ file_changed_type_t change,
+ off_t start,
+ off_t end)
+{ return _S_file_changed (notify_port, change, start, end); }
+