Add in a new restart init target, triggered by SIGHUP.  Patch from
Russ Dill, with adjustments by me.
 -Erik
diff --git a/examples/inittab b/examples/inittab
index 45f5a61..4eed848 100644
--- a/examples/inittab
+++ b/examples/inittab
@@ -24,7 +24,7 @@
 # <runlevels>: The runlevels field is completely ignored.
 #
 # <action>: Valid actions include: sysinit, respawn, askfirst, wait, once, 
-#                                  ctrlaltdel, and shutdown.
+#                                  restart, ctrlaltdel, and shutdown.
 #
 #       Note: askfirst acts just like respawn, but before running the specified
 #       process it displays the line "Please press Enter to activate this
@@ -43,6 +43,8 @@
 #         ::ctrlaltdel:/sbin/reboot
 #         ::shutdown:/sbin/swapoff -a
 #         ::shutdown:/bin/umount -a -r
+#         ::restart:/sbin/init
+#
 # if it detects that /dev/console is _not_ a serial console, it will
 # also run:
 #         tty2::askfirst:/bin/sh
@@ -79,6 +81,9 @@
 # Example how to put a getty on a modem line.
 #::respawn:/sbin/getty 57600 ttyS2
 
+# Stuff to do when restarting the init process
+::restart:/sbin/init
+
 # Stuff to do before rebooting
 ::ctrlaltdel:/sbin/reboot
 ::shutdown:/bin/umount -a -r
diff --git a/include/usage.h b/include/usage.h
index b84cdd5..a970c0f 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -765,6 +765,7 @@
 "	::ctrlaltdel:/sbin/reboot\n" \
 "	::shutdown:/sbin/swapoff -a\n" \
 "	::shutdown:/bin/umount -a -r\n" \
+"	::restart:/sbin/init\n" \
 "\n" \
 "if it detects that /dev/console is _not_ a serial console, it will also run:\n" \
 "\n" \
@@ -796,7 +797,7 @@
 "	<action>: \n" \
 "\n" \
 "		Valid actions include: sysinit, respawn, askfirst, wait, \n" \
-"		once, ctrlaltdel, and shutdown.\n" \
+"		once, restart, ctrlaltdel, and shutdown.\n" \
 "\n" \
 "		The available actions can be classified into two groups: actions\n" \
 "		that are run only once, and actions that are re-run when the specified\n" \
@@ -809,7 +810,10 @@
 "			completion of all sysinit actions, all 'wait' actions are run.\n" \
 "			'wait' actions, like  'sysinit' actions, cause init to wait until\n" \
 "			the specified task completes.  'once' actions are asynchronous,\n" \
-"			therefore, init does not wait for them to complete.  'ctrlaltdel'\n" \
+"			therefore, init does not wait for them to complete.  'restart' is\n" \
+"			the action taken to restart the init process.  By default this should\n" \
+"			simply run /sbin/init, but can be a script which runs pivot_root or it\n" \
+"			can do all sorts of other interesting things.  The 'ctrlaltdel' init\n" \
 "			actions are run when the system detects that someone on the system\n" \
 "                       console has pressed the CTRL-ALT-DEL key combination.  Typically one\n" \
 "                       wants to run 'reboot' at this point to cause the system to reboot.\n" \
@@ -865,6 +869,9 @@
 "	# Example how to put a getty on a modem line.\n" \
 "	#::respawn:/sbin/getty 57600 ttyS2\n" \
 "	\n" \
+"	# Stuff to do when restarting the init process\n" \
+"	::restart:/sbin/init\n" \
+"	\n" \
 "	# Stuff to do before rebooting\n" \
 "	::ctrlaltdel:/sbin/reboot\n" \
 "	::shutdown:/bin/umount -a -r\n" \
diff --git a/init/init.c b/init/init.c
index d0beb2a..f6108f1 100644
--- a/init/init.c
+++ b/init/init.c
@@ -142,7 +142,8 @@
 	WAIT,
 	ONCE,
 	CTRLALTDEL,
-	SHUTDOWN
+	SHUTDOWN,
+	RESTART
 } initActionEnum;
 
 /* A mapping between "inittab" action name strings and action type codes. */
@@ -159,6 +160,7 @@
 	{"once", ONCE},
 	{"ctrlaltdel", CTRLALTDEL},
 	{"shutdown", SHUTDOWN},
+	{"restart", RESTART},
 	{0, 0}
 };
 
@@ -688,6 +690,26 @@
 	}
 }
 
+static void exec_signal(int sig)
+{
+	initAction *a, *tmp;
+	for (a = initActionList; a; a = tmp) {
+		tmp = a->nextPtr;
+		if (a->action == RESTART) {
+			shutdown_system();
+			message(CONSOLE|LOG, "Trying to re-exec %s\n", a->process);
+			execl(a->process, a->process, NULL);
+	
+			message(CONSOLE|LOG, "execl of %s failed: %s\n", 
+				a->process, sys_errlist[errno]);
+			sync();
+			sleep(2);
+			init_reboot(RB_HALT_SYSTEM);
+			loop_forever();
+		}
+	}
+}
+
 static void halt_signal(int sig)
 {
 	shutdown_system();
@@ -839,6 +861,8 @@
 		/* Swapoff on halt/reboot */
 		new_initAction(SHUTDOWN, "/sbin/swapoff -a", console);
 #endif
+		/* Prepare to restart init when a HUP is received */
+		new_initAction(RESTART, "/sbin/init", console);
 		/* Askfirst shell on tty1 */
 		new_initAction(ASKFIRST, LOGIN_SHELL, console);
 		/* Askfirst shell on tty2 */
@@ -937,6 +961,12 @@
 	pid_t wpid;
 	int status;
 
+
+	if (argc > 1 && !strcmp(argv[1], "-q")) {
+		kill(1, SIGHUP);
+		exit(0);
+	}
+
 #ifndef DEBUG_INIT
 	/* Expect to be invoked as init with PID=1 or be invoked as linuxrc */
 	if (getpid() != 1
@@ -949,6 +979,7 @@
 	}
 	/* Set up sig handlers  -- be sure to
 	 * clear all of these in run() */
+	signal(SIGHUP, exec_signal);
 	signal(SIGUSR1, halt_signal);
 	signal(SIGUSR2, halt_signal);
 	signal(SIGINT, ctrlaltdel_signal);