* Argh, another short-write problem. Added wrappers around

read()/write() to fix this once and for all.
This commit is contained in:
Eelco Dolstra 2003-07-20 21:11:43 +00:00
parent 667a6afb9d
commit 7984cfc7c1
9 changed files with 46 additions and 36 deletions

View file

@ -15,6 +15,9 @@ $hash || die "no package hash specified";
my $linkdir = "@localstatedir@/nix/links"; my $linkdir = "@localstatedir@/nix/links";
# Build the specified package, and all its dependencies. # Build the specified package, and all its dependencies.
system "nix -ih $hash";
if ($?) { die "`nix -ih' failed"; }
my $pkgdir = `nix -qph $hash`; my $pkgdir = `nix -qph $hash`;
if ($?) { die "`nix -qph' failed"; } if ($?) { die "`nix -qph' failed"; }
chomp $pkgdir; chomp $pkgdir;

View file

@ -190,7 +190,7 @@ static string readString(RestoreSource & source)
{ {
unsigned int len = readInt(source); unsigned int len = readInt(source);
char buf[len]; char buf[len];
source((const unsigned char *) buf, len); source((unsigned char *) buf, len);
readPadding(len, source); readPadding(len, source);
return string(buf, len); return string(buf, len);
} }

View file

@ -54,7 +54,7 @@ struct RestoreSource
pointed to by data. It should block if that much data is not 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 yet available, or throw an error if it is not going to be
available. */ 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); void restorePath(const string & path, RestoreSource & source);

View file

@ -215,12 +215,7 @@ struct StdoutSink : DumpSink
virtual void operator () virtual void operator ()
(const unsigned char * data, unsigned int len) (const unsigned char * data, unsigned int len)
{ {
while (len) { writeFull(STDOUT_FILENO, data, len);
ssize_t res = write(STDOUT_FILENO, (char *) data, len);
if (res == -1) throw SysError("writing to stdout");
len -= res;
data += res;
}
} }
}; };
@ -247,15 +242,9 @@ static void opDump(Strings opFlags, Strings opArgs)
/* A source that read restore intput to stdin. */ /* A source that read restore intput to stdin. */
struct StdinSource : RestoreSource struct StdinSource : RestoreSource
{ {
virtual void operator () (const unsigned char * data, unsigned int len) virtual void operator () (unsigned char * data, unsigned int len)
{ {
while (len) { readFull(STDIN_FILENO, data, 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;
}
} }
}; };

View file

@ -55,12 +55,11 @@ void checkPath(const string & path,
int fd = open(path.c_str(), O_RDONLY); int fd = open(path.c_str(), O_RDONLY);
if (fd == -1) throw SysError(format("opening file `%1%'") % path); 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) readFull(fd, buf, st.st_size);
throw SysError(format("reading file %1%") % path);
search(string(buf, st.st_size), ids, seen); search(string((char *) buf, st.st_size), ids, seen);
delete buf; /* !!! autodelete */ delete buf; /* !!! autodelete */

View file

@ -15,8 +15,7 @@ struct CopySink : DumpSink
int fd; int fd;
virtual void operator () (const unsigned char * data, unsigned int len) virtual void operator () (const unsigned char * data, unsigned int len)
{ {
if (write(fd, (char *) data, len) != (ssize_t) len) writeFull(fd, data, len);
throw SysError("writing to child");
} }
}; };
@ -24,13 +23,9 @@ struct CopySink : DumpSink
struct CopySource : RestoreSource struct CopySource : RestoreSource
{ {
int fd; 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); readFull(fd, data, len);
if (res == -1)
throw SysError("reading from parent");
if (res != (ssize_t) len)
throw Error("not enough data available on parent");
} }
}; };

View file

@ -37,21 +37,16 @@ struct MySink : DumpSink
virtual void operator () (const unsigned char * data, unsigned int len) virtual void operator () (const unsigned char * data, unsigned int len)
{ {
/* Don't use cout, it's slow as hell! */ /* Don't use cout, it's slow as hell! */
if (write(STDOUT_FILENO, (char *) data, len) != (ssize_t) len) writeFull(STDOUT_FILENO, data, len);
throw SysError("writing to stdout");
} }
}; };
struct MySource : RestoreSource 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); readFull(STDIN_FILENO, data, len);
if (res == -1)
throw SysError("reading from stdin");
if (res != (ssize_t) len)
throw Error("not enough data available on stdin");
} }
}; };

View file

@ -159,3 +159,26 @@ void debug(const format & f)
{ {
msg(format("debug: %1%") % f.str()); 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;
}
}

View file

@ -85,4 +85,10 @@ void msg(const format & f);
void debug(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 */ #endif /* !__UTIL_H */