diff -urN vinagre-oneiric.orig/vinagre-3.2.0/vinagre/pty_open.c vinagre-oneiric/vinagre-3.2.0/vinagre/pty_open.c
--- vinagre-oneiric.orig/vinagre-3.2.0/vinagre/pty_open.c	2011-08-13 05:06:34.000000000 -0700
+++ vinagre-oneiric/vinagre-3.2.0/vinagre/pty_open.c	2011-10-15 15:11:52.490988002 -0700
@@ -404,9 +404,10 @@
 		      const char *directory,
 		      int columns, int rows, 
 		      int *stdin_fd, int *stdout_fd, int *stderr_fd, 
+		      int *held_fd,
 		      pid_t *child, gboolean reapchild, gboolean login)
 {
-	int fd, i;
+	int fd, hold_fd, i;
 	char c;
 	int ready_a[2] = { 0, 0 };
 	int ready_b[2] = { 0, 0 };
@@ -416,6 +417,16 @@
 	int stdout_pipe[2];
 	int stderr_pipe[2];
 
+	/* Optionally hold the slave PTY open in the parent. Needed to prevent
+	 * EIO from read() on the master if exec'ing a program that enumerates
+	 * and closes open fds before opening /dev/tty (ssh). */
+	if (held_fd) {
+		hold_fd = open(path, O_RDWR|O_NOCTTY);
+		if (hold_fd == -1) {
+			return -1;
+		}
+	}
+
 	/* Open pipes for synchronizing between parent and child. */
 	if (_pty_pipe_open_bi(&ready_a[0], &ready_a[1],
 			      &ready_b[0], &ready_b[1]) == -1) {
@@ -457,6 +468,7 @@
 		close(stdin_pipe[1]);
 		close(stdout_pipe[0]);
 		close(stderr_pipe[0]);
+		if (held_fd) close(hold_fd);
 
 		if(reapchild) {
 			close(pid_pipe[0]);
@@ -575,6 +587,7 @@
 		*stdin_fd = stdin_pipe[1];
 		*stdout_fd = stdout_pipe[0];
 		*stderr_fd = stderr_pipe[0];
+		if (held_fd) *held_fd = hold_fd;
 
 		return 0;
 		break;
@@ -603,6 +616,7 @@
 	close(ready_b[1]);
  bail_ready:
 	*child = -1;
+	if (held_fd) close(hold_fd);
 	return -1;
 }
 
@@ -716,7 +730,8 @@
 _pty_open_unix98(pid_t *child, guint flags, char **env_add,
 			   const char *command, char **argv,
 			   const char *directory, int columns, int rows,
-			   int *stdin_fd, int *stdout_fd, int *stderr_fd)
+			   int *stdin_fd, int *stdout_fd, int *stderr_fd,
+			   int *held_fd)
 {
 	int fd;
 	char *buf;
@@ -736,6 +751,7 @@
 						  argv, directory,
 						  columns, rows,
 						  stdin_fd, stdout_fd, stderr_fd, 
+						  held_fd,
 						  child, 
 						  flags & PTY_REAP_CHILD, 
 						  flags & PTY_LOGIN_TTY) != 0) {
@@ -773,13 +789,15 @@
 pty_open(pid_t *child, guint flags, char **env_add, 
 	 const char *command, char **argv, const char *directory,
 	 int columns, int rows,
-	 int *stdin_fd, int *stdout_fd, int *stderr_fd)
+	 int *stdin_fd, int *stdout_fd, int *stderr_fd,
+	 int *held_fd)
 {
 	int ret = -1;
 	if (ret == -1) {
 		ret = _pty_open_unix98(child, flags, env_add, command, 
 						 argv, directory, columns, rows,
-						 stdin_fd, stdout_fd, stderr_fd);
+						 stdin_fd, stdout_fd, stderr_fd,
+						 held_fd);
 	}
 	return ret;
 }
diff -urN vinagre-oneiric.orig/vinagre-3.2.0/vinagre/pty_open.h vinagre-oneiric/vinagre-3.2.0/vinagre/pty_open.h
--- vinagre-oneiric.orig/vinagre-3.2.0/vinagre/pty_open.h	2011-08-13 05:06:34.000000000 -0700
+++ vinagre-oneiric/vinagre-3.2.0/vinagre/pty_open.h	2011-10-15 15:09:42.774990837 -0700
@@ -59,7 +59,8 @@
 int pty_open(pid_t *child, guint flags, char **env_add,
 	     const char *command, char **argv, const char *directory,
 	     int columns, int rows,
-	     int *stdin_fd, int *stdout_fd, int *stderr_fd);
+	     int *stdin_fd, int *stdout_fd, int *stderr_fd,
+	     int *held_fd);
 
 G_END_DECLS
 
diff -urN vinagre-oneiric.orig/vinagre-3.2.0/vinagre/vinagre-ssh.c vinagre-oneiric/vinagre-3.2.0/vinagre/vinagre-ssh.c
--- vinagre-oneiric.orig/vinagre-3.2.0/vinagre/vinagre-ssh.c	2011-08-14 03:37:18.000000000 -0700
+++ vinagre-oneiric/vinagre-3.2.0/vinagre/vinagre-ssh.c	2011-10-15 15:14:20.198984773 -0700
@@ -172,13 +172,15 @@
            int *stdin_fd,
            int *stdout_fd,
            int *stderr_fd,
+           int *held_fd,
            GError **error)
 {
 #ifdef USE_PTY
   *tty_fd = pty_open(pid, PTY_REAP_CHILD, NULL,
 		     args[0], args, NULL,
 		     300, 300, 
-		     stdin_fd, stdout_fd, stderr_fd);
+		     stdin_fd, stdout_fd, stderr_fd,
+		     held_fd);
   if (*tty_fd == -1)
     {
       g_set_error_literal (error,
@@ -206,6 +208,7 @@
       return FALSE;
     }
   *pid = gpid;
+  if (held_fd) *held_fd = -1; /* Not applicable here. */
 #endif
   
   return TRUE;
@@ -727,7 +730,7 @@
 		     gint *tty,
 		     GError **error)
 {
-  int tty_fd, stdin_fd, stdout_fd, stderr_fd;
+  int tty_fd, stdin_fd, stdout_fd, stderr_fd, held_fd;
   GPid pid;
   gchar *user, *host, **args;
   gboolean res;
@@ -757,7 +760,7 @@
   args = setup_ssh_commandline (host, port, user, extra_arguments, command);
   if (!spawn_ssh (args,
 		  &pid,
-		  &tty_fd, &stdin_fd, &stdout_fd, &stderr_fd,
+		  &tty_fd, &stdin_fd, &stdout_fd, &stderr_fd, &held_fd,
 		  error))
     {
       g_strfreev (args);
@@ -771,6 +774,9 @@
   else
     res = handle_login (parent, host, port, user, tty_fd, stdout_fd, stderr_fd, error);
 
+  /* ssh has opened the PTY slave by now, so we can close it */
+  if (held_fd != -1) close(held_fd);
+
   g_strfreev (args);
   g_free (user);
   g_free (host);
