about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2003-07-20T21·11+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2003-07-20T21·11+0000
commit7984cfc7c18c85c5db42c5c7d57927b12c846ce0 (patch)
treea728a7500892e4de089c090538cb8fd34e4a1ffa
parent667a6afb9dabcb3e5c851b910705b7eb1c87c9b6 (diff)
* Argh, another short-write problem. Added wrappers around
  read()/write() to fix this once and for all.

-rwxr-xr-xscripts/nix-switch.in3
-rw-r--r--src/archive.cc2
-rw-r--r--src/archive.hh2
-rw-r--r--src/nix.cc17
-rw-r--r--src/references.cc7
-rw-r--r--src/store.cc11
-rw-r--r--src/test.cc11
-rw-r--r--src/util.cc23
-rw-r--r--src/util.hh6
9 files changed, 46 insertions, 36 deletions
diff --git a/scripts/nix-switch.in b/scripts/nix-switch.in
index 55305418c7f6..2ccb6b4e5786 100755
--- a/scripts/nix-switch.in
+++ b/scripts/nix-switch.in
@@ -15,6 +15,9 @@ $hash || die "no package hash specified";
 my $linkdir = "@localstatedir@/nix/links";
 
 # Build the specified package, and all its dependencies.
+system "nix -ih $hash";
+if ($?) { die "`nix -ih' failed"; }
+
 my $pkgdir = `nix -qph $hash`;
 if ($?) { die "`nix -qph' failed"; }
 chomp $pkgdir;
diff --git a/src/archive.cc b/src/archive.cc
index 73fc75fa27d4..9170ca3ad650 100644
--- a/src/archive.cc
+++ b/src/archive.cc
@@ -190,7 +190,7 @@ static string readString(RestoreSource & source)
 {
     unsigned int len = readInt(source);
     char buf[len];
-    source((const unsigned char *) buf, len);
+    source((unsigned char *) buf, len);
     readPadding(len, source);
     return string(buf, len);
 }
diff --git a/src/archive.hh b/src/archive.hh
index 7d9b1e2b5676..e6006e454942 100644
--- a/src/archive.hh
+++ b/src/archive.hh
@@ -54,7 +54,7 @@ struct RestoreSource
        pointed to by data.  It should block if that much data is not
        yet available, or throw an error if it is not going to be
        available. */
-    virtual void operator () (const unsigned char * data, unsigned int len) = 0;
+    virtual void operator () (unsigned char * data, unsigned int len) = 0;
 };
 
 void restorePath(const string & path, RestoreSource & source);
diff --git a/src/nix.cc b/src/nix.cc
index f5ca0b4d8793..ad4e6a468a0c 100644
--- a/src/nix.cc
+++ b/src/nix.cc
@@ -215,12 +215,7 @@ struct StdoutSink : DumpSink
     virtual void operator ()
         (const unsigned char * data, unsigned int len)
     {
-        while (len) {
-            ssize_t res = write(STDOUT_FILENO, (char *) data, len);
-            if (res == -1) throw SysError("writing to stdout");
-            len -= res;
-            data += res;
-        }
+        writeFull(STDOUT_FILENO, data, len);
     }
 };
 
@@ -247,15 +242,9 @@ static void opDump(Strings opFlags, Strings opArgs)
 /* A source that read restore intput to stdin. */
 struct StdinSource : RestoreSource
 {
-    virtual void operator () (const unsigned char * data, unsigned int len)
+    virtual void operator () (unsigned char * data, unsigned int len)
     {
-        while (len) {
-            ssize_t res = read(STDIN_FILENO, (char *) data, len);
-            if (res == -1) throw SysError("reading from stdin");
-            if (res == 0) throw Error("unexpected end-of-file on stdin");
-            len -= res;
-            data += res;
-        }
+        readFull(STDIN_FILENO, data, len);
     }
 };
 
