2008-05-21 [colin] 3.4.0cvs57
authorColin Leroy <colin@colino.net>
Wed, 21 May 2008 06:36:25 +0000 (06:36 +0000)
committerColin Leroy <colin@colino.net>
Wed, 21 May 2008 06:36:25 +0000 (06:36 +0000)
* src/common/utils.c
Fix bug 1615, 'hang on FIFO when the other end's not
opened'

ChangeLog
PATCHSETS
configure.ac
src/common/utils.c

index 4ede9fc..cafd4c6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-05-21 [colin]     3.4.0cvs57
+
+       * src/common/utils.c
+               Fix bug 1615, 'hang on FIFO when the other end's not 
+               opened'
+
 2008-05-21 [colin]     3.4.0cvs56
 
        * src/imap.c
index 45dd1e5..df8a48d 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.1.4.50 -r 1.1.4.51 src/prefs_filtering_action.c;  cvs diff -u -r 1.43.2.72 -r 1.43.2.73 src/prefs_matcher.c;  cvs diff -u -r 1.1.2.6 -r 1.1.2.7 src/common/tags.c;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 src/common/tags.h;  cvs diff -u -r 1.1.2.12 -r 1.1.2.13 src/gtk/combobox.c;  cvs diff -u -r 1.1.2.10 -r 1.1.2.11 src/gtk/combobox.h;  ) > 3.4.0cvs54.patchset
 ( cvs diff -u -r 1.1.2.50 -r 1.1.2.51 src/plugins/pgpcore/sgpgme.c;  ) > 3.4.0cvs55.patchset
 ( cvs diff -u -r 1.179.2.220 -r 1.179.2.221 src/imap.c;  ) > 3.4.0cvs56.patchset
+( cvs diff -u -r 1.36.2.139 -r 1.36.2.140 src/common/utils.c;  ) > 3.4.0cvs57.patchset
index 8fae96f..4bab55f 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=4
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=56
+EXTRA_VERSION=57
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index f37db2b..c8f7cb5 100644 (file)
 #include <sys/utsname.h>
 #endif
 
+#include <fcntl.h>
+
 #ifdef G_OS_WIN32
 #  include <direct.h>
 #  include <io.h>
-#  include <fcntl.h>
 #  include <w32lib.h>
 #endif
 
@@ -3089,11 +3090,62 @@ static gchar *file_read_to_str_full(const gchar *file, gboolean recode)
 {
        FILE *fp;
        gchar *str;
+       struct stat s;
+       gint fd, err;
+       struct timeval timeout = {1, 0};
+       fd_set fds;
+       int fflags = 0;
 
        g_return_val_if_fail(file != NULL, NULL);
 
-       if ((fp = g_fopen(file, "rb")) == NULL) {
-               FILE_OP_ERROR(file, "fopen");
+       if (g_stat(file, &s) != 0) {
+               FILE_OP_ERROR(file, "stat");
+               return NULL;
+       }
+       if (S_ISDIR(s.st_mode)) {
+               g_warning("%s: is a directory\n", file);
+               return NULL;
+       }
+
+       /* test whether the file is readable without blocking */
+       fd = open(file, O_RDONLY | O_NONBLOCK);
+       if (fd == -1) {
+               FILE_OP_ERROR(file, "open");
+               return NULL;
+       }
+       FD_ZERO(&fds);
+       FD_SET(fd, &fds);
+
+       /* allow for one second */
+       err = select(fd+1, &fds, NULL, NULL, &timeout);
+       if (err <= 0 || !FD_ISSET(fd, &fds)) {
+               if (err < 0) {
+                       FILE_OP_ERROR(file, "select");
+               } else {
+                       g_warning("%s: doesn't seem readable\n", file);
+               }
+               close(fd);
+               return NULL;
+       }
+       
+       /* Now clear O_NONBLOCK */
+       if ((fflags = fcntl(fd, F_GETFL)) < 0) {
+               FILE_OP_ERROR(file, "fcntl (F_GETFL)");
+               close(fd);
+               return NULL;
+       }
+       if (fcntl(fd, F_SETFL, (fflags & ~O_NONBLOCK)) < 0) {
+               FILE_OP_ERROR(file, "fcntl (F_SETFL)");
+               close(fd);
+               return NULL;
+       }
+       
+       /* get the FILE pointer */
+       fp = fdopen(fd, "rb");
+
+       if (fp == NULL) {
+               FILE_OP_ERROR(file, "fdopen");
+               close(fd); /* if fp isn't NULL, we'll use fclose instead! */
                return NULL;
        }