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.

svn path=/trunk/; revision=7444
This commit is contained in:
Christian Neumair 2008-09-08 12:44:07 +00:00 committed by Christian Neumair
parent 7b54bccc74
commit b9c69790a8
3 changed files with 106 additions and 20 deletions

View File

@ -1,3 +1,9 @@
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.
2008-09-06 Matthias Clasen <mclasen@redhat.com>
Bug 551149 xdgmime mem leak

View File

@ -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 @@ eject_unmount_read_error (GIOChannel *channel,
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 @@ eject_unmount_do (GMount *mount,
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 @@ eject_unmount_do (GMount *mount,
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

View File

@ -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 @@ eject_mount_read_error (GIOChannel *channel,
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 @@ eject_mount_do (GVolume *volume,
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 @@ eject_mount_do (GVolume *volume,
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);
}