diff --git a/src/references.cc b/src/references.cc
index a42c1aed02c1..8934d53061cd 100644
--- a/src/references.cc
+++ b/src/references.cc
@@ -55,12 +55,11 @@ void checkPath(const string & path,
         int fd = open(path.c_str(), O_RDONLY);
         if (fd == -1) throw SysError(format("opening file `%1%'") % path);
 
-        char * buf = new char[st.st_size];
+        unsigned char * buf = new unsigned char[st.st_size];
 
-        if (read(fd, buf, st.st_size) != st.st_size)
-            throw SysError(format("reading file %1%") % path);
+        readFull(fd, buf, st.st_size);
 
-        search(string(buf, st.st_size), ids, seen);
+        search(string((char *) buf, st.st_size), ids, seen);
         
         delete buf; /* !!! autodelete */
 
diff --git a/src/store.cc b/src/store.cc
index 0ce5f26044fb..6f1a2fc39d1c 100644
--- a/src/store.cc
+++ b/src/store.cc
@@ -15,8 +15,7 @@ struct CopySink : DumpSink
     int fd;
     virtual void operator () (const unsigned char * data, unsigned int len)
     {
-        if (write(fd, (char *) data, len) != (ssize_t) len)
-            throw SysError("writing to child");
+        writeFull(fd, data, len);
     }
 };
 
@@ -24,13 +23,9 @@ struct CopySink : DumpSink
 struct CopySource : RestoreSource
 {
     int fd;
-    virtual void operator () (const unsigned char * data, unsigned int len)
+    virtual void operator () (unsigned char * data, unsigned int len)
     {
-        ssize_t res = read(fd, (char *) data, len);
-        if (res == -1)
-            throw SysError("reading from parent");
-        if (res != (ssize_t) len)
-            throw Error("not enough data available on parent");
+        readFull(fd, data, len);
     }
 };
 
diff --git a/src/test.cc b/src/test.cc
index fa7c93820558..5c7559af6afd 100644
--- a/src/test.cc
+++ b/src/test.cc
@@ -37,21 +37,16 @@ struct MySink : DumpSink
     virtual void operator () (const unsigned char * data, unsigned int len)
     {
         /* Don't use cout, it's slow as hell! */
-        if (write(STDOUT_FILENO, (char *) data, len) != (ssize_t) len)
-            throw SysError("writing to stdout");
+        writeFull(STDOUT_FILENO, data, len);
     }
 };
 
 
 struct MySource : RestoreSource
 {
-    virtual void operator () (const unsigned char * data, unsigned int len)
+    virtual void operator () (unsigned char * data, unsigned int len)
     {
-        ssize_t res = read(STDIN_FILENO, (char *) data, len);
-        if (res == -1)
-            throw SysError("reading from stdin");
-        if (res != (ssize_t) len)
-            throw Error("not enough data available on stdin");
+        readFull(STDIN_FILENO, data, len);
     }
 };
 
diff --git a/src/util.cc b/src/util.cc
index d7c1fe60e15a..a16643022a9d 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -159,3 +159,26 @@ void debug(const format & f)
 {
     msg(format("debug: %1%") % f.str());
 }
+
+
+void readFull(int fd, unsigned char * buf, size_t count)
+{
+    while (count) {
+        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");
+        count -= res;
+        buf += res;
+    }
+}
+
+
+void writeFull(int fd, const unsigned char * buf, size_t count)
+{
+    while (count) {
+        ssize_t res = write(fd, (char *) buf, count);
+        if (res == -1) throw SysError("writing to file");
+        count -= res;
+        buf += res;
+    }
+}
diff --git a/src/util.hh b/src/util.hh
index 611612a589c6..8b23bee00b76 100644
--- a/src/util.hh
+++ b/src/util.hh
@@ -85,4 +85,10 @@ void msg(const format & f);
 void debug(const format & f);
 
 
+/* Wrappers arount read()/write() that read/write exactly the
+   requested number of bytes. */
+void readFull(int fd, unsigned char * buf, size_t count);
+void writeFull(int fd, const unsigned char * buf, size_t count);
+
+
 #endif /* !__UTIL_H */