From 54664b6fb74e964d70530d13e25459751d0c63fb Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 16 Jul 2003 21:24:02 +0000 Subject: [PATCH] * The write() system call can write less than the requested number of bytes, e.g., in case of a signal like SIGSTOP. This caused `nix --dump' to fail sometimes. Note that this bug went unnoticed because the call to `nix --dump' is in a pipeline, and the shell ignores non-zero exit codes from all but the last element in the pipeline. Is there any way to check the result of the initial elements in the pipeline? (In other words, is it at all possible to write reliable shell scripts?) --- corepkgs/nar/nar.sh | 2 ++ scripts/nix-push.in | 4 ++++ src/nix.cc | 10 +++++++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/corepkgs/nar/nar.sh b/corepkgs/nar/nar.sh index 059bca8ba..a7b6be8aa 100644 --- a/corepkgs/nar/nar.sh +++ b/corepkgs/nar/nar.sh @@ -1,3 +1,5 @@ #! /bin/sh +echo "packing $path into $out..." /nix/bin/nix --dump --file "$path" | bzip2 > $out || exit 1 + diff --git a/scripts/nix-push.in b/scripts/nix-push.in index fdb432303..bb25019e8 100644 --- a/scripts/nix-push.in +++ b/scripts/nix-push.in @@ -8,6 +8,8 @@ foreach my $id (@ARGV) { # Get all paths referenced by the normalisation of the given # fstate expression. + system "nix -ih $id"; + if ($?) { die "`nix -ih' failed"; } my @paths; open PATHS, "nix -qrh $id 2> /dev/null |" or die "nix -qrh"; while () { @@ -51,6 +53,8 @@ foreach my $id (@ARGV) { die unless $nid =~ /^([0-9a-z]{32})$/; # Realise the Nix expression. + system "nix -ih $nid"; + if ($?) { die "`nix -ih' failed"; } my $npath = `nix -qph $nid 2> /dev/null`; $? and die "creating Nix archive"; chomp $npath; diff --git a/src/nix.cc b/src/nix.cc index ae016824d..fe762798e 100644 --- a/src/nix.cc +++ b/src/nix.cc @@ -216,8 +216,12 @@ struct StdoutSink : DumpSink virtual void operator () (const unsigned char * data, unsigned int len) { - if (write(STDOUT_FILENO, (char *) data, len) != (ssize_t) len) - throw SysError("writing to stdout"); + while (len) { + ssize_t res = write(STDOUT_FILENO, (char *) data, len); + if (res == -1) throw SysError("writing to stdout"); + len -= res; + data += res; + } } }; @@ -249,7 +253,7 @@ struct StdinSource : RestoreSource while (len) { ssize_t res = read(STDIN_FILENO, (char *) data, len); if (res == -1) throw SysError("reading from stdin"); - if (res == 0) throw SysError("unexpected end-of-file on stdin"); + if (res == 0) throw Error("unexpected end-of-file on stdin"); len -= res; data += res; }