author | Alberto Bertogli
<albertito@blitiri.com.ar> 2009-06-16 18:34:49 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2009-06-16 19:17:07 UTC |
parent | f50ef946b445346457108e40b1d31c44283935ee |
libfiu/fiu-rc.c | +18 | -2 |
libfiu/fiu.c | +5 | -1 |
libfiu/internal.h | +11 | -0 |
diff --git a/libfiu/fiu-rc.c b/libfiu/fiu-rc.c index 678a4b8..83dcb83 100644 --- a/libfiu/fiu-rc.c +++ b/libfiu/fiu-rc.c @@ -18,6 +18,7 @@ #define FIU_ENABLE 1 #include "fiu-control.h" +#include "internal.h" /* Max length of a line containing a control directive */ @@ -181,6 +182,11 @@ static void *rc_fifo_thread(void *unused) { int fdr, fdw, r; + /* increment the recursion count so we're not affected by libfiu, + * otherwise we could make the remote control useless by enabling all + * failure points */ + rec_count++; + reopen: fdr = open(npipe_path_in, O_RDONLY); if (fdr < 0) @@ -196,7 +202,9 @@ reopen: r = rc_do_command(fdr, fdw); if (r < 0 && errno != EPIPE) { perror("libfiu: Error reading from remote control"); - break; + close(fdr); + close(fdw); + goto reopen; } else if (r == 0 || (r < 0 && errno == EPIPE)) { /* one of the ends of the pipe was closed */ close(fdr); @@ -221,25 +229,33 @@ static int _fiu_rc_fifo(const char *basename) { pthread_t thread; + /* see rc_fifo_thread() */ + rec_count++; + snprintf(npipe_path_in, PATH_MAX,"%s-%d.in", basename, getpid()); snprintf(npipe_path_out, PATH_MAX,"%s-%d.out", basename, getpid()); - if (mknod(npipe_path_in, S_IFIFO | 0600, 0) != 0) + if (mknod(npipe_path_in, S_IFIFO | 0600, 0) != 0) { + rec_count--; return -1; + } if (mknod(npipe_path_out, S_IFIFO | 0600, 0) != 0) { unlink(npipe_path_in); + rec_count--; return -1; } if (pthread_create(&thread, NULL, rc_fifo_thread, NULL) != 0) { unlink(npipe_path_in); unlink(npipe_path_out); + rec_count--; return -1; } atexit(fifo_atexit); + rec_count--; return 0; } diff --git a/libfiu/fiu.c b/libfiu/fiu.c index 797fe00..f0c344b 100644 --- a/libfiu/fiu.c +++ b/libfiu/fiu.c @@ -11,6 +11,7 @@ #include "fiu.h" #include "fiu-control.h" +#include "internal.h" /* Different methods to decide when a point of failure fails */ @@ -66,10 +67,13 @@ static pthread_rwlock_t enabled_fails_lock = PTHREAD_RWLOCK_INITIALIZER; * for writing, and can call malloc() (for example), which can in turn call * fiu_fail() which can take the lock for reading. * + * It is also modified at fiu-rc.c, to prevent failing within the remote + * control thread. + * * Sadly, we have to use the GNU extension for TLS, so we do not resort to * pthread_[get|set]specific() which could be wrapped. Luckily it's available * almost everywhere. */ -static __thread int rec_count = 0; +__thread int rec_count = 0; /* Maximum number of free elements in enabled_fails (used to decide when to diff --git a/libfiu/internal.h b/libfiu/internal.h new file mode 100644 index 0000000..2c3bfba --- /dev/null +++ b/libfiu/internal.h @@ -0,0 +1,11 @@ + +/* Some libfiu's internal declarations */ + +#ifndef _INTERNAL_H +#define _INTERNAL_H + +/* Recursion count, used both in fiu.c and fiu-rc.c */ +extern __thread int rec_count; + +#endif +