[vinagre] Hold the slave PTY open, so that SSH does not fail
- From: David King <davidk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vinagre] Hold the slave PTY open, so that SSH does not fail
- Date: Tue, 18 Oct 2011 16:06:23 +0000 (UTC)
commit 9001d60fab1057057e995d323ef6fffcc9dfa082
Author: Tristan Schmelcher <tristan_schmelcher alumni uwaterloo ca>
Date: Tue Oct 18 17:59:39 2011 +0200
Hold the slave PTY open, so that SSH does not fail
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). Partially fixes bug
644432.
vinagre/pty_open.c | 27 +++++++++++++++++++++++----
vinagre/pty_open.h | 3 ++-
vinagre/vinagre-ssh.c | 12 +++++++++---
3 files changed, 34 insertions(+), 8 deletions(-)
---
diff --git a/vinagre/pty_open.c b/vinagre/pty_open.c
index a535809..a299146 100644
--- a/vinagre/pty_open.c
+++ b/vinagre/pty_open.c
@@ -404,9 +404,10 @@ _pty_fork_on_pty_name(const char *path, int parent_fd, char **env_add,
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,17 @@ _pty_fork_on_pty_name(const char *path, int parent_fd, char **env_add,
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). Partially fixes
+ * bug 644432. */
+ 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 +469,7 @@ _pty_fork_on_pty_name(const char *path, int parent_fd, char **env_add,
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 +588,7 @@ _pty_fork_on_pty_name(const char *path, int parent_fd, char **env_add,
*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 +617,7 @@ _pty_fork_on_pty_name(const char *path, int parent_fd, char **env_add,
close(ready_b[1]);
bail_ready:
*child = -1;
+ if (held_fd) close(hold_fd);
return -1;
}
@@ -716,7 +731,8 @@ static int
_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 +752,7 @@ _pty_open_unix98(pid_t *child, guint flags, char **env_add,
argv, directory,
columns, rows,
stdin_fd, stdout_fd, stderr_fd,
+ held_fd,
child,
flags & PTY_REAP_CHILD,
flags & PTY_LOGIN_TTY) != 0) {
@@ -773,13 +790,15 @@ 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)
{
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 --git a/vinagre/pty_open.h b/vinagre/pty_open.h
index 2e482e1..9a3e026 100644
--- a/vinagre/pty_open.h
+++ b/vinagre/pty_open.h
@@ -59,7 +59,8 @@ enum {
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 --git a/vinagre/vinagre-ssh.c b/vinagre/vinagre-ssh.c
index c5b3427..8bfa507 100644
--- a/vinagre/vinagre-ssh.c
+++ b/vinagre/vinagre-ssh.c
@@ -173,13 +173,15 @@ spawn_ssh (char *args[],
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,
@@ -207,6 +209,7 @@ spawn_ssh (char *args[],
return FALSE;
}
*pid = gpid;
+ if (held_fd) *held_fd = -1; /* Not applicable here. */
#endif
return TRUE;
@@ -728,7 +731,7 @@ vinagre_ssh_connect (GtkWindow *parent,
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;
@@ -758,7 +761,7 @@ vinagre_ssh_connect (GtkWindow *parent,
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);
@@ -772,6 +775,9 @@ vinagre_ssh_connect (GtkWindow *parent,
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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]