Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Turn Descriptor into a struct, hiding the CPP #10616

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/libstore/remote-fs-accessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ std::pair<ref<SourceAccessor>, CanonPath> RemoteFSAccessor::fetch(const CanonPat
auto narAccessor = makeLazyNarAccessor(listing,
[cacheFile](uint64_t offset, uint64_t length) {

AutoCloseFD fd = toDescriptor(open(cacheFile.c_str(), O_RDONLY
AutoCloseFD fd = Descriptor::fromFileDescriptor(open(cacheFile.c_str(), O_RDONLY
#ifndef _WIN32
| O_CLOEXEC
#endif
));
if (!fd)
throw SysError("opening NAR cache file '%s'", cacheFile);

if (lseek(fromDescriptorReadOnly(fd.get()), offset, SEEK_SET) != (off_t) offset)
if (lseek(toFileDescriptorReadOnly(fd.get()), offset, SEEK_SET) != (off_t) offset)
throw SysError("seeking in '%s'", cacheFile);

std::string buf(length, 0);
Expand Down
8 changes: 4 additions & 4 deletions src/libstore/ssh.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(
}, options);


in.readSide = INVALID_DESCRIPTOR;
out.writeSide = INVALID_DESCRIPTOR;
in.readSide = Descriptor::invalid;
out.writeSide = Descriptor::invalid;

// Wait for the SSH connection to be established,
// So that we don't overwrite the password prompt with our progress bar.
Expand Down Expand Up @@ -140,7 +140,7 @@ Path SSHMaster::startMaster()

auto state(state_.lock());

if (state->sshMaster != INVALID_DESCRIPTOR) return state->socketPath;
if (state->sshMaster != Descriptor::invalid) return state->socketPath;

state->socketPath = (Path) *state->tmpDir + "/ssh.sock";

Expand Down Expand Up @@ -173,7 +173,7 @@ Path SSHMaster::startMaster()
throw SysError("unable to execute '%s'", args.front());
}, options);

out.writeSide = INVALID_DESCRIPTOR;
out.writeSide = Descriptor::invalid;

std::string reply;
try {
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/windows/pathlocks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ bool PathLocks::lockPaths(const PathSet & paths, const std::string & waitMsg, bo
debug("lock aquired on '%1%'", lockPath);

struct _stat st;
if (_fstat(fromDescriptorReadOnly(fd.get()), &st) == -1)
if (_fstat(toFileDescriptorReadOnly(fd.get()), &st) == -1)
throw SysError("statting lock file '%1%'", lockPath);
if (st.st_size != 0)
debug("open lock file '%1%' has become stale", lockPath);
Expand Down
16 changes: 8 additions & 8 deletions src/libutil/file-descriptor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,23 @@ std::string drainFD(Descriptor fd, bool block, const size_t reserveSize)
//////////////////////////////////////////////////////////////////////


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


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


AutoCloseFD::AutoCloseFD(AutoCloseFD && that) : fd{that.fd}
{
that.fd = INVALID_DESCRIPTOR;
that.fd = Descriptor::invalid;
}


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

Expand All @@ -78,7 +78,7 @@ Descriptor AutoCloseFD::get() const

void AutoCloseFD::close()
{
if (fd != INVALID_DESCRIPTOR) {
if (fd != Descriptor::invalid) {
if(
#ifdef _WIN32
::CloseHandle(fd)
Expand All @@ -88,13 +88,13 @@ void AutoCloseFD::close()
== -1)
/* This should never happen. */
throw NativeSysError("closing file descriptor %1%", fd);
fd = INVALID_DESCRIPTOR;
fd = Descriptor::invalid;
}
}

void AutoCloseFD::fsync()
{
if (fd != INVALID_DESCRIPTOR) {
if (fd != Descriptor::invalid) {
int result;
result =
#ifdef _WIN32
Expand All @@ -113,14 +113,14 @@ void AutoCloseFD::fsync()

AutoCloseFD::operator bool() const
{
return fd != INVALID_DESCRIPTOR;
return fd != Descriptor::invalid;
}


Descriptor AutoCloseFD::release()
{
Descriptor oldFD = fd;
fd = INVALID_DESCRIPTOR;
fd = Descriptor::invalid;
return oldFD;
}

Expand Down
89 changes: 56 additions & 33 deletions src/libutil/file-descriptor.hh
Original file line number Diff line number Diff line change
Expand Up @@ -17,50 +17,70 @@ struct Source;
/**
* Operating System capability
*/
using Descriptor =
struct Descriptor {

/**
* Underlying operating-system-specific type
*/
#if _WIN32
HANDLE
#else
int
#endif
;

const Descriptor INVALID_DESCRIPTOR =
#if _WIN32
INVALID_HANDLE_VALUE
raw;

auto operator<=>(const Descriptor &) const = default;

/**
* A descriptor that is always invalid, regardless of the state of
* opened resources. It is useful as a [sentinel
* value](https://en.wikipedia.org/wiki/Sentinel_value).
*/
const static Descriptor invalid;

/**
* Convert a native `Descriptor` to a POSIX file descriptor
*
* This is a no-op except on Windows.
*/
[[gnu::always_inline]]
static inline Descriptor fromFileDescriptor(int fd)
{
return {
.raw =
#ifdef _WIN32
reinterpret_cast<HANDLE>(_get_osfhandle(fd.raw));
#else
-1
fd
#endif
;

/**
* Convert a native `Descriptor` to a POSIX file descriptor
*
* This is a no-op except on Windows.
*/
static inline Descriptor toDescriptor(int fd)
{
};
}

/**
* Convert a POSIX file descriptor to a native `Descriptor` in read-only
* mode.
*
* This is a no-op except on Windows.
*/
[[gnu::always_inline]]
inline int toFileDescriptorReadOnly()
{
#ifdef _WIN32
return reinterpret_cast<HANDLE>(_get_osfhandle(fd));
return _open_osfhandle(reinterpret_cast<intptr_t>(raw), _O_RDONLY);
#else
return fd;
return raw;
#endif
}
}
};

/**
* Convert a POSIX file descriptor to a native `Descriptor` in read-only
* mode.
*
* This is a no-op except on Windows.
*/
static inline int fromDescriptorReadOnly(Descriptor fd)
{
#ifdef _WIN32
return _open_osfhandle(reinterpret_cast<intptr_t>(fd), _O_RDONLY);
constexpr Descriptor Descriptor::invalid = {
.raw =
#if _WIN32
INVALID_HANDLE_VALUE
#else
return fd;
-1
#endif
}
};

/**
* Read the contents of a resource into a string.
Expand Down Expand Up @@ -103,11 +123,14 @@ void drainFD(

[[gnu::always_inline]]
inline Descriptor getStandardOut() {
return {
.raw =
#ifndef _WIN32
return STDOUT_FILENO;
STDOUT_FILENO
#else
return GetStdHandle(STD_OUTPUT_HANDLE);
GetStdHandle(STD_OUTPUT_HANDLE)
#endif
};
}

/**
Expand Down
14 changes: 7 additions & 7 deletions src/libutil/file-system.cc
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ unsigned char getFileType(const Path & path)

std::string readFile(const Path & path)
{
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_RDONLY
AutoCloseFD fd = Descriptor::fromFileDescriptor(open(path.c_str(), O_RDONLY
// TODO
#ifndef _WIN32
| O_CLOEXEC
Expand All @@ -302,7 +302,7 @@ std::string readFile(const Path & path)

void readFile(const Path & path, Sink & sink)
{
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_RDONLY
AutoCloseFD fd = Descriptor::fromFileDescriptor(open(path.c_str(), O_RDONLY
// TODO
#ifndef _WIN32
| O_CLOEXEC
Expand All @@ -316,7 +316,7 @@ void readFile(const Path & path, Sink & sink)

void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
{
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
AutoCloseFD fd = Descriptor::fromFileDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
// TODO
#ifndef _WIN32
| O_CLOEXEC
Expand All @@ -341,7 +341,7 @@ void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)

void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
{
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
AutoCloseFD fd = Descriptor::fromFileDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
// TODO
#ifndef _WIN32
| O_CLOEXEC
Expand Down Expand Up @@ -373,7 +373,7 @@ void writeFile(const Path & path, Source & source, mode_t mode, bool sync)

void syncParent(const Path & path)
{
AutoCloseFD fd = toDescriptor(open(dirOf(path).c_str(), O_RDONLY, 0));
AutoCloseFD fd = Descriptor::fromFileDescriptor(open(dirOf(path).c_str(), O_RDONLY, 0));
if (!fd)
throw SysError("opening file '%1%'", path);
fd.fsync();
Expand Down Expand Up @@ -453,7 +453,7 @@ static void _deletePath(const Path & path, uint64_t & bytesFreed)
if (dir == "")
dir = "/";

AutoCloseFD dirfd = toDescriptor(open(dir.c_str(), O_RDONLY));
AutoCloseFD dirfd = Descriptor::fromFileDescriptor(open(dir.c_str(), O_RDONLY));
if (!dirfd) {
if (errno == ENOENT) return;
throw SysError("opening directory '%1%'", path);
Expand Down Expand Up @@ -600,7 +600,7 @@ std::pair<AutoCloseFD, Path> createTempFile(const Path & prefix)
Path tmpl(defaultTempDir() + "/" + prefix + ".XXXXXX");
// Strictly speaking, this is UB, but who cares...
// FIXME: use O_TMPFILE.
AutoCloseFD fd = toDescriptor(mkstemp((char *) tmpl.c_str()));
AutoCloseFD fd = Descriptor::fromFileDescriptor(mkstemp((char *) tmpl.c_str()));
if (!fd)
throw SysError("creating temporary file '%s'", tmpl);
#ifndef _WIN32
Expand Down
6 changes: 3 additions & 3 deletions src/libutil/posix-source-accessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void PosixSourceAccessor::readFile(

auto ap = makeAbsPath(path);

AutoCloseFD fd = toDescriptor(open(ap.string().c_str(), O_RDONLY
AutoCloseFD fd = Descriptor::fromFileDescriptor(open(ap.string().c_str(), O_RDONLY
#ifndef _WIN32
| O_NOFOLLOW | O_CLOEXEC
#endif
Expand All @@ -56,7 +56,7 @@ void PosixSourceAccessor::readFile(
throw SysError("opening file '%1%'", ap.string());

struct stat st;
if (fstat(fromDescriptorReadOnly(fd.get()), &st) == -1)
if (fstat(toFileDescriptorReadOnly(fd.get()), &st) == -1)
throw SysError("statting file");

sizeCallback(st.st_size);
Expand All @@ -66,7 +66,7 @@ void PosixSourceAccessor::readFile(
std::array<unsigned char, 64 * 1024> buf;
while (left) {
checkInterrupt();
ssize_t rd = read(fromDescriptorReadOnly(fd.get()), buf.data(), (size_t) std::min(left, (off_t) buf.size()));
ssize_t rd = read(toFileDescriptorReadOnly(fd.get()), buf.data(), (size_t) std::min(left, (off_t) buf.size()));
if (rd == -1) {
if (errno != EINTR)
throw SysError("reading from file '%s'", showPath(path));
Expand Down
8 changes: 4 additions & 4 deletions src/libutil/serialise.hh
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,15 @@ struct FdSink : BufferedSink
Descriptor fd;
size_t written = 0;

FdSink() : fd(INVALID_DESCRIPTOR) { }
FdSink() : fd(Descriptor::invalid) { }
FdSink(Descriptor fd) : fd(fd) { }
FdSink(FdSink&&) = default;

FdSink & operator=(FdSink && s)
{
flush();
fd = s.fd;
s.fd = INVALID_DESCRIPTOR;
s.fd = Descriptor::invalid;
written = s.written;
return *this;
}
Expand All @@ -155,14 +155,14 @@ struct FdSource : BufferedSource
size_t read = 0;
BackedStringView endOfFileError{"unexpected end-of-file"};

FdSource() : fd(INVALID_DESCRIPTOR) { }
FdSource() : fd(Descriptor::invalid) { }
FdSource(Descriptor fd) : fd(fd) { }
FdSource(FdSource &&) = default;

FdSource & operator=(FdSource && s)
{
fd = s.fd;
s.fd = INVALID_DESCRIPTOR;
s.fd = Descriptor::invalid;
read = s.read;
return *this;
}
Expand Down
2 changes: 1 addition & 1 deletion src/nix/prefetch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ std::tuple<StorePath, Hash> prefetchFile(
if (executable)
mode = 0700;

AutoCloseFD fd = toDescriptor(open(tmpFile.c_str(), O_WRONLY | O_CREAT | O_EXCL, mode));
AutoCloseFD fd = Descriptor::fromFileDescriptor(open(tmpFile.c_str(), O_WRONLY | O_CREAT | O_EXCL, mode));
if (!fd) throw SysError("creating temporary file '%s'", tmpFile);

FdSink sink(fd.get());
Expand Down