diff --git a/daemon/daemon-main.c b/daemon/daemon-main.c
index b3b2b47..5be61c3 100644
--- a/daemon/daemon-main.c
+++ b/daemon/daemon-main.c
@@ -82,6 +82,14 @@ daemon_setup (void)
 }
 
 static void
+daemon_shutdown (GVfsDaemon *daemon,
+		 GMainLoop  *loop)
+{
+  if (g_main_loop_is_running (loop))
+    g_main_loop_quit (loop);
+}
+
+static void
 send_spawned (DBusConnection *connection, gboolean succeeded, char *error_message)
 {
   DBusMessage *message;
@@ -253,7 +261,11 @@ daemon_main (int argc,
       exit (1);
     }
 
-  g_vfs_daemon_set_max_threads (daemon, max_job_threads);  
+  loop = g_main_loop_new (NULL, FALSE); 
+  
+  g_vfs_daemon_set_max_threads (daemon, max_job_threads);
+  g_signal_connect (daemon, "shutdown",
+		    G_CALLBACK (daemon_shutdown), loop);
   
   send_spawned (connection, TRUE, NULL);
 	  
@@ -265,8 +277,9 @@ daemon_main (int argc,
       g_object_unref (mount_source);
     }
   
-  loop = g_main_loop_new (NULL, FALSE);
-
   g_main_loop_run (loop);
+
+  g_object_unref (daemon);
+  g_main_loop_unref (loop);
 }
 
diff --git a/daemon/gvfsbackendcdda.c b/daemon/gvfsbackendcdda.c
index 24ba0c2..22839d6 100644
--- a/daemon/gvfsbackendcdda.c
+++ b/daemon/gvfsbackendcdda.c
@@ -165,7 +165,7 @@ _hal_device_removed (LibHalContext *hal_ctx, const char *udi)
     {
       /*g_warning ("we have been removed!");*/
       /* TODO: need a cleaner way to force unmount ourselves */
-      exit (1);
+      g_vfs_job_source_closed (G_VFS_JOB_SOURCE (cdda_backend));
     }
 }
 
