summaryrefslogtreecommitdiff
path: root/daemon/gvfsbackendsftp.c
diff options
context:
space:
mode:
authorRoss Lagerwall <rosslagerwall@gmail.com>2014-06-04 21:42:00 +0100
committerRoss Lagerwall <rosslagerwall@gmail.com>2014-10-17 20:48:45 +0100
commit82305d74bdb750ae2dc6f070af85a22ee0e2a76d (patch)
tree7dcc73720676b9d9f83b94cbeed0614330d025da /daemon/gvfsbackendsftp.c
parent0077603d193ddd8c3c6f2d7f9053808b0ff1f944 (diff)
downloadgvfs-82305d74bdb750ae2dc6f070af85a22ee0e2a76d.tar.gz
sftp: Don't spin before the SSH process opens the slave pty
When OpenSSH starts, it closes all its open file descriptors, including the slave pty which is used for handling the login. This would cause gvfsd-sftp to spin because the poll() call in handle_login would return immediately with POLLHUP. Open the slave pty in the parent process so that poll() doesn't return POLLHUP and spin needlessly. Once the login has been completed, the slave fd can be closed in the parent process (this fixes an fd leak in the BSD openpty codepath). This change is based on what sshfs does, and is also similar to how the BSD openpty codepath behaves. Although the problem occurs briefly for any login, it is most noticeable when trying to connect to a server that drops SSH packets. E.g. gvfs-mount sftp://8.8.8.8 https://bugzilla.gnome.org/show_bug.cgi?id=724780
Diffstat (limited to 'daemon/gvfsbackendsftp.c')
-rw-r--r--daemon/gvfsbackendsftp.c15
1 files changed, 11 insertions, 4 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)
{