io/Open: add TryOpen(struct open_how), Open(struct open_how)
This commit is contained in:
parent
5b393052ee
commit
dda85e02bf
src
16
src/io/FileAt.hxx
Normal file
16
src/io/FileAt.hxx
Normal file
@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
// Copyright CM4all GmbH
|
||||
// author: Max Kellermann <mk@cm4all.com>
|
||||
|
||||
#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;
|
||||
};
|
@ -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
|
||||
@ -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__
|
||||
|
@ -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
src/system/linux/openat2.h
Normal file
17
src/system/linux/openat2.h
Normal file
@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
// Copyright CM4all GmbH
|
||||
// author: Max Kellermann <mk@cm4all.com>
|
||||
|
||||
#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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user