+ GSubprocess *subprocess = G_SUBPROCESS (source);
+ GTask *task = user_data;
+ GError *error = NULL;
+ gchar *stderr_str;
+
+ if (!g_subprocess_communicate_utf8_finish (subprocess, result, NULL, &stderr_str, &error))
+ {
+ g_task_return_error (task, error);
+ g_error_free (error);
+ }
+ else /* successful communication */
+ {
+ if (!g_subprocess_get_successful (subprocess))
+ /* ...but bad exit code */
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "%s", stderr_str);
+ else
+ /* ...and successful exit code */
+ g_task_return_boolean (task, TRUE);
+
+ g_free (stderr_str);
+ }
+
+ g_object_unref (task);
+}
+
+static void
+eject_mount_do (GVolume *volume,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data,
+ const gchar * const *argv)
+{
+ GSubprocess *subprocess;
+ GError *error = NULL;
+ GTask *task;
+
+ task = g_task_new (volume, cancellable, callback, user_data);
+
+ if (g_task_return_error_if_cancelled (task))
+ {
+ g_object_unref (task);
+ return;
+ }
+
+ subprocess = g_subprocess_newv (argv, G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_PIPE, &error);
+ g_assert_no_error (error);
+
+ g_subprocess_communicate_utf8_async (subprocess, NULL,
+ g_task_get_cancellable (task),
+ eject_mount_done, task);