[gvfs] gvfschannel: Return proper error if we're out of free fds



commit 94f8380381c46b1512712be1192894dd9a9e12f0
Author: Tomas Bzatek <tbzatek redhat com>
Date:   Wed Apr 3 15:08:20 2013 +0200

    gvfschannel: Return proper error if we're out of free fds
    
    In case of too many open files within the process the
    g_vfs_channel_init() call fails on socketpair and subsequent
    g_vfs_channel_steal_remote_fd() call returns -1 for the fd.
    Then g_unix_fd_list_append() hits the assert and doesn't set an
    error we're dereferencing afterwards.
    
    This patch doesn't solve the lack of free fds situation and since glib
    heavily depends on it it would fail somewhere else. We're just fixing
    the segfault and returning nicer error.
    
    Based on a fix suggested by Stephen M. Webb
    
    https://bugzilla.gnome.org/show_bug.cgi?id=696713

 daemon/gvfschannel.c         |    2 +-
 daemon/gvfsjobopenforread.c  |   12 +++++++++++-
 daemon/gvfsjobopenforwrite.c |   10 ++++++++++
 3 files changed, 22 insertions(+), 2 deletions(-)
---
diff --git a/daemon/gvfschannel.c b/daemon/gvfschannel.c
index e70f13b..7a4ace6 100644
--- a/daemon/gvfschannel.c
+++ b/daemon/gvfschannel.c
@@ -200,7 +200,7 @@ g_vfs_channel_init (GVfsChannel *channel)
 
   ret = socketpair (AF_UNIX, SOCK_STREAM, 0, socket_fds);
   if (ret == -1) 
-    g_warning ("Error creating socket pair: %d\n", errno);
+    g_warning ("Error creating socket pair: %s\n", g_strerror (errno));
   else
     {
       channel->priv->command_stream = g_unix_input_stream_new (socket_fds[0], TRUE);
diff --git a/daemon/gvfsjobopenforread.c b/daemon/gvfsjobopenforread.c
index 32eaf59..d978136 100644
--- a/daemon/gvfsjobopenforread.c
+++ b/daemon/gvfsjobopenforread.c
@@ -174,7 +174,17 @@ create_reply (GVfsJob *job,
                                     open_job->pid);
 
   remote_fd = g_vfs_channel_steal_remote_fd (G_VFS_CHANNEL (channel));
-  
+  if (remote_fd < 0)
+    {
+      /* expecting we're out of fds when remote_fd == -1 */
+      g_dbus_method_invocation_return_error_literal (invocation,
+                                                     G_IO_ERROR,
+                                                     G_IO_ERROR_TOO_MANY_OPEN_FILES,
+                                                     _("Couldn't get stream file descriptor"));
+      g_object_unref (channel);
+      return;
+    }
+
   fd_list = g_unix_fd_list_new ();
   error = NULL;
   fd_id = g_unix_fd_list_append (fd_list, remote_fd, &error);
diff --git a/daemon/gvfsjobopenforwrite.c b/daemon/gvfsjobopenforwrite.c
index 9544d51..a63e9cd 100644
--- a/daemon/gvfsjobopenforwrite.c
+++ b/daemon/gvfsjobopenforwrite.c
@@ -258,6 +258,16 @@ create_reply (GVfsJob *job,
                                      open_job->pid);
 
   remote_fd = g_vfs_channel_steal_remote_fd (G_VFS_CHANNEL (channel));
+  if (remote_fd < 0)
+    {
+      /* expecting we're out of fds when remote_fd == -1 */
+      g_dbus_method_invocation_return_error_literal (invocation,
+                                                     G_IO_ERROR,
+                                                     G_IO_ERROR_TOO_MANY_OPEN_FILES,
+                                                     _("Couldn't get stream file descriptor"));
+      g_object_unref (channel);
+      return;
+    }
 
   fd_list = g_unix_fd_list_new ();
   error = NULL;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]