* Argh, another short-write problem. Added wrappers around
read()/write() to fix this once and for all.
This commit is contained in:
parent
667a6afb9d
commit
7984cfc7c1
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
17
src/nix.cc
17
src/nix.cc
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
11
src/store.cc
11
src/store.cc
|
@ -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");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
11
src/test.cc
11
src/test.cc
|
@ -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");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
23
src/util.cc
23
src/util.cc
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue