Skip to content

Commit

Permalink
Start factoring out Unix assumptions
Browse files Browse the repository at this point in the history
This splits files and adds new identifiers in preperation for supporting
windows, but no Windows-specific code is actually added yet.
  • Loading branch information
Ericson2314 committed Mar 31, 2024
1 parent c54ce09 commit f42eca1
Show file tree
Hide file tree
Showing 34 changed files with 356 additions and 296 deletions.
File renamed without changes.
File renamed without changes.
26 changes: 13 additions & 13 deletions src/libstore/build/local-derivation-goal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "cgroup.hh"
#include "personality.hh"
#include "current-process.hh"
#include "namespaces.hh"
#include "child.hh"
#include "unix-domain-socket.hh"
#include "posix-fs-canonicalise.hh"
Expand All @@ -40,18 +39,19 @@

/* Includes required for chroot support. */
#if __linux__
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <sys/mman.h>
#include <sched.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#if HAVE_SECCOMP
#include <seccomp.h>
#endif
#define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old))
# include <sys/ioctl.h>
# include <net/if.h>
# include <netinet/ip.h>
# include <sys/mman.h>
# include <sched.h>
# include <sys/param.h>
# include <sys/mount.h>
# include <sys/syscall.h>
# include "namespaces.hh"
# if HAVE_SECCOMP
# include <seccomp.h>
# endif
# define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old))
#endif

#if __APPLE__
Expand Down
7 changes: 6 additions & 1 deletion src/libstore/filetransfer.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "filetransfer.hh"
#include "namespaces.hh"
#include "globals.hh"
#include "store-api.hh"
#include "s3.hh"
Expand All @@ -12,6 +11,10 @@
#include <aws/core/client/ClientConfiguration.h>
#endif

#if __linux__
# include "namespaces.hh"
#endif

#include <unistd.h>
#include <fcntl.h>

Expand Down Expand Up @@ -568,7 +571,9 @@ struct curlFileTransfer : public FileTransfer
stopWorkerThread();
});

#if __linux__
unshareFilesystem();
#endif

std::map<CURL *, std::shared_ptr<TransferItem>> items;

Expand Down
4 changes: 3 additions & 1 deletion src/libutil/current-process.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include <cstring>

#include "current-process.hh"
#include "namespaces.hh"
#include "util.hh"
#include "finally.hh"
#include "file-system.hh"
Expand All @@ -17,6 +16,7 @@
# include <mutex>
# include <sys/resource.h>
# include "cgroup.hh"
# include "namespaces.hh"
#endif

#include <sys/mount.h>
Expand Down Expand Up @@ -84,7 +84,9 @@ void restoreProcessContext(bool restoreMounts)
{
restoreSignals();
if (restoreMounts) {
#if __linux__
restoreMountNamespace();
#endif
}

if (savedStackSize) {
Expand Down
14 changes: 0 additions & 14 deletions src/libutil/environment-variables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,4 @@ std::map<std::string, std::string> getEnv()
return env;
}


void clearEnv()
{
for (auto & name : getEnv())
unsetenv(name.first.c_str());
}

void replaceEnv(const std::map<std::string, std::string> & newEnv)
{
clearEnv();
for (auto & newEnvVar : newEnv)
setenv(newEnvVar.first.c_str(), newEnvVar.second.c_str(), 1);
}

}
186 changes: 25 additions & 161 deletions src/libutil/file-descriptor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,74 +8,14 @@

