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);
|
int issetugid(void);
|
||||||
void setusershell(void);
|
void setusershell(void);
|
||||||
|
|
||||||
|
int closefrom(int lowFd);
|
||||||
|
int close_range(u_int minFd, u_int maxFd, int flags);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -327,6 +327,8 @@
|
|||||||
# define SEEK_HOLE 4
|
# define SEEK_HOLE 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CLOSE_RANGE_CLOEXEC 0x4
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
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_lock_node(int fd);
|
||||||
status_t _user_unlock_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_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) */
|
/* socket user prototypes (implementation in socket.cpp) */
|
||||||
int _user_socket(int family, int type, int protocol);
|
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,
|
extern status_t _kern_get_next_fd_info(team_id team, uint32 *_cookie,
|
||||||
struct fd_info *info, size_t infoSize);
|
struct fd_info *info, size_t infoSize);
|
||||||
extern status_t _kern_preallocate(int fd, off_t offset, off_t length);
|
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
|
// socket functions
|
||||||
extern int _kern_socket(int family, int type, int protocol);
|
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 {
|
struct fcntl_info {
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
const char *name;
|
const char *name;
|
||||||
@@ -69,6 +76,7 @@ static const fcntl_info kFcntls[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static FlagsTypeHandler::FlagsList kOpenFlags;
|
static FlagsTypeHandler::FlagsList kOpenFlags;
|
||||||
|
static FlagsTypeHandler::FlagsList kCloseRangeFlags;
|
||||||
static EnumTypeHandler::EnumMap kFcntlNames;
|
static EnumTypeHandler::EnumMap kFcntlNames;
|
||||||
static TypeHandlerSelector::SelectMap kFcntlTypeHandlers;
|
static TypeHandlerSelector::SelectMap kFcntlTypeHandlers;
|
||||||
|
|
||||||
@@ -79,6 +87,10 @@ patch_fcntl()
|
|||||||
kOpenFlags.push_back(kOpenFlagInfos[i]);
|
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++) {
|
for (int i = 0; kFcntls[i].name != NULL; i++) {
|
||||||
kFcntlNames[kFcntls[i].index] = kFcntls[i].name;
|
kFcntlNames[kFcntls[i].index] = kFcntls[i].name;
|
||||||
if (kFcntls[i].handler != NULL)
|
if (kFcntls[i].handler != NULL)
|
||||||
@@ -90,6 +102,9 @@ patch_fcntl()
|
|||||||
Syscall *open = get_syscall("_kern_open");
|
Syscall *open = get_syscall("_kern_open");
|
||||||
open->GetParameter("openMode")->SetHandler(new FlagsTypeHandler(kOpenFlags));
|
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");
|
Syscall *fcntl = get_syscall("_kern_fcntl");
|
||||||
fcntl->GetParameter("op")->SetHandler(new EnumTypeHandler(kFcntlNames));
|
fcntl->GetParameter("op")->SetHandler(new EnumTypeHandler(kFcntlNames));
|
||||||
fcntl->GetParameter("argument")->SetHandler(
|
fcntl->GetParameter("argument")->SetHandler(
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
SharedLibrary [ MultiArchDefaultGristFiles libbsd.so ] :
|
SharedLibrary [ MultiArchDefaultGristFiles libbsd.so ] :
|
||||||
arc4random.c
|
arc4random.c
|
||||||
arc4random_uniform.c
|
arc4random_uniform.c
|
||||||
|
closefrom.cpp
|
||||||
daemon.c
|
daemon.c
|
||||||
dl_iterate_phdr.c
|
dl_iterate_phdr.c
|
||||||
err.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
|
status_t
|
||||||
user_fd_kernel_ioctl(int fd, uint32 op, void* buffer, size_t length)
|
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
|
int
|
||||||
_user_dup(int fd)
|
_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
|
int
|
||||||
_kern_dup(int fd)
|
_kern_dup(int fd)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user