Use select when reading mount command output
authorMikko Rasa <tdb@tdb.fi>
Sat, 19 Apr 2014 18:02:47 +0000 (21:02 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 19 Apr 2014 18:02:47 +0000 (21:02 +0300)
If pmount ends up using FUSE to do the actual mounting, the filesystem
driver process inherits the output capture pipe.  In this case the write
end of the pipe stays open and read can block indefinitely.  Instead of
relying on read to return eof, call waitpid if select indicates no data
available.

main.c

diff --git a/main.c b/main.c
index 609db229f90787cd076fa1d245b6c6d864ceb99b..916c2e214fce6c636c6eaf5889a012231af990eb 100644 (file)
--- a/main.c
+++ b/main.c
@@ -566,22 +566,32 @@ void row_activated(GtkTreeView *list, GtkTreePath *path, GtkTreeViewColumn *colu
                        char buf[1024];
                        int pos = 0;
                        int status;
+                       fd_set fds;
+                       struct timeval timeout;
 
                        close(pipe_fd[1]);
+                       FD_ZERO(&fds);
+                       FD_SET(pipe_fd[0], &fds);
+                       timeout.tv_sec = 0;
+                       timeout.tv_usec = 200000;
 
                        while(1)
                        {
-                               int len;
+                               if(select(pipe_fd[0]+1, &fds, NULL, NULL, &timeout))
+                               {
+                                       int len;
 
-                               len = read(pipe_fd[0], buf+pos, sizeof(buf)-pos-1);
-                               if(len<=0)
+                                       len = read(pipe_fd[0], buf+pos, sizeof(buf)-pos-1);
+                                       if(len<=0)
+                                               break;
+                                       pos += len;
+                               }
+                               else if(waitpid(pid, &status, 0))
                                        break;
-                               pos += len;
                        }
 
                        buf[pos] = 0;
 
-                       waitpid(pid, &status, 0);
                        if(!WIFEXITED(status) || WEXITSTATUS(status))
                        {
                                GtkWidget *dialog;