Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/fast_io_driver/install_path/bsd.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ inline ::fast_io::install_path get_module_install_path()
char buffer1[PATH_MAX + 1];
char buffer2[PATH_MAX + 1];
char *resolved{};
int length = -1;
// int length = -1;

#if defined(__NetBSD__)
int mib[4]{CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME};
Expand Down
2 changes: 1 addition & 1 deletion include/fast_io_driver/install_path/linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ inline ::fast_io::install_path get_module_install_path()
char buffer[path_max + 1];
::fast_io::install_path ret;

using my_ssize_t = ::std::make_signed_t<::std::size_t>;
using my_ssize_t [[maybe_unused]] = ::std::make_signed_t<::std::size_t>;
#if defined(__linux__) && defined(__NR_readlink)
auto resolved{::fast_io::system_call<__NR_readlink, my_ssize_t>("/proc/self/exe", buffer, path_max)};
system_call_throw_error(resolved);
Expand Down
59 changes: 38 additions & 21 deletions include/fast_io_hosted/filesystem/nt_at.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,35 +56,52 @@ namespace win32::nt::details

inline constexpr nt_open_mode calculate_nt_delete_flag(nt_at_flags flags) noexcept
{
// FILE_DELETE_ON_CLOSE is not used here. Instead, use FILE_DISPOSITION_INFORMATION to control deletion!

// FILE_DELETE_ON_CLOSE schedules deletion at handle close.
// The actual delete operation happens inside NtClose, which does not provide detailed error codes.
// Therefore, you cannot reliably retrieve the actual delete failure reason.

// POSIX requires unlinkat() to always operate in no-follow mode (symlinks are
// unconditionally unlinked as directory entries and never resolved). Therefore,
// we must enforce the same no-follow behavior here.

nt_open_mode mode{
.DesiredAccess = 0x00010000, // FILE_GENERIC_READ
.FileAttributes = 0x80, // FILE_ATTRIBUTE_NORMAL
.ShareAccess = 0x00000007, // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
.CreateDisposition = 0x00000001, /*OPEN_EXISTING => FILE_OPEN*/
.CreateOptions = 0x00001000 /*FILE_DELETE_ON_CLOSE*/
.DesiredAccess = 0x00010000 | 0x00100000, // DELETE | SYNCHRONIZE
.FileAttributes = 0x80, // FILE_ATTRIBUTE_NORMAL
.ShareAccess = 0x00000007, // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
.CreateDisposition = 0x00000001, // OPEN_EXISTING => FILE_OPEN
.CreateOptions = 0x00000020 | 0x00004000 | 0x00200000 // FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_FLAG_OPEN_REPARSE_POINT
};
if ((flags & nt_at_flags::symlink_nofollow) == nt_at_flags::symlink_nofollow)
{
mode.CreateOptions |= 0x00200000; // FILE_FLAG_OPEN_REPARSE_POINT => FILE_OPEN_REPARSE_POINT (0x00200000)
}

if ((flags & nt_at_flags::removedir) == nt_at_flags::removedir)
{
mode.CreateOptions |= 0x00004000; // FILE_OPEN_FOR_BACKUP_INTENT
mode.CreateOptions |= 0x00000001; // FILE_DIRECTORY_FILE
}
else
{
mode.CreateOptions |= 0x00000040; // FILE_NON_DIRECTORY_FILE 0x00000040
mode.CreateOptions |= 0x00000040; // FILE_NON_DIRECTORY_FILE
}

return mode;
}

