about summary refs log tree commit diff
path: root/src/libutil/util.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2004-05-11T13·48+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2004-05-11T13·48+0000
commitaea436503e9126b06cd15acf1f0c6b738ffbc7de (patch)
tree0ab35cc22a84f6ce7f5bf69b164dcb1cc2002330 /src/libutil/util.cc
parenta9858c9f26c5be743e0bbe1949954f6bd2497306 (diff)
* Ignore interrupt signals while handling an exception.
* Ignore EINTR in reads and writes.

Diffstat (limited to 'src/libutil/util.cc')
-rw-r--r--src/libutil/util.cc19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 354165432c..bf2954f534 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -305,7 +305,10 @@ void readFull(int fd, unsigned char * buf, size_t count)
     while (count) {
         checkInterrupt();
         ssize_t res = read(fd, (char *) buf, count);
-        if (res == -1) throw SysError("reading from file");
+        if (res == -1) {
+            if (errno == EINTR) continue;
+            throw SysError("reading from file");
+        }
         if (res == 0) throw Error("unexpected end-of-file");
         count -= res;
         buf += res;
@@ -318,7 +321,10 @@ void writeFull(int fd, const unsigned char * buf, size_t count)
     while (count) {
         checkInterrupt();
         ssize_t res = write(fd, (char *) buf, count);
-        if (res == -1) throw SysError("writing to file");
+        if (res == -1) {
+            if (errno == EINTR) continue;
+            throw SysError("writing to file");
+        }
         count -= res;
         buf += res;
     }
@@ -397,6 +403,11 @@ volatile sig_atomic_t _isInterrupted = 0;
 
 void _interrupted()
 {
-    _isInterrupted = 0;
-    throw Error("interrupted by the user");
+    /* Block user interrupts while an exception is being handled.
+       Throwing an exception while another exception is being handled
+       kills the program! */
+    if (!uncaught_exception()) {
+        _isInterrupted = 0;
+        throw Error("interrupted by the user");
+    }
 }