Skip to content

Commit

Permalink
io/Open: add TryOpen(struct open_how), Open(struct open_how)
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxKellermann committed Feb 13, 2025
1 parent 5b39305 commit dda85e0
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 1 deletion.
16 changes: 16 additions & 0 deletions src/io/FileAt.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: BSD-2-Clause
// Copyright CM4all GmbH
// author: Max Kellermann <[email protected]>

#pragma once

#include "FileDescriptor.hxx"

/**
* Reference to a file by an anchor directory (which can be an
* `O_PATH` descriptor) and a path name relative to it.
*/
struct FileAt {
FileDescriptor directory;
const char *name;
};
24 changes: 23 additions & 1 deletion src/io/Open.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
#include "UniqueFileDescriptor.hxx"
#include "lib/fmt/SystemError.hxx"

#ifdef __linux__
#include "FileAt.hxx"
#include "system/linux/openat2.h"
#endif

#include <fcntl.h>

UniqueFileDescriptor
Expand Down Expand Up @@ -93,4 +98,21 @@ OpenDirectory(FileDescriptor directory, const char *name, int flags)
return fd;
}

#endif
UniqueFileDescriptor
TryOpen(FileAt file, const struct open_how &how) noexcept
{
int fd = openat2(file.directory.Get(), file.name, &how, sizeof(how));
return UniqueFileDescriptor{AdoptTag{}, fd};
}

UniqueFileDescriptor
Open(FileAt file, const struct open_how &how)
{
auto fd = TryOpen(file, how);
if (!fd.IsDefined())
throw FmtErrno("Failed to open {:?}", file.name);

return fd;
}

#endif // __linux__
21 changes: 21 additions & 0 deletions src/io/Open.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,25 @@ OpenWriteOnly(FileDescriptor directory, const char *name, int flags=0);
UniqueFileDescriptor
OpenDirectory(FileDescriptor directory, const char *name, int flags=0);

struct opwn_how;
struct FileAt;

/**
* Wrapper for openat2() which converts the returned file descriptor
* to a #UniqueFileDescriptor.
*
* Returns an "undefined" instance on error and sets errno.
*/
UniqueFileDescriptor
TryOpen(FileAt file, const struct open_how &how) noexcept;

/**
* Wrapper for openat2() which converts the returned file descriptor
* to a #UniqueFileDescriptor.
*
* Throws on error.
*/
UniqueFileDescriptor
Open(FileAt file, const struct open_how &how);

#endif
17 changes: 17 additions & 0 deletions src/system/linux/openat2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: BSD-2-Clause
// Copyright CM4all GmbH
// author: Max Kellermann <[email protected]>

#pragma once

#include <fcntl.h> // for O_*
#include <linux/openat2.h> // for RESOLVE_*
#include <sys/syscall.h>
#include <unistd.h>

static inline int
openat2(int dirfd, const char *pathname,
const struct open_how *how, size_t size)
{
return syscall(__NR_openat2, dirfd, pathname, how, size);
}

0 comments on commit dda85e0

Please sign in to comment.