support for multiplexing fuse fd
diff --git a/ChangeLog b/ChangeLog
index 6786d2e..5448cc9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,12 @@
 	* Acquire inode->i_sem before open and release methods to prevent
 	concurrent rename or unlink operations.
 
+	* Make __fuse_read_cmd() read only one command.  This allows
+	multiplexing the fuse file descriptor with other event sources
+	using select() or poll() (patch by Jeff Harris)
+
+	* Export 'exited' flag with __fuse_exited() (patch by Jeff Harris)
+
 2004-06-27  Miklos Szeredi <mszeredi@inf.bme.hu>
 
 	* Fix file offset wrap around at 4G when doing large reads
diff --git a/include/fuse.h b/include/fuse.h
index d298cb3..aeeb204 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -273,6 +273,7 @@
 struct fuse_cmd *__fuse_read_cmd(struct fuse *f);
 void __fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd);
 void __fuse_loop_mt(struct fuse *f, fuse_processor_t proc, void *data);
+int __fuse_exited(struct fuse* f);
 
 #ifdef __cplusplus
 }
diff --git a/lib/fuse.c b/lib/fuse.c
index d4e95f2..4cd8915 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -1432,6 +1432,11 @@
     free_cmd(cmd);
 }
 
+int __fuse_exited(struct fuse* f)
+{
+    return f->exited;
+}
+
 struct fuse_cmd *__fuse_read_cmd(struct fuse *f)
 {
     ssize_t res;
@@ -1444,36 +1449,36 @@
     in = (struct fuse_in_header *) cmd->buf;
     inarg = cmd->buf + sizeof(struct fuse_in_header);
 
-    do {
-        res = read(f->fd, cmd->buf, FUSE_MAX_IN);
-        if (res == -1) {
-            free_cmd(cmd);
-            if (f->exited || errno == EINTR)
-                return NULL;
-
-            /* ENODEV means we got unmounted, so we silenty return failure */
-            if (errno != ENODEV) {
-                /* BAD... This will happen again */
-                perror("fuse: reading device");
-            }
-
-            fuse_exit(f);
+    res = read(f->fd, cmd->buf, FUSE_MAX_IN);
+    if (res == -1) {
+        free_cmd(cmd);
+        if (__fuse_exited(f) || errno == EINTR)
             return NULL;
-        }
-        if ((size_t) res < sizeof(struct fuse_in_header)) {
-            free_cmd(cmd);
-            /* Cannot happen */
-            fprintf(stderr, "short read on fuse device\n");
-            fuse_exit(f);
-            return NULL;
-        }
-        cmd->buflen = res;
         
-        /* Forget is special, it can be done without messing with threads. */
-        if (in->opcode == FUSE_FORGET)
-            do_forget(f, in, (struct fuse_forget_in *) inarg);
-
-    } while (in->opcode == FUSE_FORGET);
+        /* ENODEV means we got unmounted, so we silenty return failure */
+        if (errno != ENODEV) {
+            /* BAD... This will happen again */
+            perror("fuse: reading device");
+        }
+        
+        fuse_exit(f);
+        return NULL;
+    }
+    if ((size_t) res < sizeof(struct fuse_in_header)) {
+        free_cmd(cmd);
+        /* Cannot happen */
+        fprintf(stderr, "short read on fuse device\n");
+        fuse_exit(f);
+        return NULL;
+    }
+    cmd->buflen = res;
+    
+    /* Forget is special, it can be done without messing with threads. */
+    if (in->opcode == FUSE_FORGET) {
+        do_forget(f, in, (struct fuse_forget_in *) inarg);
+        free_cmd(cmd);
+        return NULL;
+    }
 
     return cmd;
 }
@@ -1486,7 +1491,7 @@
     while (1) {
         struct fuse_cmd *cmd;
 
-        if (f->exited)
+        if (__fuse_exited(f))
             return;
 
         cmd = __fuse_read_cmd(f);
diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c
index afc70d4..597ce1a 100644
--- a/lib/fuse_mt.c
+++ b/lib/fuse_mt.c
@@ -38,7 +38,7 @@
     while (1) {
         struct fuse_cmd *cmd;
 
-        if (f->exited)
+        if (__fuse_exited(f))
             break;
 
         cmd = __fuse_read_cmd(w->f);