diff --git a/daemon/gvfsbackendsftp.c b/daemon/gvfsbackendsftp.c
index 8a08e1f..e181648 100644
--- a/daemon/gvfsbackendsftp.c
+++ b/daemon/gvfsbackendsftp.c
@@ -1038,7 +1038,12 @@ read_reply_async_got_len  (GObject *source_object,
   error = NULL;
   res = g_input_stream_read_finish (G_INPUT_STREAM (source_object), result, &error);
 
-  if (res <= 0)
+  if (res == 0)
+    {
+      /* EOF */
+      return;
+    }
+  else if (res < 0)
     {
       /* TODO: unmount, etc */
       g_warning ("Error reading results: %s", res < 0 ? error->message : "end of stream");
diff --git a/daemon/gvfsdaemon.c b/daemon/gvfsdaemon.c
index f9f5276..9756697 100644
--- a/daemon/gvfsdaemon.c
+++ b/daemon/gvfsdaemon.c
@@ -46,6 +46,11 @@ enum {
   PROP_0
 };
 
+enum {
+  SHUTDOWN,
+  LAST_SIGNAL
+};
+
 typedef struct {
   char *obj_path;
   DBusObjectPathMessageFunction callback;
@@ -82,6 +87,8 @@ typedef struct {
   DBusConnection *conn;
 } NewConnectionData;
 
+static guint signals[LAST_SIGNAL] = { 0 };
+
 static void              g_vfs_daemon_get_property (GObject        *object,
 						    guint           prop_id,
 						    GValue         *value,
@@ -131,6 +138,15 @@ g_vfs_daemon_class_init (GVfsDaemonClass *klass)
   gobject_class->finalize = g_vfs_daemon_finalize;
   gobject_class->set_property = g_vfs_daemon_set_property;
   gobject_class->get_property = g_vfs_daemon_get_property;
+
+  signals[SHUTDOWN] =
+    g_signal_new ("shutdown",
+		  G_TYPE_FROM_CLASS (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GVfsDaemonClass, shutdown),
+		  NULL, NULL,
+		  g_cclosure_marshal_VOID__VOID,
+		  G_TYPE_NONE, 0);
 }
 
 static void
@@ -289,9 +305,9 @@ g_vfs_daemon_set_max_threads (GVfsDaemon                    *daemon,
 }
 
 static gboolean
-exit_at_idle (gpointer data)
+exit_at_idle (GVfsDaemon *daemon)
 {
-  exit (0);
+  g_signal_emit (daemon, signals[SHUTDOWN], 0);
   return FALSE;
 }
 
@@ -309,7 +325,7 @@ static void
 daemon_schedule_exit (GVfsDaemon *daemon)
 {
   if (daemon->exit_tag == 0)
-    daemon->exit_tag = g_timeout_add (1000, exit_at_idle, daemon);
+    daemon->exit_tag = g_timeout_add (1000, (GSourceFunc)exit_at_idle, daemon);
 }
 
 static void
@@ -324,8 +340,10 @@ static void
 job_source_closed_callback (GVfsJobSource *job_source,
 			    GVfsDaemon *daemon)
 {
+  g_print ("Removed job source %p (%s)\n", job_source, g_type_name_from_instance ((gpointer)job_source));
+	
   g_mutex_lock (daemon->lock);
-  
+
   daemon->job_sources = g_list_remove (daemon->job_sources,
 				       job_source);
   
@@ -420,7 +438,8 @@ static void
 job_finished_callback (GVfsJob *job, 
 		       GVfsDaemon *daemon)
 {
-
+  g_print ("Finished job %p (%s)\n", job, g_type_name_from_instance ((gpointer)job));
+	
   g_signal_handlers_disconnect_by_func (job,
 					(GCallback)job_new_source_callback,
 					daemon);
@@ -431,7 +450,7 @@ job_finished_callback (GVfsJob *job,
   g_mutex_lock (daemon->lock);
   daemon->jobs = g_list_remove (daemon->jobs, job);
   g_mutex_unlock (daemon->lock);
-  
+
   g_object_unref (job);
 }
 
@@ -1057,4 +1076,5 @@ g_vfs_daemon_initiate_mount (GVfsDaemon *daemon,
 
   job = g_vfs_job_mount_new (mount_spec, mount_source, is_automount, request, backend);
   g_vfs_daemon_queue_job (daemon, job);
+  g_object_unref (job);
 }
diff --git a/daemon/gvfsdaemon.h b/daemon/gvfsdaemon.h
index f40f216..2c12e70 100644
--- a/daemon/gvfsdaemon.h
+++ b/daemon/gvfsdaemon.h
@@ -45,6 +45,9 @@ struct _GVfsDaemonClass
 {
   GObjectClass parent_class;
 
+  /* signals */
+  void (*shutdown) (GVfsDaemon *daemon);
+	
   /* vtable */
   
 };
diff --git a/daemon/main.c b/daemon/main.c
index 660e9aa..8f8c4d8 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -34,6 +34,14 @@
 #include "mount.h"
 #include <locale.h>
 
+static void
+daemon_shutdown (GVfsDaemon *daemon,
+                 GMainLoop  *loop)
+{
+  if (g_main_loop_is_running (loop))
+    g_main_loop_quit (loop);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -99,6 +107,9 @@ main (int argc, char *argv[])
   
   loop = g_main_loop_new (NULL, FALSE);
 
+  g_signal_connect (daemon, "shutdown",
+                    G_CALLBACK (daemon_shutdown), loop);
+
 
 #ifdef HAVE_FUSE
   if (!no_fuse)
@@ -128,6 +139,9 @@ main (int argc, char *argv[])
 #endif
   
   g_main_loop_run (loop);
+
+  g_object_unref (daemon);
+  g_main_loop_unref (loop);
   
   return 0;
 }
