FYI: init_subshell_child

Pavel Roskin proski at gnu.org
Thu May 17 00:40:57 UTC 2001


Hello!

Another patch, just applied.

ChangeLog:
        * subshell.c (init_subshell_child): New function to initialize
        child process and run subshell. Code moved from ...
        (init_subshell): ... here.

_______________________________
--- subshell.c
+++ subshell.c
@@ -181,18 +181,6 @@ static int prompt_pos;

 /* }}} */

-/* {{{ init_subshell */
-
-/*
- *  Fork the subshell, and set up many, many things.
- *
- *  Possibly modifies the global variables:
- *	shell_mode
- *	subshell_type, subshell_alive, subshell_stopped, subshell_pid
- *	use_subshell - Is set to FALSE if we can't run the subshell
- *	quit - Can be set to SUBSHELL_EXIT by the SIGCHLD handler
- */
-
 #ifdef HAVE_GRANTPT
 #    define SYNC_PTY_SIDES
 #else
@@ -208,6 +196,168 @@ static void sigusr1_handler (int sig)
 }
 #endif

+/*
+ *  Prepare child process to running the shell and run it.
+ *
+ *  Modifies the global variables (in the child process only):
+ *	shell_mode
+ *
+ *  Returns: never.
+ */
+static void init_subshell_child (const char *pty_name)
+{
+    int pty_slave;
+    char *init_file = NULL;
+
+    setsid ();  /* Get a fresh terminal session */
+
+    /* {{{ Open the slave side of the pty: again */
+    pty_slave = pty_open_slave (pty_name);
+
+    /* This must be done before closing the master side of the pty, */
+    /* or it will fail on certain idiotic systems, such as Solaris.	*/
+
+    /* Close master side of pty.  This is important; apart from	*/
+    /* freeing up the descriptor for use in the subshell, it also	*/
+    /* means that when MC exits, the subshell will get a SIGHUP and	*/
+    /* exit too, because there will be no more descriptors pointing	*/
+    /* at the master side of the pty and so it will disappear.	*/
+
+    close (subshell_pty);
+
+#ifdef SYNC_PTY_SIDES
+    /* Give our parent process (MC) the go-ahead */
+    kill (getppid (), SIGUSR1);
+#endif
+
+    /* }}} */
+    /* {{{ Make sure that it has become our controlling terminal */
+
+    /* Redundant on Linux and probably most systems, but just in case: */
+
+#ifdef TIOCSCTTY
+    ioctl (pty_slave, TIOCSCTTY, 0);
+#endif
+
+    /* }}} */
+    /* {{{ Configure its terminal modes and window size */
+
+    /* Set up the pty with the same termios flags as our own tty, plus  */
+    /* TOSTOP, which keeps background processes from writing to the pty */
+
+    shell_mode.c_lflag |= TOSTOP;  /* So background writers get SIGTTOU */
+    if (tcsetattr (pty_slave, TCSANOW, &shell_mode))
+    {
+        perror (__FILE__": couldn't set pty terminal modes");
+        _exit (FORK_FAILURE);
+    }
+
+    /* Set the pty's size (80x25 by default on Linux) according to the */
+    /* size of the real terminal as calculated by ncurses, if possible */
+#if defined TIOCSWINSZ && !defined SCO_FLAVOR
+    {
+	struct winsize tty_size;
+	tty_size.ws_row = LINES;
+	tty_size.ws_col = COLS;
+	tty_size.ws_xpixel = tty_size.ws_ypixel = 0;
+
+	if (ioctl (pty_slave, TIOCSWINSZ, &tty_size))
+	    perror (__FILE__": couldn't set pty size");
+    }
+#endif
+
+    /* }}} */
+    /* {{{ Set up the subshell's environment and init file name */
+
+    /* It simplifies things to change to our home directory here, */
+    /* and the user's startup file may do a `cd' command anyway   */
+    chdir (home_dir);  /* FIXME? What about when we re-run the subshell? */
+
+    switch (subshell_type)
+    {
+        case BASH:
+	    init_file = ".mc/bashrc";
+	    if (access (init_file, R_OK) == -1)
+		init_file = ".bashrc";
+
+	    /* Make MC's special commands not show up in bash's history */
+	    putenv ("HISTCONTROL=ignorespace");
+
+	    /* Allow alternative readline settings for MC */
+	    if (access (".mc/inputrc", R_OK) == 0)
+		putenv ("INPUTRC=.mc/inputrc");
+
+	    break;
+
+	case TCSH:
+	    init_file = ".mc/tcshrc";
+	    if (access (init_file, R_OK) == -1)
+		init_file += 3;
+	break;
+
+	case ZSH:
+	    break;
+
+	default:
+	    fprintf (stderr, __FILE__": unimplemented subshell type %d\n",
+		     subshell_type);
+	    _exit (FORK_FAILURE);
+    }
+
+    /* }}} */
+    /* {{{ Attach all our standard file descriptors to the pty */
+
+    /* This is done just before the fork, because stderr must still	 */
+    /* be connected to the real tty during the above error messages; */
+    /* otherwise the user will never see them.			 */
+
+    dup2 (pty_slave, STDIN_FILENO);
+    dup2 (pty_slave, STDOUT_FILENO);
+    dup2 (pty_slave, STDERR_FILENO);
+
+    /* }}} */
+    /* {{{ Execute the subshell at last */
+
+    close (subshell_pipe[READ]);
+    close (pty_slave);  /* These may be FD_CLOEXEC, but just in case... */
+
+    switch (subshell_type)
+    {
+        case BASH:
+	    execl (shell, "bash", "-rcfile", init_file, NULL);
+	    break;
+
+        case TCSH:
+	    execl (shell, "tcsh", NULL);  /* What's the -rcfile equivalent? */
+	    break;
+
+        case ZSH:
+	    /* change from "+Z" to "-Z" by Michael Bramer
+	     * (Debian-mc-maintainer) <grisu at debian.org> from a patch from
+	     * Radovan Garabik <garabik at center.fmph.uniba.sk>
+	     */
+	    execl (shell, "zsh", "-Z", NULL);
+
+	    break;
+    }
+
+    /* If we get this far, everything failed miserably */
+    _exit (FORK_FAILURE);
+
+    /* }}} */
+}
+
+/* {{{ init_subshell */
+
+/*
+ *  Fork the subshell, and set up many, many things.
+ *
+ *  Possibly modifies the global variables:
+ *	subshell_type, subshell_alive, subshell_stopped, subshell_pid
+ *	use_subshell - Is set to FALSE if we can't run the subshell
+ *	quit - Can be set to SUBSHELL_EXIT by the SIGCHLD handler
+ */
+
 void init_subshell (void)
 {
     /* {{{ Local variables */
@@ -339,144 +489,7 @@ void init_subshell (void)

     if (subshell_pid == 0)  /* We are in the child process */
     {
-	char *init_file = NULL;
-
-	setsid ();  /* Get a fresh terminal session */
-
-	/* {{{ Open the slave side of the pty: again */
-	pty_slave = pty_open_slave (pty_name);
-
-	/* This must be done before closing the master side of the pty, */
-	/* or it will fail on certain idiotic systems, such as Solaris.	*/
-
-	/* Close master side of pty.  This is important; apart from	*/
-	/* freeing up the descriptor for use in the subshell, it also	*/
-	/* means that when MC exits, the subshell will get a SIGHUP and	*/
-	/* exit too, because there will be no more descriptors pointing	*/
-	/* at the master side of the pty and so it will disappear.	*/
-
-	close (subshell_pty);
-
-#ifdef SYNC_PTY_SIDES
-	    /* Give our parent process (MC) the go-ahead */
-	    kill (getppid (), SIGUSR1);
-#endif
-
-	/* }}} */
-	/* {{{ Make sure that it has become our controlling terminal */
-
-	/* Redundant on Linux and probably most systems, but just in case: */
-
-#	ifdef TIOCSCTTY
-	ioctl (pty_slave, TIOCSCTTY, 0);
-#	endif
-
-	/* }}} */
-	/* {{{ Configure its terminal modes and window size */
-
-	/* Set up the pty with the same termios flags as our own tty, plus  */
-	/* TOSTOP, which keeps background processes from writing to the pty */
-
-	shell_mode.c_lflag |= TOSTOP;  /* So background writers get SIGTTOU */
-	if (tcsetattr (pty_slave, TCSANOW, &shell_mode))
-	{
-	    perror (__FILE__": couldn't set pty terminal modes");
-	    _exit (FORK_FAILURE);
-	}
-
-	/* Set the pty's size (80x25 by default on Linux) according to the */
-	/* size of the real terminal as calculated by ncurses, if possible */
-#	if defined TIOCSWINSZ && !defined SCO_FLAVOR
-	{
-	    struct winsize tty_size;
-	    tty_size.ws_row = LINES;
-	    tty_size.ws_col = COLS;
-	    tty_size.ws_xpixel = tty_size.ws_ypixel = 0;
-
-	    if (ioctl (pty_slave, TIOCSWINSZ, &tty_size))
-		perror (__FILE__": couldn't set pty size");
-	}
-#	endif
-
-	/* }}} */
-	/* {{{ Set up the subshell's environment and init file name */
-
-	/* It simplifies things to change to our home directory here, */
-	/* and the user's startup file may do a `cd' command anyway   */
-	chdir (home_dir);  /* FIXME? What about when we re-run the subshell? */
-
-	switch (subshell_type)
-	{
-	    case BASH:
-		init_file = ".mc/bashrc";
-		if (access (init_file, R_OK) == -1)
-		    init_file = ".bashrc";
-
-		/* Make MC's special commands not show up in bash's history */
-		putenv ("HISTCONTROL=ignorespace");
-
-		/* Allow alternative readline settings for MC */
-		if (access (".mc/inputrc", R_OK) == 0)
-		    putenv ("INPUTRC=.mc/inputrc");
-
-		break;
-
-	    case TCSH:
-		init_file = ".mc/tcshrc";
-		if (access (init_file, R_OK) == -1)
-		    init_file += 3;
-		break;
-
-	    case ZSH:
-		break;
-
-	    default:
-		fprintf (stderr, __FILE__": unimplemented subshell type %d\n",
-			 subshell_type);
-		_exit (FORK_FAILURE);
-	}
-
-	/* }}} */
-	/* {{{ Attach all our standard file descriptors to the pty */
-
-	/* This is done just before the fork, because stderr must still	 */
-	/* be connected to the real tty during the above error messages; */
-	/* otherwise the user will never see them.			 */
-
-	dup2 (pty_slave, STDIN_FILENO);
-	dup2 (pty_slave, STDOUT_FILENO);
-	dup2 (pty_slave, STDERR_FILENO);
-
-	/* }}} */
-	/* {{{ Execute the subshell at last */
-
-	close (subshell_pipe[READ]);
-	close (pty_slave);  /* These may be FD_CLOEXEC, but just in case... */
-
-	switch (subshell_type)
-	{
-	    case BASH:
-	    execl (shell, "bash", "-rcfile", init_file, NULL);
-	    break;
-
-	    case TCSH:
-	    execl (shell, "tcsh", NULL);  /* What's the -rcfile equivalent? */
-	    break;
-
-	    case ZSH:
-	    /* change from "+Z" to "-Z" by Michael Bramer
-	     * (Debian-mc-maintainer) <grisu at debian.org> from a patch from
-	     * Radovan Garabik <garabik at center.fmph.uniba.sk>
-	     */
-	    execl (shell, "zsh", "-Z", NULL);
-
-	    break;
-	}
-
-	/* If we get this far, everything failed miserably */
-	_exit (FORK_FAILURE);
-
-	/* }}} */
+	init_subshell_child (pty_name);
     }

     /* pty_slave is only opened when called the first time */
_______________________________

Regards,
Pavel Roskin





More information about the mc-devel mailing list