template <bool zw>
inline void nt_unlinkat_impl(void *dirhd, char16_t const *path_c_str, ::std::size_t path_size, nt_at_flags flags, bool kernel)
{
auto status{nt_close<zw>(
nt_call_determine_kernel_callback(dirhd, path_c_str, path_size, kernel, nt_create_callback<zw>{calculate_nt_delete_flag(flags)}))};
if (status)
::fast_io::basic_nt_family_file<(zw ? nt_family::zw : nt_family::nt), char> file{
nt_call_determine_kernel_callback(dirhd, path_c_str, path_size, kernel, nt_create_callback<zw>{calculate_nt_delete_flag(flags)})};

::fast_io::win32::nt::io_status_block IoStatusBlock; // no initialization needed
::fast_io::win32::nt::file_disposition_information fdi{.DeleteFile = true};

auto status{::fast_io::win32::nt::nt_set_information_file<zw>(file.native_handle(),
__builtin_addressof(IoStatusBlock),
__builtin_addressof(fdi),
sizeof(fdi),
::fast_io::win32::nt::file_information_class::FileDispositionInformation)};

if (status) [[unlikely]]
{
throw_nt_error(status);
}
Expand All @@ -107,7 +124,7 @@ inline void nt_mkdirat_impl(void *dirhd, char16_t const *path_c_str, ::std::size
}

auto status{nt_close<zw>(nt_call_determine_kernel_callback(dirhd, path_c_str, path_size, kernel, nt_create_callback<zw>{m_dir_mode}))};

if (status)
{
throw_nt_error(status);
Expand Down Expand Up @@ -777,10 +794,10 @@ inline ::fast_io::details::basic_ct_string<char_type> nt_readlinkat_impl(void *d
{
#if !defined(_WIN32_WINNT) || _WIN32_WINNT > 0x0600
constexpr ::fast_io::win32::nt::details::nt_open_mode md{
.DesiredAccess = 0x00100000 | 0x0080, // SYNCHRONIZE | FILE_READ_ATTRIBUTES
.FileAttributes = 0x80, // FILE_ATTRIBUTE_NORMAL
.ShareAccess = 0x00000007, // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
.CreateDisposition = 0x00000001, // OPEN_EXISTING => FILE_OPEN
.DesiredAccess = 0x00100000 | 0x0080, // SYNCHRONIZE | FILE_READ_ATTRIBUTES
.FileAttributes = 0x80, // FILE_ATTRIBUTE_NORMAL
.ShareAccess = 0x00000007, // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
.CreateDisposition = 0x00000001, // OPEN_EXISTING => FILE_OPEN
.CreateOptions = 0x00200000 | 0x00000020 // FILE_FLAG_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_NONALERT
};

Expand Down Expand Up @@ -834,7 +851,7 @@ inline ::fast_io::details::basic_ct_string<char_type> nt_readlinkat_impl(void *d
#endif
else
{
throw_nt_error(0xC0000002);
throw_nt_error(0xC0000275u /*STATUS_NOT_A_REPARSE_POINT*/);
}

return {};
Expand All @@ -851,7 +868,7 @@ inline ::fast_io::details::basic_ct_string<char_type> nt_readlinkat_impl(void *d
::fast_io::basic_nt_family_file<(zw ? nt_family::zw : nt_family::nt), char> file{
nt_call_determine_kernel_callback(dirhd, path_c_str, path_size, kernel, nt_create_callback<zw>{md})};

throw_nt_error(0xC0000002);
throw_nt_error(0xC0000275u /*STATUS_NOT_A_REPARSE_POINT*/);

return {};
#endif
Expand Down
13 changes: 9 additions & 4 deletions include/fast_io_hosted/process/process/posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ namespace fast_io

namespace posix
{
// The statement about argu[] and enopl] being constants is included to make explicit to future writers of language bindings that these objects are completely constant.
// Due toa limitation of the ISOC standard, it is not possible to state that idea in standard C. Specifying two levels of const-qualification for the argol] and enopll
// parameters for the exec functions may seem to be the natural choice, given that these functions do not modify either the array of pointers or the characters to which the
// function points, but this would disallow existing correct code. Instead, only the array of pointers is noted as constant.

#if defined(__DARWIN_C_LEVEL) || defined(__MSDOS__)
extern int libc_fexecve(int fd, char *const *argv, char *const *envp) noexcept __asm__("_fexecve");
extern int libc_execveat(int dirfd, char const *pathname, char *const *argv, char *const *envp, int flags) noexcept __asm__("_execveat");
Expand Down Expand Up @@ -130,7 +135,7 @@ namespace details
* - The returned path may differ from original open() argument due to symlinks or namespaces.
*/

inline void portable_fd_path(int fd, char *buf, ::std::size_t bufsz)
inline void portable_fd_path([[maybe_unused]] int fd, char *buf, ::std::size_t bufsz)
{
if (buf == nullptr || bufsz == 0u) [[unlikely]]
{
Expand Down Expand Up @@ -179,7 +184,7 @@ inline void portable_fd_path(int fd, char *buf, ::std::size_t bufsz)
::fast_io::obuffer_view linkpath_ov{linkpath, linkpath + all_sz};
::fast_io::operations::print_freestanding<false>(linkpath_ov, path_str, fd, ::fast_io::mnp::chvw(::fast_io::char_literal_v<u8'\0', char>));

using my_ssize_t = ::std::make_signed_t<::std::size_t>;
using my_ssize_t [[maybe_unused]] = ::std::make_signed_t<::std::size_t>;

#if defined(__linux__) && defined(__NR_readlink)
auto resolved{::fast_io::system_call<__NR_readlink, my_ssize_t>(linkpath, buf, bufsz - 1u)};
Expand Down Expand Up @@ -763,7 +768,7 @@ inline void vfork_and_execveat(pid_t &pid, int dirfd, char const *cstr, char con
flags |= AT_SYMLINK_NOFOLLOW;
}

auto ret{::fast_io::posix::libc_execveat(dirfd, cstr, args, envp, flags)};
auto ret{::fast_io::posix::libc_execveat(dirfd, cstr, const_cast<char *const *>(args), const_cast<char *const *>(envp), flags)};
if (ret == -1)
{
t_errno = errno;
Expand All @@ -786,7 +791,7 @@ inline void vfork_and_execveat(pid_t &pid, int dirfd, char const *cstr, char con
flags |= AT_SYMLINK_NOFOLLOW;
}

auto ret{::fast_io::posix::libc_execveat(dirfd, cstr, args, envp, flags)};
auto ret{::fast_io::posix::libc_execveat(dirfd, cstr, const_cast<char *const *>(args), const_cast<char *const *>(envp), flags)};
if (ret == -1)
{
t_errno = errno;
Expand Down
Loading