--- pty.c.old	2008-10-19 13:41:52.219002279 -0700
+++ pty.c	2008-10-19 13:39:53.098994803 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001,2002 Red Hat, Inc.
+ * Copyright (C) 2001,2002, 2008 Red Hat, Inc.
  *
  * This is free software; you can redistribute it and/or modify it under
  * the terms of the GNU Library General Public License as published by
@@ -307,7 +307,8 @@
 _vte_pty_run_on_pty (struct vte_pty_child_setup_data *data,
 		     const char *command, char **argv, char **envp,
 		     const char *directory,
-		     GPid *pid, GError **error)
+		     GPid *pid, GError **error,
+		     gboolean closefds)
 {
 	gboolean ret = TRUE;
 	GError *local_error = NULL;
@@ -316,6 +317,14 @@
 		gchar **arg2, **envp2;
 		gint i, argc;
 
+		GSpawnFlags flags =
+		  G_SPAWN_CHILD_INHERITS_STDIN |
+		  G_SPAWN_SEARCH_PATH |
+		  G_SPAWN_DO_NOT_REAP_CHILD |
+		  (argv ? G_SPAWN_FILE_AND_ARGV_ZERO : 0);
+		if(!closefds)
+		  flags |= G_SPAWN_LEAVE_DESCRIPTORS_OPEN;
+
 		/* push the command into argv[0] */
 		argc = argv ? g_strv_length (argv) : 0;
 		arg2 = g_new (char *, argc + 2);
@@ -342,10 +351,7 @@
 
 		ret = g_spawn_async_with_pipes (directory,
 				arg2, envp2,
-				G_SPAWN_CHILD_INHERITS_STDIN |
-				G_SPAWN_SEARCH_PATH |
-				G_SPAWN_DO_NOT_REAP_CHILD |
-				(argv ? G_SPAWN_FILE_AND_ARGV_ZERO : 0),
+				flags,
 				vte_pty_child_setup, data,
 				pid,
 				NULL, NULL, NULL,
@@ -358,10 +364,7 @@
 				g_clear_error (&local_error);
 				ret = g_spawn_async_with_pipes (NULL,
 						arg2, envp2,
-						G_SPAWN_CHILD_INHERITS_STDIN |
-						G_SPAWN_SEARCH_PATH |
-						G_SPAWN_DO_NOT_REAP_CHILD |
-						(argv ? G_SPAWN_FILE_AND_ARGV_ZERO : 0),
+						flags,
 						vte_pty_child_setup, data,
 						pid,
 						NULL, NULL, NULL,
@@ -407,7 +410,8 @@
 _vte_pty_fork_on_pty_name (const char *path, int parent_fd, char **envp,
 			   const char *command, char **argv,
 			   const char *directory,
-			   int columns, int rows, GPid *child)
+			   int columns, int rows, GPid *child,
+			   gboolean closefds)
 {
 	struct vte_pty_child_setup_data data;
 
@@ -416,7 +420,7 @@
 
 	if (!_vte_pty_run_on_pty(&data,
 			command, argv, envp, directory,
-			child, NULL)) {
+				 child, NULL, closefds)) {
 		/* XXX propagate the error */
 		return FALSE;
 	}
@@ -431,7 +435,8 @@
 _vte_pty_fork_on_pty_fd (int fd, char **envp,
 			 const char *command, char **argv,
 			 const char *directory,
-			 int columns, int rows, GPid *child)
+			 int columns, int rows, GPid *child,
+			 gboolean closefds)
 {
 	struct vte_pty_child_setup_data data;
 
@@ -439,8 +444,8 @@
 	data.tty.fd = fd;
 
 	if (!_vte_pty_run_on_pty(&data,
-				command, argv, envp, directory,
-				child, NULL)) {
+				 command, argv, envp, directory,
+				 child, NULL, closefds)) {
 		/* XXX propagate the error */
 		return FALSE;
 	}
@@ -603,7 +608,8 @@
 static int
 _vte_pty_open_unix98(GPid *child, char **env_add,
 		     const char *command, char **argv,
-		     const char *directory, int columns, int rows)
+		     const char *directory, int columns, int rows,
+		     gboolean closefds)
 {
 	int fd;
 	char *buf;
@@ -626,7 +632,7 @@
 						      env_add, command,
 						      argv, directory,
 						      columns, rows,
-						      child)) {
+						      child, closefds)) {
 				close(fd);
 				fd = -1;
 			}
@@ -878,7 +884,8 @@
 _vte_pty_open_with_helper(GPid *child, char **env_add,
 			  const char *command, char **argv,
 			  const char *directory,
-			  int columns, int rows, int op)
+			  int columns, int rows, int op,
+			  gboolean closefds)
 {
 	GnomePtyOps ops;
 	int ret;
@@ -934,7 +941,8 @@
 		/* Start up a child process with the given command. */
 		if (!_vte_pty_fork_on_pty_fd(childfd, env_add, command,
 					    argv, directory,
-					    columns, rows, child)) {
+					    columns, rows, child,
+					    closefds)) {
 			close(parentfd);
 			close(childfd);
 			return -1;
@@ -971,7 +979,8 @@
 _vte_pty_open(pid_t *child_pid, char **env_add,
 	      const char *command, char **argv, const char *directory,
 	      int columns, int rows,
-	      gboolean lastlog, gboolean utmp, gboolean wtmp)
+	      gboolean lastlog, gboolean utmp, gboolean wtmp,
+	      gboolean closefds)
 {
 	GPid child;
 	int ret = -1;
@@ -1001,12 +1010,14 @@
 	if (ret == -1) {
 		ret = _vte_pty_open_with_helper(&child, env_add, command, argv,
 						directory,
-						columns, rows, opmap[op]);
+						columns, rows, opmap[op],
+						closefds);
 	}
 #endif
 	if (ret == -1) {
 		ret = _vte_pty_open_unix98(&child, env_add, command, argv,
-					   directory, columns, rows);
+					   directory, columns, rows,
+					   closefds);
 	}
 	if (ret != -1) {
 		*child_pid = (pid_t) child;
--- pty.h.old	2008-10-19 13:34:56.887002071 -0700
+++ pty.h	2008-10-19 13:35:05.046992197 -0700
@@ -30,7 +30,8 @@
 int _vte_pty_open(pid_t *child, char **env_add,
 		  const char *command, char **argv, const char *directory,
 		  int columns, int rows,
-		  gboolean lastlog, gboolean utmp, gboolean wtmp);
+		  gboolean lastlog, gboolean utmp, gboolean wtmp,
+		  gboolean closefds);
 
 /* Set or read the size of a terminal.  Returns 0 on success, -1 on failure,
  * with errno set to defined return codes from ioctl(). */
