glib r7444 - trunk/gio



Author: cneumair
Date: Mon Sep  8 12:44:07 2008
New Revision: 7444
URL: http://svn.gnome.org/viewvc/glib?rev=7444&view=rev

Log:
(gio)
2008-09-08  Christian Neumair  <cneumair gnome org>

	* gunixmount.c (eject_unmount_read_error), (eject_unmount_do):
	* gunixvolume.c (eject_mount_read_error), (eject_mount_do):
	Use non-blocking pipe for mount helper I/O. Fixes #550647.


Modified:
   trunk/gio/ChangeLog
   trunk/gio/gunixmount.c
   trunk/gio/gunixvolume.c

Modified: trunk/gio/gunixmount.c
==============================================================================
--- trunk/gio/gunixmount.c	(original)
+++ trunk/gio/gunixmount.c	Mon Sep  8 12:44:07 2008
@@ -42,6 +42,8 @@
 #include "gsimpleasyncresult.h"
 #include "gioerror.h"
 #include "glibintl.h"
+/* for BUFSIZ */
+#include <stdio.h>
 
 #include "gioalias.h"
 
@@ -284,13 +286,33 @@
                     GIOCondition condition,
                     gpointer user_data)
 {
-  char *str;
-  gsize str_len;
   UnmountEjectOp *data = user_data;
+  char buf[BUFSIZ];
+  gsize bytes_read;
+  GError *error;
+  GIOStatus status;
+
+  error = NULL;
+read:
+  status = g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read, &error);
+  if (status == G_IO_STATUS_NORMAL)
+   {
+     g_string_append_len (data->error_string, buf, bytes_read);
+     if (bytes_read == sizeof (buf))
+        goto read;
+   }
+  else if (status == G_IO_STATUS_EOF)
+    g_string_append_len (data->error_string, buf, bytes_read);
+  else if (status == G_IO_STATUS_ERROR)
+    {
+      if (data->error_string->len > 0)
+        g_string_append (data->error_string, "\n");
+
+      g_string_append (data->error_string, error->message);
+      g_error_free (error);
+      return FALSE;
+    }
 
-  g_io_channel_read_to_end (channel, &str, &str_len, NULL);
-  g_string_append (data->error_string, str);
-  g_free (str);
   return TRUE;
 }
 
@@ -324,6 +346,22 @@
                                  NULL,           /* standard_output */
                                  &(data->error_fd),
                                  &error)) {
+    g_assert (error != NULL);
+    goto handle_error;
+  }
+
+  data->error_string = g_string_new ("");
+
+  data->error_channel = g_io_channel_unix_new (data->error_fd);
+  g_io_channel_set_flags (data->error_channel, G_IO_FLAG_NONBLOCK, &error);
+  if (error != NULL)
+    goto handle_error;
+
+  data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, eject_unmount_read_error, data);
+  g_child_watch_add (child_pid, eject_unmount_cb, data);
+
+handle_error:
+  if (error != NULL) {
     GSimpleAsyncResult *simple;
     simple = g_simple_async_result_new_from_error (G_OBJECT (data->unix_mount),
                                                    data->callback,
@@ -331,14 +369,16 @@
                                                    error);
     g_simple_async_result_complete (simple);
     g_object_unref (simple);
+
+    if (data->error_string != NULL)
+      g_string_free (data->error_string, TRUE);
+
+    if (data->error_channel != NULL)
+      g_io_channel_unref (data->error_channel);
+
     g_error_free (error);
     g_free (data);
-    return;
   }
-  data->error_string = g_string_new ("");
-  data->error_channel = g_io_channel_unix_new (data->error_fd);
-  data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, eject_unmount_read_error, data);
-  g_child_watch_add (child_pid, eject_unmount_cb, data);
 }
 
 static void

Modified: trunk/gio/gunixvolume.c
==============================================================================
--- trunk/gio/gunixvolume.c	(original)
+++ trunk/gio/gunixvolume.c	Mon Sep  8 12:44:07 2008
@@ -39,6 +39,8 @@
 #include "gsimpleasyncresult.h"
 #include "gioerror.h"
 #include "glibintl.h"
+/* for BUFSIZ */
+#include <stdio.h>
 
 #include "gioalias.h"
 
@@ -333,13 +335,33 @@
                   GIOCondition condition,
                   gpointer user_data)
 {
-  char *str;
-  gsize str_len;
   EjectMountOp *data = user_data;
+  char buf[BUFSIZ];
+  gsize bytes_read;
+  GError *error;
+  GIOStatus status;
+
+  error = NULL;
+read:
+  status = g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read, &error);
+  if (status == G_IO_STATUS_NORMAL)
+   {
+     g_string_append_len (data->error_string, buf, bytes_read);
+     if (bytes_read == sizeof (buf))
+        goto read;
+   }
+  else if (status == G_IO_STATUS_EOF)
+    g_string_append_len (data->error_string, buf, bytes_read);
+  else if (status == G_IO_STATUS_ERROR)
+    {
+      if (data->error_string->len > 0)
+        g_string_append (data->error_string, "\n");
+
+      g_string_append (data->error_string, error->message);
+      g_error_free (error);
+      return FALSE;
+    }
 
-  g_io_channel_read_to_end (channel, &str, &str_len, NULL);
-  g_string_append (data->error_string, str);
-  g_free (str);
   return TRUE;
 }
 
@@ -373,6 +395,22 @@
                                  NULL,           /* standard_output */
                                  &(data->error_fd),
                                  &error)) {
+    g_assert (error != NULL);
+    goto handle_error;
+  }
+
+  data->error_string = g_string_new ("");
+
+  data->error_channel = g_io_channel_unix_new (data->error_fd);
+  g_io_channel_set_flags (data->error_channel, G_IO_FLAG_NONBLOCK, &error);
+  if (error != NULL)
+    goto handle_error;
+
+  data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, eject_mount_read_error, data);
+  g_child_watch_add (child_pid, eject_mount_cb, data);
+
+handle_error:
+  if (error != NULL) {
     GSimpleAsyncResult *simple;
     simple = g_simple_async_result_new_from_error (G_OBJECT (data->unix_volume),
                                                    data->callback,
@@ -380,14 +418,16 @@
                                                    error);
     g_simple_async_result_complete (simple);
     g_object_unref (simple);
+
+    if (data->error_string != NULL)
+      g_string_free (data->error_string, TRUE);
+
+    if (data->error_channel != NULL)
+      g_io_channel_unref (data->error_channel);
+
     g_error_free (error);
     g_free (data);
-    return;
   }
-  data->error_string = g_string_new ("");
-  data->error_channel = g_io_channel_unix_new (data->error_fd);
-  data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, eject_mount_read_error, data);
-  g_child_watch_add (child_pid, eject_mount_cb, data);
 }
 
 



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