* 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?)
This commit is contained in:
parent
335aa1c35d
commit
54664b6fb7
|
@ -1,3 +1,5 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
|
||||||
|
echo "packing $path into $out..."
|
||||||
/nix/bin/nix --dump --file "$path" | bzip2 > $out || exit 1
|
/nix/bin/nix --dump --file "$path" | bzip2 > $out || exit 1
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ foreach my $id (@ARGV) {
|
||||||
|
|
||||||
# Get all paths referenced by the normalisation of the given
|
# Get all paths referenced by the normalisation of the given
|
||||||
# fstate expression.
|
# fstate expression.
|
||||||
|
system "nix -ih $id";
|
||||||
|
if ($?) { die "`nix -ih' failed"; }
|
||||||
my @paths;
|
my @paths;
|
||||||
open PATHS, "nix -qrh $id 2> /dev/null |" or die "nix -qrh";
|
open PATHS, "nix -qrh $id 2> /dev/null |" or die "nix -qrh";
|
||||||
while (<PATHS>) {
|
while (<PATHS>) {
|
||||||
|
@ -51,6 +53,8 @@ foreach my $id (@ARGV) {
|
||||||
die unless $nid =~ /^([0-9a-z]{32})$/;
|
die unless $nid =~ /^([0-9a-z]{32})$/;
|
||||||
|
|
||||||
# Realise the Nix expression.
|
# Realise the Nix expression.
|
||||||
|
system "nix -ih $nid";
|
||||||
|
if ($?) { die "`nix -ih' failed"; }
|
||||||
my $npath = `nix -qph $nid 2> /dev/null`;
|
my $npath = `nix -qph $nid 2> /dev/null`;
|
||||||
$? and die "creating Nix archive";
|
$? and die "creating Nix archive";
|
||||||
chomp $npath;
|
chomp $npath;
|
||||||
|
|
10
src/nix.cc
10
src/nix.cc
|
@ -216,8 +216,12 @@ struct StdoutSink : DumpSink
|
||||||
virtual void operator ()
|
virtual void operator ()
|
||||||
(const unsigned char * data, unsigned int len)
|
(const unsigned char * data, unsigned int len)
|
||||||
{
|
{
|
||||||
if (write(STDOUT_FILENO, (char *) data, len) != (ssize_t) len)
|
while (len) {
|
||||||
throw SysError("writing to stdout");
|
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) {
|
while (len) {
|
||||||
ssize_t res = read(STDIN_FILENO, (char *) data, len);
|
ssize_t res = read(STDIN_FILENO, (char *) data, len);
|
||||||
if (res == -1) throw SysError("reading from stdin");
|
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;
|
len -= res;
|
||||||
data += res;
|
data += res;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue