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;