namespace nix {

std::string readFile(int fd)
{
struct stat st;
if (fstat(fd, &st) == -1)
throw SysError("statting file");

return drainFD(fd, true, st.st_size);
}


void readFull(int fd, char * buf, size_t count)
{
while (count) {
checkInterrupt();
ssize_t res = read(fd, buf, count);
if (res == -1) {
if (errno == EINTR) continue;
throw SysError("reading from file");
}
if (res == 0) throw EndOfFile("unexpected end-of-file");
count -= res;
buf += res;
}
}


void writeFull(int fd, std::string_view s, bool allowInterrupts)
{
while (!s.empty()) {
if (allowInterrupts) checkInterrupt();
ssize_t res = write(fd, s.data(), s.size());
if (res == -1 && errno != EINTR)
throw SysError("writing to file");
if (res > 0)
s.remove_prefix(res);
}
}


std::string readLine(int fd)
{
std::string s;
while (1) {
checkInterrupt();
char ch;
// FIXME: inefficient
ssize_t rd = read(fd, &ch, 1);
if (rd == -1) {
if (errno != EINTR)
throw SysError("reading a line");
} else if (rd == 0)
throw EndOfFile("unexpected EOF reading a line");
else {
if (ch == '\n') return s;
s += ch;
}
}
}


void writeLine(int fd, std::string s)
void writeLine(Descriptor fd, std::string s)
{
s += '\n';
writeFull(fd, s);
}


std::string drainFD(int fd, bool block, const size_t reserveSize)
std::string drainFD(Descriptor fd, bool block, const size_t reserveSize)
{
// the parser needs two extra bytes to append terminating characters, other users will
// not care very much about the extra memory.
Expand All @@ -85,58 +25,26 @@ std::string drainFD(int fd, bool block, const size_t reserveSize)
}


void drainFD(int fd, Sink & sink, bool block)
{
// silence GCC maybe-uninitialized warning in finally
int saved = 0;

if (!block) {
saved = fcntl(fd, F_GETFL);
if (fcntl(fd, F_SETFL, saved | O_NONBLOCK) == -1)
throw SysError("making file descriptor non-blocking");
}

Finally finally([&] {
if (!block) {
if (fcntl(fd, F_SETFL, saved) == -1)
throw SysError("making file descriptor blocking");
}
});

std::vector<unsigned char> buf(64 * 1024);
while (1) {
checkInterrupt();
ssize_t rd = read(fd, buf.data(), buf.size());
if (rd == -1) {
if (!block && (errno == EAGAIN || errno == EWOULDBLOCK))
break;
if (errno != EINTR)
throw SysError("reading from file");
}
else if (rd == 0) break;
else sink({reinterpret_cast<char *>(buf.data()), size_t(rd)});
}
}

//////////////////////////////////////////////////////////////////////

AutoCloseFD::AutoCloseFD() : fd{-1} {}

AutoCloseFD::AutoCloseFD() : fd{INVALID_DESCRIPTOR} {}

AutoCloseFD::AutoCloseFD(int fd) : fd{fd} {}

AutoCloseFD::AutoCloseFD(Descriptor fd) : fd{fd} {}


AutoCloseFD::AutoCloseFD(AutoCloseFD && that) : fd{that.fd}
{
that.fd = -1;
that.fd = INVALID_DESCRIPTOR;
}


AutoCloseFD & AutoCloseFD::operator =(AutoCloseFD && that)
{
close();
fd = that.fd;
that.fd = -1;
that.fd = INVALID_DESCRIPTOR;
return *this;
}

Expand All @@ -151,64 +59,54 @@ AutoCloseFD::~AutoCloseFD()
}


int AutoCloseFD::get() const
Descriptor AutoCloseFD::get() const
{
return fd;
}


void AutoCloseFD::close()
{
if (fd != -1) {
if (::close(fd) == -1)
if (fd != INVALID_DESCRIPTOR) {
if(::close(fd) == -1)
/* This should never happen. */
throw SysError("closing file descriptor %1%", fd);
fd = -1;
fd = INVALID_DESCRIPTOR;
}
}

void AutoCloseFD::fsync()
{
if (fd != -1) {
int result;
if (fd != INVALID_DESCRIPTOR) {
int result;
result =
#if __APPLE__
result = ::fcntl(fd, F_FULLFSYNC);
::fcntl(fd, F_FULLFSYNC)
#else
result = ::fsync(fd);
::fsync(fd)
#endif
if (result == -1)
throw SysError("fsync file descriptor %1%", fd);
}
;
if (result == -1)
throw SysError("fsync file descriptor %1%", fd);
}
}


AutoCloseFD::operator bool() const
{
return fd != -1;
return fd != INVALID_DESCRIPTOR;
}


int AutoCloseFD::release()
Descriptor AutoCloseFD::release()
{
int oldFD = fd;
fd = -1;
Descriptor oldFD = fd;
fd = INVALID_DESCRIPTOR;
return oldFD;
}


void Pipe::create()
{
int fds[2];
#if HAVE_PIPE2
if (pipe2(fds, O_CLOEXEC) != 0) throw SysError("creating pipe");
#else
if (pipe(fds) != 0) throw SysError("creating pipe");
closeOnExec(fds[0]);
closeOnExec(fds[1]);
#endif
readSide = fds[0];
writeSide = fds[1];
}
//////////////////////////////////////////////////////////////////////


void Pipe::close()
Expand All @@ -217,38 +115,4 @@ void Pipe::close()
writeSide.close();
}

//////////////////////////////////////////////////////////////////////

void closeMostFDs(const std::set<int> & exceptions)
{
#if __linux__
try {
for (auto & s : readDirectory("/proc/self/fd")) {
auto fd = std::stoi(s.name);
if (!exceptions.count(fd)) {
debug("closing leaked FD %d", fd);
close(fd);
}
}
return;
} catch (SystemError &) {
}
#endif

int maxFD = 0;
maxFD = sysconf(_SC_OPEN_MAX);
for (int fd = 0; fd < maxFD; ++fd)
if (!exceptions.count(fd))
close(fd); /* ignore result */
}


void closeOnExec(int fd)
{
int prev;
if ((prev = fcntl(fd, F_GETFD, 0)) == -1 ||
fcntl(fd, F_SETFD, prev | FD_CLOEXEC) == -1)
throw SysError("setting close-on-exec flag");
}

}
Loading

0 comments on commit f42eca1

Please sign in to comment.