[BusyBox] init: dup2 [PATCH]

Shaun Jackman sjackman at gmail.com
Tue Jul 5 01:21:06 UTC 2005


This patch uses dup2 instead of close/dup, which could reduce code
size by a few bytes. It also removes the include of sys/mount.h since
it appears to be unused, and changes all O_NDELAY to O_NONBLOCK, the
latter being the standard name for the former. Finally, it attempts a
call to run_applet_by_name before finally calling execv.

Cheers,
Shaun

2005-07-04  Shaun Jackman  <sjackman at gmail.com>

	* init/init.c: Do not include sys/mount.h.
	(message): Use O_NONBLOCK instead of O_NDELAY.
	(console_init): Ditto.
	(run): Use dup2 instead of close/dup. Try run_applet_by_name
	before execv.
	(exec_signal): Use dup2 instead of close/dup. 

--- init/init.c
+++ init/init.c
@@ -39,7 +39,6 @@
 #include <limits.h>
  #include <sys/fcntl.h>
  #include <sys/ioctl.h>
-#include <sys/mount.h>
  #include <sys/types.h>
  #include <sys/wait.h>
  #include <sys/reboot.h>
@@ -239,7 +238,7 @@
  	/* Take full control of the log tty, and never close it.
  	 * It's mine, all mine!  Muhahahaha! */
 	if (log_fd < 0) {
-		if ((log_fd = device_open(log, O_RDWR | O_NDELAY | O_NOCTTY)) < 0) {
+		if ((log_fd = device_open(log, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
 			log_fd = -2;
 			bb_error_msg("Bummer, can't write to log on %s!", log);
 			device = CONSOLE;
@@ -254,7 +253,7 @@
 
 	if (device & CONSOLE) {
  		int fd = device_open(_PATH_CONSOLE,
-					O_WRONLY | O_NOCTTY | O_NDELAY);
+					O_WRONLY | O_NOCTTY | O_NONBLOCK);
 		/* Always send console messages to /dev/console so people will see them. */
  		if (fd >= 0) {
  			bb_full_write(fd, msg, l);
@@ -424,7 +423,7 @@
  static pid_t run(const struct init_action *a)
 {
  	struct stat sb;
-	int i, junk;
+	int i, junk, argc;
  	pid_t pid, pgrp, tmp_pid;
  	char *s, *tmpCmd, *cmd[INIT_BUFFS_SIZE], *cmdpath;
  	char buf[INIT_BUFFS_SIZE + 6];	/* INIT_BUFFS_SIZE+strlen("exec ")+1 */
@@ -441,10 +440,9 @@
  	sigprocmask(SIG_BLOCK, &nmask, &omask);
 
  	if ((pid = fork()) == 0) {
+		int fd;
+
 		/* Clean up */
-		close(0);
-		close(1);
-		close(2);
  		sigprocmask(SIG_SETMASK, &omask, NULL);
 
 		/* Reset signal handlers that were set by the parent process */
@@ -462,7 +460,7 @@
  		setsid();
 
 		/* Open the new terminal device */
-		if ((device_open(a->terminal, O_RDWR)) < 0) {
+		if (((fd = device_open(a->terminal, O_RDWR))) < 0) {
  			if (stat(a->terminal, &sb) != 0) {
 				message(LOG | CONSOLE, "device '%s' does not exist.",
 						a->terminal);
@@ -473,11 +471,13 @@
 		}
 
 		/* Make sure the terminal will act fairly normal for us */
-		set_term(0);
+		set_term(fd);
  		/* Setup stdout, stderr for the new process so
 		 * they point to the supplied terminal */
-		dup(0);
-		dup(0);
+		dup2(fd, STDIN_FILENO);
+		dup2(fd, STDOUT_FILENO);
+		dup2(fd, STDERR_FILENO);
+		close(fd);
 
  		/* If the init Action requires us to wait, then force the
  		 * supplied terminal to be the controlling tty. */
@@ -536,6 +536,7 @@
  			cmd[1] = "-c";
  			cmd[2] = strcat(strcpy(buf, "exec "), a->command);
  			cmd[3] = NULL;
+			argc = 3;
 		} else {
  			/* Convert command (char*) into cmd (char**, one word per string) */
  			strcpy(buf, a->command);
@@ -547,6 +548,7 @@
 				}
 			}
  			cmd[i] = NULL;
+			argc = i;
 		}
 
  		cmdpath = cmd[0];
@@ -610,6 +612,9 @@
 		}
  #endif
 
+		/* Try an applet first. */
+		run_applet_by_name(cmdpath, argc, cmd);
+
  		/* Now run it.  The new program will take over this PID,
  		 * so nothing further in init.c should be run. */
  		execv(cmdpath, cmd);
@@ -730,7 +735,7 @@
  	for (a = init_action_list; a; a = tmp) {
  		tmp = a->next;
 		if (a->action & RESTART) {
-			struct stat sb;
+			int fd;
 
 			shutdown_system();
 
@@ -747,13 +752,9 @@
  			sigaddset(&unblock_signals, SIGTSTP);
  			sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL);
 
-			/* Close whatever files are open. */
-			close(0);
-			close(1);
-			close(2);
-
 			/* Open the new terminal device */
-			if ((device_open(a->terminal, O_RDWR)) < 0) {
+			if (((fd = device_open(a->terminal, O_RDWR))) < 0) {
+				struct stat sb;
  				if (stat(a->terminal, &sb) != 0) {
 					message(LOG | CONSOLE, "device '%s' does not exist.", a->terminal);
 				} else {
@@ -763,10 +764,12 @@
 			}
 
 			/* Make sure the terminal will act fairly normal for us */
-			set_term(0);
+			set_term(fd);
  			/* Setup stdout, stderr on the supplied terminal */
-			dup(0);
-			dup(0);
+			dup2(fd, STDIN_FILENO);
+			dup2(fd, STDOUT_FILENO);
+			dup2(fd, STDERR_FILENO);
+			close(fd);
 
  			messageD(CONSOLE | LOG, "Trying to re-exec %s", a->command);
  			execl(a->command, a->command, NULL);



More information about the busybox mailing list