forked from lix-project/lix
don't allocate large buffers on the stack
This commit is contained in:
parent
3748a0ca1e
commit
c89a3d5368
|
@ -4156,8 +4156,8 @@ void Worker::waitForInput()
|
||||||
set<int> fds2(j->fds);
|
set<int> fds2(j->fds);
|
||||||
for (auto & k : fds2) {
|
for (auto & k : fds2) {
|
||||||
if (FD_ISSET(k, &fds)) {
|
if (FD_ISSET(k, &fds)) {
|
||||||
unsigned char buffer[4096];
|
std::vector<unsigned char> buffer(4096);
|
||||||
ssize_t rd = read(k, buffer, sizeof(buffer));
|
ssize_t rd = read(k, buffer.data(), buffer.size());
|
||||||
if (rd == -1) {
|
if (rd == -1) {
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
throw SysError(format("reading from %1%")
|
throw SysError(format("reading from %1%")
|
||||||
|
@ -4169,7 +4169,7 @@ void Worker::waitForInput()
|
||||||
} else {
|
} else {
|
||||||
printMsg(lvlVomit, format("%1%: read %2% bytes")
|
printMsg(lvlVomit, format("%1%: read %2% bytes")
|
||||||
% goal->getName() % rd);
|
% goal->getName() % rd);
|
||||||
string data((char *) buffer, rd);
|
string data((char *) buffer.data(), rd);
|
||||||
j->lastOutput = after;
|
j->lastOutput = after;
|
||||||
goal->handleChildOutput(k, data);
|
goal->handleChildOutput(k, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,14 +40,14 @@ static void dumpContents(const Path & path, size_t size,
|
||||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
||||||
if (!fd) throw SysError(format("opening file '%1%'") % path);
|
if (!fd) throw SysError(format("opening file '%1%'") % path);
|
||||||
|
|
||||||
unsigned char buf[65536];
|
std::vector<unsigned char> buf(65536);
|
||||||
size_t left = size;
|
size_t left = size;
|
||||||
|
|
||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
size_t n = left > sizeof(buf) ? sizeof(buf) : left;
|
size_t n = left > buf.size() ? buf.size() : left;
|
||||||
readFull(fd.get(), buf, n);
|
readFull(fd.get(), buf.data(), n);
|
||||||
left -= n;
|
left -= n;
|
||||||
sink(buf, n);
|
sink(buf.data(), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
writePadding(size, sink);
|
writePadding(size, sink);
|
||||||
|
@ -146,14 +146,14 @@ static void parseContents(ParseSink & sink, Source & source, const Path & path)
|
||||||
sink.preallocateContents(size);
|
sink.preallocateContents(size);
|
||||||
|
|
||||||
unsigned long long left = size;
|
unsigned long long left = size;
|
||||||
unsigned char buf[65536];
|
std::vector<unsigned char> buf(65536);
|
||||||
|
|
||||||
while (left) {
|
while (left) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
unsigned int n = sizeof(buf);
|
auto n = buf.size();
|
||||||
if ((unsigned long long) n > left) n = left;
|
if ((unsigned long long)n > left) n = left;
|
||||||
source(buf, n);
|
source(buf.data(), n);
|
||||||
sink.receiveContents(buf, n);
|
sink.receiveContents(buf.data(), n);
|
||||||
left -= n;
|
left -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -256,12 +256,12 @@ Hash hashFile(HashType ht, const Path & path)
|
||||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
||||||
if (!fd) throw SysError(format("opening file '%1%'") % path);
|
if (!fd) throw SysError(format("opening file '%1%'") % path);
|
||||||
|
|
||||||
unsigned char buf[8192];
|
std::vector<unsigned char> buf(8192);
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
while ((n = read(fd.get(), buf, sizeof(buf)))) {
|
while ((n = read(fd.get(), buf.data(), buf.size()))) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
if (n == -1) throw SysError(format("reading file '%1%'") % path);
|
if (n == -1) throw SysError(format("reading file '%1%'") % path);
|
||||||
update(ht, ctx, buf, n);
|
update(ht, ctx, buf.data(), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
finish(ht, ctx, hash.hash);
|
finish(ht, ctx, hash.hash);
|
||||||
|
|
|
@ -229,16 +229,17 @@ bool pathExists(const Path & path)
|
||||||
Path readLink(const Path & path)
|
Path readLink(const Path & path)
|
||||||
{
|
{
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
std::vector<char> buf;
|
||||||
for (ssize_t bufSize = PATH_MAX/4; true; bufSize += bufSize/2) {
|
for (ssize_t bufSize = PATH_MAX/4; true; bufSize += bufSize/2) {
|
||||||
char buf[bufSize];
|
buf.resize(bufSize);
|
||||||
ssize_t rlSize = readlink(path.c_str(), buf, bufSize);
|
ssize_t rlSize = readlink(path.c_str(), buf.data(), bufSize);
|
||||||
if (rlSize == -1)
|
if (rlSize == -1)
|
||||||
if (errno == EINVAL)
|
if (errno == EINVAL)
|
||||||
throw Error("'%1%' is not a symlink", path);
|
throw Error("'%1%' is not a symlink", path);
|
||||||
else
|
else
|
||||||
throw SysError("reading symbolic link '%1%'", path);
|
throw SysError("reading symbolic link '%1%'", path);
|
||||||
else if (rlSize < bufSize)
|
else if (rlSize < bufSize)
|
||||||
return string(buf, rlSize);
|
return string(buf.data(), rlSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,10 +294,10 @@ string readFile(int fd)
|
||||||
if (fstat(fd, &st) == -1)
|
if (fstat(fd, &st) == -1)
|
||||||
throw SysError("statting file");
|
throw SysError("statting file");
|
||||||
|
|
||||||
auto buf = std::make_unique<unsigned char[]>(st.st_size);
|
std::vector<unsigned char> buf(st.st_size);
|
||||||
readFull(fd, buf.get(), st.st_size);
|
readFull(fd, buf.data(), st.st_size);
|
||||||
|
|
||||||
return string((char *) buf.get(), st.st_size);
|
return string((char *) buf.data(), st.st_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -438,10 +439,10 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix,
|
||||||
static Lazy<Path> getHome2([]() {
|
static Lazy<Path> getHome2([]() {
|
||||||
Path homeDir = getEnv("HOME");
|
Path homeDir = getEnv("HOME");
|
||||||
if (homeDir.empty()) {
|
if (homeDir.empty()) {
|
||||||
char buf[16384];
|
std::vector<char> buf(16384);
|
||||||
struct passwd pwbuf;
|
struct passwd pwbuf;
|
||||||
struct passwd * pw;
|
struct passwd * pw;
|
||||||
if (getpwuid_r(getuid(), &pwbuf, buf, sizeof(buf), &pw) != 0
|
if (getpwuid_r(getuid(), &pwbuf, buf.data(), buf.size(), &pw) != 0
|
||||||
|| !pw || !pw->pw_dir || !pw->pw_dir[0])
|
|| !pw || !pw->pw_dir || !pw->pw_dir[0])
|
||||||
throw Error("cannot determine user's home directory");
|
throw Error("cannot determine user's home directory");
|
||||||
homeDir = pw->pw_dir;
|
homeDir = pw->pw_dir;
|
||||||
|
@ -569,16 +570,16 @@ void writeFull(int fd, const string & s, bool allowInterrupts)
|
||||||
string drainFD(int fd)
|
string drainFD(int fd)
|
||||||
{
|
{
|
||||||
string result;
|
string result;
|
||||||
unsigned char buffer[4096];
|
std::vector<unsigned char> buffer(4096);
|
||||||
while (1) {
|
while (1) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
ssize_t rd = read(fd, buffer, sizeof buffer);
|
ssize_t rd = read(fd, buffer.data(), buffer.size());
|
||||||
if (rd == -1) {
|
if (rd == -1) {
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
throw SysError("reading from file");
|
throw SysError("reading from file");
|
||||||
}
|
}
|
||||||
else if (rd == 0) break;
|
else if (rd == 0) break;
|
||||||
else result.append((char *) buffer, rd);
|
else result.append((char *) buffer.data(), rd);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,13 +37,13 @@ using namespace nix;
|
||||||
static ssize_t splice(int fd_in, void *off_in, int fd_out, void *off_out, size_t len, unsigned int flags)
|
static ssize_t splice(int fd_in, void *off_in, int fd_out, void *off_out, size_t len, unsigned int flags)
|
||||||
{
|
{
|
||||||
/* We ignore most parameters, we just have them for conformance with the linux syscall */
|
/* We ignore most parameters, we just have them for conformance with the linux syscall */
|
||||||
char buf[8192];
|
std::vector<char> buf(8192);
|
||||||
auto read_count = read(fd_in, buf, sizeof(buf));
|
auto read_count = read(fd_in, buf.data(), buf.size());
|
||||||
if (read_count == -1)
|
if (read_count == -1)
|
||||||
return read_count;
|
return read_count;
|
||||||
auto write_count = decltype(read_count)(0);
|
auto write_count = decltype(read_count)(0);
|
||||||
while (write_count < read_count) {
|
while (write_count < read_count) {
|
||||||
auto res = write(fd_out, buf + write_count, read_count - write_count);
|
auto res = write(fd_out, buf.data() + write_count, read_count - write_count);
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
return res;
|
return res;
|
||||||
write_count += res;
|
write_count += res;
|
||||||
|
|
Loading…
Reference in a new issue