libbsd: add closefrom() and close_range()
Change-Id: I9c88948d6c4d5a32e3aa06cd696e2ce24c2d298f Reviewed-on: https://review.haiku-os.org/c/haiku/+/9334 Reviewed-by: waddlesplash <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
396ebbc16f
commit
23f923bcaf
@@ -28,6 +28,9 @@ char *getusershell(void);
|
||||
int issetugid(void);
|
||||
void setusershell(void);
|
||||
|
||||
int closefrom(int lowFd);
|
||||
int close_range(u_int minFd, u_int maxFd, int flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -327,6 +327,8 @@
|
||||
# define SEEK_HOLE 4
|
||||
#endif
|
||||
|
||||
#define CLOSE_RANGE_CLOEXEC 0x4
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -255,6 +255,7 @@ int _user_dup2(int ofd, int nfd, int flags);
|
||||
status_t _user_lock_node(int fd);
|
||||
status_t _user_unlock_node(int fd);
|
||||
status_t _user_preallocate(int fd, off_t offset, off_t length);
|
||||
status_t _user_close_range(u_int minFd, u_int maxFd, int flags);
|
||||
|
||||
/* socket user prototypes (implementation in socket.cpp) */
|
||||
int _user_socket(int family, int type, int protocol);
|
||||
|
||||
@@ -355,6 +355,7 @@ extern status_t _kern_unlock_node(int fd);
|
||||
extern status_t _kern_get_next_fd_info(team_id team, uint32 *_cookie,
|
||||
struct fd_info *info, size_t infoSize);
|
||||
extern status_t _kern_preallocate(int fd, off_t offset, off_t length);
|
||||
extern status_t _kern_close_range(u_int minFd, u_int maxFd, int flags);
|
||||
|
||||
// socket functions
|
||||
extern int _kern_socket(int family, int type, int protocol);
|
||||
|
||||
@@ -44,6 +44,13 @@ static const FlagsTypeHandler::FlagInfo kOpenFlagInfos[] = {
|
||||
};
|
||||
|
||||
|
||||
static const FlagsTypeHandler::FlagInfo kCloseRangeFlagInfos[] = {
|
||||
FLAG_INFO_ENTRY(CLOSE_RANGE_CLOEXEC),
|
||||
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
struct fcntl_info {
|
||||
unsigned int index;
|
||||
const char *name;
|
||||
@@ -69,6 +76,7 @@ static const fcntl_info kFcntls[] = {
|
||||
};
|
||||
|
||||
static FlagsTypeHandler::FlagsList kOpenFlags;
|
||||
static FlagsTypeHandler::FlagsList kCloseRangeFlags;
|
||||
static EnumTypeHandler::EnumMap kFcntlNames;
|
||||
static TypeHandlerSelector::SelectMap kFcntlTypeHandlers;
|
||||
|
||||
@@ -79,6 +87,10 @@ patch_fcntl()
|
||||
kOpenFlags.push_back(kOpenFlagInfos[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; kCloseRangeFlagInfos[i].name != NULL; i++) {
|
||||
kCloseRangeFlags.push_back(kCloseRangeFlagInfos[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; kFcntls[i].name != NULL; i++) {
|
||||
kFcntlNames[kFcntls[i].index] = kFcntls[i].name;
|
||||
if (kFcntls[i].handler != NULL)
|
||||
@@ -90,6 +102,9 @@ patch_fcntl()
|
||||
Syscall *open = get_syscall("_kern_open");
|
||||
open->GetParameter("openMode")->SetHandler(new FlagsTypeHandler(kOpenFlags));
|
||||
|
||||
Syscall *closeRange = get_syscall("_kern_close_range");
|
||||
closeRange->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kCloseRangeFlags));
|
||||
|
||||
Syscall *fcntl = get_syscall("_kern_fcntl");
|
||||
fcntl->GetParameter("op")->SetHandler(new EnumTypeHandler(kFcntlNames));
|
||||
fcntl->GetParameter("argument")->SetHandler(
|
||||
|
||||
@@ -13,6 +13,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
SharedLibrary [ MultiArchDefaultGristFiles libbsd.so ] :
|
||||
arc4random.c
|
||||
arc4random_uniform.c
|
||||
closefrom.cpp
|
||||
daemon.c
|
||||
dl_iterate_phdr.c
|
||||
err.c
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2025, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno_private.h>
|
||||
#include <syscall_utils.h>
|
||||
#include <syscalls.h>
|
||||
|
||||
|
||||
extern "C" int
|
||||
closefrom(int lowFd)
|
||||
{
|
||||
RETURN_AND_SET_ERRNO(_kern_close_range(lowFd, ~0, 0));
|
||||
}
|
||||
|
||||
|
||||
extern "C" int
|
||||
close_range(u_int minFd, u_int maxFd, int flags)
|
||||
{
|
||||
RETURN_AND_SET_ERRNO(_kern_close_range(minFd, maxFd, flags));
|
||||
}
|
||||
|
||||
@@ -857,6 +857,27 @@ common_close(int fd, bool kernel)
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
common_close_range(u_int minFd, u_int maxFd, int flags, bool kernel)
|
||||
{
|
||||
if (maxFd < minFd)
|
||||
return B_BAD_VALUE;
|
||||
struct io_context* context = get_current_io_context(kernel);
|
||||
maxFd = min_c(maxFd, context->table_size - 1);
|
||||
if ((flags & CLOSE_RANGE_CLOEXEC) == 0) {
|
||||
for (u_int fd = minFd; fd <= maxFd; fd++)
|
||||
close_fd_index(context, fd);
|
||||
} else {
|
||||
WriteLocker locker(context->lock);
|
||||
for (u_int fd = minFd; fd <= maxFd; fd++) {
|
||||
if (context->fds[fd] != NULL)
|
||||
fd_set_close_on_exec(context, fd, true);
|
||||
}
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
user_fd_kernel_ioctl(int fd, uint32 op, void* buffer, size_t length)
|
||||
{
|
||||
@@ -1018,6 +1039,15 @@ _user_close(int fd)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_user_close_range(u_int minFd, u_int maxFd, int flags)
|
||||
{
|
||||
if ((flags & ~(CLOSE_RANGE_CLOEXEC)) != 0)
|
||||
return B_BAD_VALUE;
|
||||
return common_close_range(minFd, maxFd, flags, false);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_user_dup(int fd)
|
||||
{
|
||||
@@ -1210,6 +1240,13 @@ _kern_close(int fd)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_kern_close_range(u_int minFd, u_int maxFd, int flags)
|
||||
{
|
||||
return common_close_range(minFd, maxFd, flags, true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_kern_dup(int fd)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user