diff options
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/archive.cc | 6 | ||||
-rw-r--r-- | src/libutil/util.cc | 17 | ||||
-rw-r--r-- | src/libutil/util.hh | 13 |
3 files changed, 36 insertions, 0 deletions
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index 90a039164..2b8fb2f10 100644 --- a/src/libutil/archive.cc +++ b/src/libutil/archive.cc @@ -83,6 +83,7 @@ static void dumpContents(const Path & path, unsigned int size, unsigned int total = 0; ssize_t n; while ((n = read(fd, buf, sizeof(buf)))) { + checkInterrupt(); if (n == -1) throw SysError("reading file " + path); total += n; sink(buf, n); @@ -200,6 +201,8 @@ static void restoreEntry(const Path & path, RestoreSource & source) if (s != "(") throw badArchive("expected open tag"); while (1) { + checkInterrupt(); + s = readString(source); if (s == ")") { @@ -224,6 +227,7 @@ static void restoreContents(int fd, const Path & path, RestoreSource & source) unsigned char buf[65536]; while (left) { + checkInterrupt(); unsigned int n = sizeof(buf); if (n > left) n = left; source(buf, n); @@ -247,6 +251,8 @@ static void restore(const Path & path, RestoreSource & source) AutoCloseFD fd; while (1) { + checkInterrupt(); + s = readString(source); if (s == ")") { diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 28e276a32..5c8b7279c 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -132,6 +132,7 @@ Strings readDirectory(const Path & path) struct dirent * dirent; while (errno = 0, dirent = readdir(dir)) { /* sic */ + checkInterrupt(); string name = dirent->d_name; if (name == "." || name == "..") continue; names.push_back(name); @@ -144,6 +145,8 @@ Strings readDirectory(const Path & path) void deletePath(const Path & path) { + checkInterrupt(); + printMsg(lvlVomit, format("deleting path `%1%'") % path); struct stat st; @@ -170,6 +173,8 @@ void deletePath(const Path & path) void makePathReadOnly(const Path & path) { + checkInterrupt(); + struct stat st; if (lstat(path.c_str(), &st)) throw SysError(format("getting attributes of path `%1%'") % path); @@ -199,6 +204,7 @@ static Path tempName() Path createTempDir() { while (1) { + checkInterrupt(); Path tmpDir = tempName(); if (mkdir(tmpDir.c_str(), 0777) == 0) return tmpDir; if (errno != EEXIST) @@ -246,6 +252,7 @@ void Nest::open(Verbosity level, const format & f) void printMsg_(Verbosity level, const format & f) { + checkInterrupt(); if (level > verbosity) return; string spaces; for (int i = 0; i < nestingLevel; i++) @@ -257,6 +264,7 @@ void printMsg_(Verbosity level, const format & f) 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 == 0) throw Error("unexpected end-of-file"); @@ -269,6 +277,7 @@ void readFull(int fd, unsigned char * buf, size_t count) 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"); count -= res; @@ -344,3 +353,11 @@ AutoCloseDir::operator DIR *() return dir; } + +volatile sig_atomic_t _isInterrupted = 0; + +void _interrupted() +{ + _isInterrupted = 0; + throw Error("interrupted by the user"); +} diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 5d27ac1bd..34fff003b 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -9,6 +9,7 @@ #include <sys/types.h> #include <dirent.h> #include <unistd.h> +#include <signal.h> #include <boost/format.hpp> @@ -179,4 +180,16 @@ public: }; +/* User interruption. */ + +extern volatile sig_atomic_t _isInterrupted; + +void _interrupted(); + +void inline checkInterrupt() +{ + if (_isInterrupted) _interrupted(); +} + + #endif /* !__UTIL_H */ |