diff options
-rw-r--r-- | daemon/gvfsbackendsftp.c | 15 | ||||
-rw-r--r-- | daemon/pty_open.c | 40 | ||||
-rw-r--r-- | daemon/pty_open.h | 2 |
3 files changed, 37 insertions, 20 deletions
diff --git a/daemon/gvfsbackendsftp.c b/daemon/gvfsbackendsftp.c index 2bdba3ed..75725e1c 100644 --- a/daemon/gvfsbackendsftp.c +++ b/daemon/gvfsbackendsftp.c @@ -500,13 +500,14 @@ spawn_ssh (GVfsBackend *backend, int *stdin_fd, int *stdout_fd, int *stderr_fd, + int *slave_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, slave_fd); if (*tty_fd == -1) { g_set_error_literal (error, @@ -1593,7 +1594,7 @@ do_mount (GVfsBackend *backend, GVfsBackendSftp *op_backend = G_VFS_BACKEND_SFTP (backend); gchar **args; /* Enough for now, extend if you add more args */ pid_t pid; - int tty_fd, stdout_fd, stdin_fd, stderr_fd; + int tty_fd, stdout_fd, stdin_fd, stderr_fd, slave_fd; GError *error; GInputStream *is; GDataOutputStream *command; @@ -1609,7 +1610,7 @@ do_mount (GVfsBackend *backend, error = NULL; if (!spawn_ssh (backend, args, &pid, - &tty_fd, &stdin_fd, &stdout_fd, &stderr_fd, + &tty_fd, &stdin_fd, &stdout_fd, &stderr_fd, &slave_fd, &error)) { g_vfs_job_failed_from_error (G_VFS_JOB (job), error); @@ -1630,7 +1631,13 @@ do_mount (GVfsBackend *backend, if (tty_fd == -1) res = wait_for_reply (backend, stdout_fd, &error); else - res = handle_login (backend, mount_source, tty_fd, stdout_fd, stderr_fd, &error); + { + res = handle_login (backend, + mount_source, + tty_fd, stdout_fd, stderr_fd, + &error); + close (slave_fd); + } if (!res) { diff --git a/daemon/pty_open.c b/daemon/pty_open.c index ca9a4b7e..fecd0d10 100644 --- a/daemon/pty_open.c +++ b/daemon/pty_open.c @@ -414,7 +414,7 @@ _pty_fork_on_pty_name(const char *path, int parent_fd, 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 *slave_fd, pid_t *child, gboolean reapchild, gboolean login) { int fd, i; @@ -452,6 +452,14 @@ _pty_fork_on_pty_name(const char *path, int parent_fd, char **env_add, goto bail_stderr; } + /* Open the slave PTY in the parent (but not as a controlling terminal) + * otherwise later when we want to poll the master fd, POLLHUP is + * returned if the process hasn't opened the slave side yet. + */ + *slave_fd = open(path, O_RDWR | O_NOCTTY); + if (*slave_fd == -1) + goto bail_slavefd; + /* Start up a child. */ pid = fork(); switch (pid) { @@ -470,6 +478,10 @@ _pty_fork_on_pty_name(const char *path, int parent_fd, char **env_add, close(stdout_pipe[0]); close(stderr_pipe[0]); + /* Close the slave PTY opened in the parent. It is later + * opened as a controlling terminal. */ + close (*slave_fd); + if(reapchild) { close(pid_pipe[0]); @@ -595,6 +607,8 @@ _pty_fork_on_pty_name(const char *path, int parent_fd, char **env_add, return -1; bail_fork: + close(*slave_fd); + bail_slavefd: close(stderr_pipe[0]); close(stderr_pipe[1]); bail_stderr: @@ -730,7 +744,7 @@ 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 *slave_fd) { int fd; char *buf; @@ -749,7 +763,7 @@ _pty_open_unix98(pid_t *child, guint flags, char **env_add, if (_pty_fork_on_pty_name(buf, fd, env_add, command, argv, directory, columns, rows, - stdin_fd, stdout_fd, stderr_fd, + stdin_fd, stdout_fd, stderr_fd, slave_fd, child, flags & PTY_REAP_CHILD, flags & PTY_LOGIN_TTY) != 0) { @@ -766,9 +780,9 @@ _pty_open_unix98(pid_t *child, guint flags, char **env_add, static int _pty_open_bsd(pid_t *child, const char *command, char **argv, - int *stdin_fd, int *stdout_fd, int *stderr_fd) + int *stdin_fd, int *stdout_fd, int *stderr_fd, int *slave_fd) { - int master, slave; + int master; char **args, *arg; int stdin_pipe[2]; int stdout_pipe[2]; @@ -783,7 +797,7 @@ _pty_open_bsd(pid_t *child, const char *command, char **argv, if (pipe(stderr_pipe)) goto bail_stderr; - if (openpty(&master, &slave, NULL, NULL, NULL) == -1) + if (openpty(&master, slave_fd, NULL, NULL, NULL) == -1) return (-1); switch(pid = fork()) { @@ -799,7 +813,7 @@ _pty_open_bsd(pid_t *child, const char *command, char **argv, close(stderr_pipe[0]); setsid(); - if (ioctl(slave, TIOCSCTTY, (char *)NULL) == -1) + if (ioctl(*slave_fd, TIOCSCTTY, (char *)NULL) == -1) _exit(0); /* Set up stdin/out/err */ @@ -835,11 +849,6 @@ _pty_open_bsd(pid_t *child, const char *command, char **argv, /* * Parent */ - - /* XXX Don't close the slave pty, it's now the control - * terminal of the child and ssh needs it to authenticate. - close(slave); - */ close(stdin_pipe[0]); close(stdout_pipe[1]); close(stderr_pipe[1]); @@ -895,16 +904,17 @@ 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 *slave_fd) { int ret = -1; #if defined(HAVE_UNIX98_PTY) ret = _pty_open_unix98(child, flags, env_add, command, argv, directory, - columns, rows, stdin_fd, stdout_fd, stderr_fd); + columns, rows, stdin_fd, stdout_fd, stderr_fd, + slave_fd); #elif defined(HAVE_OPENPTY) ret = _pty_open_bsd(child, command, argv, - stdin_fd, stdout_fd, stderr_fd); + stdin_fd, stdout_fd, stderr_fd, slave_fd); #else #error Have neither UNIX98 PTY nor BSD openpty! #endif diff --git a/daemon/pty_open.h b/daemon/pty_open.h index 1ed47242..5c6241df 100644 --- a/daemon/pty_open.h +++ b/daemon/pty_open.h @@ -57,7 +57,7 @@ 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 *slave_fd); int pty_get_size(int master, int *columns, int *rows); G_END_DECLS |