fixes
diff --git a/lib/fuse.c b/lib/fuse.c
index 42ab52a..1a11ae6 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -355,8 +355,8 @@
     size_t outsize;
     struct fuse_out_header *out;
 
-    if(error > 0) {
-        fprintf(stderr, "fuse: positive error code: %i\n",  error);
+    if(error <= -512 || error > 0) {
+        fprintf(stderr, "fuse: bad error value: %i\n",  error);
         error = -ERANGE;
     }
 
@@ -366,6 +366,7 @@
     outsize = sizeof(struct fuse_out_header) + argsize;
     outbuf = (char *) malloc(outsize);
     out = (struct fuse_out_header *) outbuf;
+    memset(out, 0, sizeof(struct fuse_out_header));
     out->unique = in->unique;
     out->error = error;
     if(argsize != 0)
@@ -395,7 +396,9 @@
             res = f->op.getattr(path, &buf);
         free(path);
     }
+
     if(res == 0) {
+        memset(&arg, 0, sizeof(struct fuse_lookup_out));
         convert_stat(&buf, &arg.attr);
         arg.ino = find_node(f, in->ino, name, &arg.attr, in->unique);
         if(f->flags & FUSE_DEBUG) {
@@ -431,8 +434,11 @@
             res = f->op.getattr(path, &buf);
         free(path);
     }
-    if(res == 0) 
+
+    if(res == 0) {
+        memset(&arg, 0, sizeof(struct fuse_getattr_out));
         convert_stat(&buf, &arg.attr);
+    }
 
     send_reply(f, in, res, &arg, sizeof(arg));
 }
@@ -513,8 +519,10 @@
             if(!res) {
                 struct stat buf;
                 res = f->op.getattr(path, &buf);
-                if(!res)
+                if(!res) {
+                    memset(&outarg, 0, sizeof(struct fuse_setattr_out));
                     convert_stat(&buf, &outarg.attr);
+                }
             }
         }
         free(path);
@@ -559,6 +567,8 @@
         free(path);
     }
     fflush(dh.fp);
+
+    memset(&arg, 0, sizeof(struct fuse_getdir_out));
     arg.fd = fileno(dh.fp);
     send_reply(f, in, res, &arg, sizeof(arg));
     fclose(dh.fp);
@@ -584,6 +594,7 @@
         free(path);
     }
     if(res == 0) {
+        memset(&outarg, 0, sizeof(struct fuse_mknod_out));
         convert_stat(&buf, &outarg.attr);
         outarg.ino = find_node(f, in->ino, PARAM(inarg), &outarg.attr,
                                in->unique);
@@ -751,6 +762,7 @@
             fflush(stdout);
         }
     }
+    memset(out, 0, sizeof(struct fuse_out_header));
     out->unique = in->unique;
     out->error = res;
     outsize = sizeof(struct fuse_out_header) + size;
@@ -798,8 +810,10 @@
     struct fuse_statfs_out arg;
 
     res = -ENOSYS;
-    if(f->op.statfs)
+    if(f->op.statfs) {
+        memset(&arg, 0, sizeof(struct fuse_statfs_out));
         res = f->op.statfs((struct fuse_statfs *) &arg.st);
+    }
 
     send_reply(f, in, res, &arg, sizeof(arg));
 }
@@ -916,18 +930,24 @@
     do {
         res = read(f->fd, cmd->buf, FUSE_MAX_IN);
         if(res == -1) {
+            free_cmd(cmd);
+            if(errno == EINTR)
+                return NULL;
+
             /* ENODEV means we got unmounted, so we silenty return failure */
             if(errno != ENODEV) {
-                perror("fuse: reading device");
                 /* BAD... This will happen again */
+                perror("fuse: reading device");
             }
-            free_cmd(cmd);
+
+            fuse_exit(f);
             return NULL;
         }
         if((size_t) res < sizeof(struct fuse_in_header)) {
-            fprintf(stderr, "short read on fuse device\n");
-            /* Cannot happen */
             free_cmd(cmd);
+            /* Cannot happen */
+            fprintf(stderr, "short read on fuse device\n");
+            fuse_exit(f);
             return NULL;
         }
         cmd->buflen = res;
@@ -941,18 +961,27 @@
     return cmd;
 }
 
-
 void fuse_loop(struct fuse *f)
 {
     while(1) {
-        struct fuse_cmd *cmd = __fuse_read_cmd(f);
+        struct fuse_cmd *cmd;
+
+        if(f->exited)
+            return;
+
+        cmd = __fuse_read_cmd(f);
         if(cmd == NULL)
-            exit(1);
+            continue;
 
         __fuse_process_cmd(f, cmd);
     }
 }
 
+void fuse_exit(struct fuse *f)
+{
+    f->exited = 1;
+}
+
 struct fuse_context *fuse_get_context(struct fuse *f)
 {
     if(f->getcontext)
@@ -985,6 +1014,7 @@
     f->getcontext = NULL;
     f->context.uid = 0;
     f->context.gid = 0;
+    f->exited = 0;
 
     root = (struct node *) calloc(1, sizeof(struct node));
     root->mode = 0;