From 95a132f183a16da62e1b0617f55a4c8e3bfd7458 Mon Sep 17 00:00:00 2001 From: Colin Leroy Date: Wed, 21 May 2008 06:36:25 +0000 Subject: [PATCH] 2008-05-21 [colin] 3.4.0cvs57 * src/common/utils.c Fix bug 1615, 'hang on FIFO when the other end's not opened' --- ChangeLog | 6 +++++ PATCHSETS | 1 + configure.ac | 2 +- src/common/utils.c | 58 +++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4ede9fce1..cafd4c6ac 100644 --- 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 diff --git a/PATCHSETS b/PATCHSETS index 45dd1e588..df8a48d5d 100644 --- a/PATCHSETS +++ b/PATCHSETS @@ -3352,3 +3352,4 @@ ( 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 diff --git a/configure.ac b/configure.ac index 8fae96f3f..4bab55fa2 100644 --- a/configure.ac +++ b/configure.ac @@ -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= diff --git a/src/common/utils.c b/src/common/utils.c index f37db2b74..c8f7cb534 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -53,10 +53,11 @@ #include #endif +#include + #ifdef G_OS_WIN32 # include # include -# include # include #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; } -- 2.25.1