diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2006-03-01 12:10:13 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2006-03-01 12:10:13 +0000 |
commit | 5d9ce36da4688ba2c14f658ed40b5b4ad971879b (patch) | |
tree | 379c5435a0741965848f8eb2449bef9c8b4d080c /lib | |
parent | ee588c01dca3991807aea456a66246ff8ad0c332 (diff) | |
download | libfuse-5d9ce36da4688ba2c14f658ed40b5b4ad971879b.tar.gz |
fix
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fuse.c | 4 | ||||
-rw-r--r-- | lib/fuse_kern_chan.c | 29 | ||||
-rw-r--r-- | lib/fuse_loop.c | 10 | ||||
-rw-r--r-- | lib/fuse_loop_mt.c | 12 | ||||
-rw-r--r-- | lib/fuse_session.c | 9 | ||||
-rw-r--r-- | lib/fuse_versionscript | 1 |
6 files changed, 41 insertions, 24 deletions
@@ -1880,10 +1880,10 @@ struct fuse_cmd *fuse_read_cmd(struct fuse *f) size_t bufsize = fuse_chan_bufsize(ch); struct fuse_cmd *cmd = fuse_alloc_cmd(bufsize); if (cmd != NULL) { - int res = fuse_chan_receive(ch, cmd->buf, bufsize); + int res = fuse_chan_recv(ch, cmd->buf, bufsize); if (res <= 0) { free_cmd(cmd); - if (res == -1) + if (res < 0 && res != -EINTR && res != -EAGAIN) fuse_exit(f); return NULL; } diff --git a/lib/fuse_kern_chan.c b/lib/fuse_kern_chan.c index d58c8b2..fe7d252 100644 --- a/lib/fuse_kern_chan.c +++ b/lib/fuse_kern_chan.c @@ -16,26 +16,33 @@ static int fuse_kern_chan_receive(struct fuse_chan *ch, char *buf, size_t size) { - ssize_t res = read(fuse_chan_fd(ch), buf, size); - int err = errno; + int err; + ssize_t res; struct fuse_session *se = fuse_chan_session(ch); - assert(se != NULL); + + restart: + res = read(fuse_chan_fd(ch), buf, size); + err = errno; + if (fuse_session_exited(se)) return 0; if (res == -1) { - /* EINTR means, the read() was interrupted, ENOENT means the - operation was interrupted */ - if (err == EINTR || err == ENOENT) - return 0; - /* ENODEV means we got unmounted, so we silently return failure */ - if (err != ENODEV) + /* ENOENT means the operation was interrupted, it's safe + to restart */ + if (err == ENOENT) + goto restart; + + /* Errors occuring during normal operation: EINTR (read + interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem + umounted) */ + if (err != EINTR && err != EAGAIN && err != ENODEV) perror("fuse: reading device"); - return -1; + return -err; } if ((size_t) res < sizeof(struct fuse_in_header)) { fprintf(stderr, "short read on fuse device\n"); - return -1; + return -EIO; } return res; } diff --git a/lib/fuse_loop.c b/lib/fuse_loop.c index 1609bfc..6a6edaa 100644 --- a/lib/fuse_loop.c +++ b/lib/fuse_loop.c @@ -10,6 +10,7 @@ #include <stdio.h> #include <stdlib.h> +#include <errno.h> int fuse_session_loop(struct fuse_session *se) { @@ -23,16 +24,15 @@ int fuse_session_loop(struct fuse_session *se) } while (!fuse_session_exited(se)) { - res = fuse_chan_receive(ch, buf, bufsize); - if (!res) + res = fuse_chan_recv(ch, buf, bufsize); + if (res == -EINTR) continue; - if (res == -1) + if (res <= 0) break; fuse_session_process(se, buf, res, ch); - res = 0; } free(buf); fuse_session_reset(se); - return res; + return res < 0 ? -1 : 0; } diff --git a/lib/fuse_loop_mt.c b/lib/fuse_loop_mt.c index 540607b..16be149 100644 --- a/lib/fuse_loop_mt.c +++ b/lib/fuse_loop_mt.c @@ -74,12 +74,14 @@ static void *do_work(void *data) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); while (!fuse_session_exited(w->se)) { - int res = fuse_chan_receive(w->prevch, buf, bufsize); - if (!res) + int res = fuse_chan_recv(w->prevch, buf, bufsize); + if (res == -EINTR) continue; - if (res == -1) { - fuse_session_exit(w->se); - w->error = -1; + if (res <= 0) { + if (res < 0) { + fuse_session_exit(w->se); + w->error = -1; + } break; } diff --git a/lib/fuse_session.c b/lib/fuse_session.c index 4ea792a..8943204 100644 --- a/lib/fuse_session.c +++ b/lib/fuse_session.c @@ -12,6 +12,7 @@ #include <stdlib.h> #include <string.h> #include <assert.h> +#include <errno.h> struct fuse_session { struct fuse_session_ops op; @@ -143,11 +144,17 @@ struct fuse_session *fuse_chan_session(struct fuse_chan *ch) return ch->se; } -int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size) +int fuse_chan_recv(struct fuse_chan *ch, char *buf, size_t size) { return ch->op.receive(ch, buf, size); } +int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size) +{ + int res = fuse_chan_recv(ch, buf, size); + return res >= 0 ? res : (res != -EINTR && res != -EAGAIN) ? -1 : 0; +} + int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], size_t count) { return ch->op.send(ch, iov, count); diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript index 02ac176..2a8067a 100644 --- a/lib/fuse_versionscript +++ b/lib/fuse_versionscript @@ -96,6 +96,7 @@ FUSE_2.6 { fuse_setup_compat25; fuse_unmount; fuse_unmount_compat22; + fuse_chan_recv; local: *; |