--- vte.c.old	2008-10-19 13:37:49.483003400 -0700
+++ vte.c	2008-10-19 13:40:37.494991299 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001-2004 Red Hat, Inc.
+ * Copyright (C) 2001-2004, 2008 Red Hat, Inc.
  *
  * This is free software; you can redistribute it and/or modify it under
  * the terms of the GNU Library General Public License as published by
@@ -2869,7 +2869,8 @@
 _vte_terminal_fork_basic(VteTerminal *terminal, const char *command,
 			 char **argv, char **envv,
 			 const char *directory,
-			 gboolean lastlog, gboolean utmp, gboolean wtmp)
+			 gboolean lastlog, gboolean utmp, gboolean wtmp,
+			 gboolean closefds)
 {
 	char **env_add;
 	int i, fd;
@@ -2900,7 +2901,7 @@
 	pid = -1;
 	fd = _vte_pty_open(&pid, env_add, command, argv, directory,
 			  terminal->column_count, terminal->row_count,
-			  lastlog, utmp, wtmp);
+			  lastlog, utmp, wtmp, closefds);
 	if (pid == -1 || fd == -1) {
 		g_strfreev(env_add);
 		return -1;
@@ -2999,7 +3000,8 @@
 
 	/* Start up the command and get the PTY of the master. */
 	return _vte_terminal_fork_basic(terminal, command, argv, envv,
-				        directory, lastlog, utmp, wtmp);
+				        directory, lastlog, utmp, wtmp,
+					FALSE);
 }
 
 /**
@@ -3016,7 +3018,8 @@
  * Starts a new child process under a newly-allocated controlling
  * pseudo-terminal.  TERM is automatically set to reflect the terminal widget's
  * emulation setting.  If @lastlog, @utmp, or @wtmp are %TRUE, logs the session
- * to the specified system log files.
+ * to the specified system log files.  All open file descriptors are closed
+ * in the child process.
  *
  * Returns: the ID of the new process in the parent, 0 in the child, and -1 if
  * there was an error
@@ -3031,7 +3034,44 @@
 	g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
 
 	return _vte_terminal_fork_basic(terminal, NULL, NULL, envv,
-				       directory, lastlog, utmp, wtmp);
+				       directory, lastlog, utmp, wtmp,
+				       FALSE);
+}
+
+/**
+ * vte_terminal_forkpty_with_open_fds:
+ * @terminal: a #VteTerminal
+ * @envv: a list of environment variables to be added to the environment before
+ * starting returning in the child process, or %NULL
+ * @directory: the name of a directory the child process should change to, or
+ * %NULL
+ * @lastlog: %TRUE if the session should be logged to the lastlog
+ * @utmp: %TRUE if the session should be logged to the utmp/utmpx log
+ * @wtmp: %TRUE if the session should be logged to the wtmp/wtmpx log
+ * @closefds: %TRUE if all open file descriptors should be closed in
+ *            the child process
+ *
+ * Starts a new child process under a newly-allocated controlling
+ * pseudo-terminal.  TERM is automatically set to reflect the terminal widget's
+ * emulation setting.  If @lastlog, @utmp, or @wtmp are %TRUE, logs the session
+ * to the specified system log files.
+ *
+ * Returns: the ID of the new process in the parent, 0 in the child, and -1 if
+ * there was an error
+ *
+ * Since: 0.11.11
+ */
+pid_t
+vte_terminal_forkpty_with_open_fds(VteTerminal *terminal,
+				   char **envv, const char *directory,
+				   gboolean lastlog, gboolean utmp, gboolean wtmp,
+				   gboolean closefds)
+{
+	g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
+
+	return _vte_terminal_fork_basic(terminal, NULL, NULL, envv,
+				       directory, lastlog, utmp, wtmp,
+				       closefds);
 }
 
 /* Handle an EOF from the client. */
--- vte.h.old	2008-10-19 13:42:01.803002271 -0700
+++ vte.h	2008-10-19 13:30:25.068290552 -0700
@@ -213,6 +213,15 @@
 			   gboolean utmp,
 			   gboolean wtmp);
 
+/* Like vte_terminal_forkpty, but lets you control whether
+ * currently open fds get cloesd. */
+pid_t vte_terminal_forkpty_with_open_fds(VteTerminal *terminal,
+					 char **envv, const char *directory,
+					 gboolean lastlog,
+					 gboolean utmp,
+					 gboolean wtmp,
+					 gboolean closefds);
+
 /* Send data to the terminal to display, or to the terminal's forked command
  * to handle in some way.  If it's 'cat', they should be the same. */
 void vte_terminal_feed(VteTerminal *terminal, const char *data, glong length);
