don't allocate large buffers on the stack
This commit is contained in:
		
							parent
							
								
									3748a0ca1e
								
							
						
					
					
						commit
						c89a3d5368
					
				
					 5 changed files with 30 additions and 29 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue