Skip to content

Add close_range() system call #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: trunk
Choose a base branch
from
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
1 change: 1 addition & 0 deletions include/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ int pipe2(int *, int);
#if defined(_NETBSD_SOURCE)
int acct(const char *);
int closefrom(int);
int close_range(unsigned int, unsigned int, int);
int des_cipher(const char *, char *, long, int);
int des_setkey(const char *);
void endusershell(void);
Expand Down
1 change: 1 addition & 0 deletions lib/libc/sys/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ ASM=\
chdir.S chflags.S chmod.S chown.S chroot.S \
clock_getcpuclockid2.S \
__clock_getres50.S __clock_gettime50.S \
close_range.S \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to also add manpage (fixed it).

dup.S dup2.S __dup3100.S \
eventfd.S \
extattrctl.S \
Expand Down
58 changes: 58 additions & 0 deletions lib/libc/sys/close_range.2
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
.Dd Feb 16, 2024
.Dt CLOSE_RANGE 2
.Os
.Sh NAME
.Nm close_range
.Nd delete open file descriptors
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In unistd.h
.Ft int
.Fn close_range "u_int first" "u_int last" "int flags"
.Sh DESCRIPTION
The
.Fn close_range
system call deletes all open file descriptors between
.Fa first
and
.Fa last
inclusive, clamped to the range of open file descriptors.
Any errors encountered while closing file descriptors are ignored.
Supported
.Fa flags :
.Bl -tag -width ".Dv CLOSE_RANGE_CLOEXEC"
.It Dv CLOSE_RANGE_CLOEXEC
Set the close-on-exec flag on descriptors in the range instead of closing them.
.El
.Sh RETURN VALUES
Upon successful completion,
.Fn close_range
returns a value
of 0.
Otherwise, a value of -1 is returned and the global variable
.Va errno
is set to indicate the error.
.Sh ERRORS
The
.Fn close_range
system call
will fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The
.Fa last
argument is lower than the
.Fa first
argument.
.It Bq Er EINVAL
An invalid flag was set.
.El
.Sh SEE ALSO
.Xr close 2
.Xr closefrom 3
.Sh HISTORY
The
.Fn close_range
function first appeared in
.Nx 11.0 .
37 changes: 8 additions & 29 deletions sys/compat/linux/common/linux_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2062,7 +2062,6 @@ linux_sys_memfd_create(struct lwp *l,
return sys_memfd_create(l, &muap, retval);
}

#define LINUX_CLOSE_RANGE_UNSHARE 0x02U
#define LINUX_CLOSE_RANGE_CLOEXEC 0x04U

/*
Expand All @@ -2077,37 +2076,17 @@ linux_sys_close_range(struct lwp *l,
syscallarg(unsigned int) last;
syscallarg(unsigned int) flags;
} */
unsigned int fd, last;
file_t *fp;
filedesc_t *fdp;
const unsigned int flags = SCARG(uap, flags);
struct sys_close_range_args crap;
const unsigned int lflags = SCARG(uap, flags);
int flags = 0;

if (flags & ~(LINUX_CLOSE_RANGE_CLOEXEC|LINUX_CLOSE_RANGE_UNSHARE))
return EINVAL;
if (SCARG(uap, first) > SCARG(uap, last))
if (lflags & ~LINUX_CLOSE_RANGE_CLOEXEC)
return EINVAL;
if (lflags & LINUX_CLOSE_RANGE_CLOEXEC)
flags |= CLOSE_RANGE_CLOEXEC;
SCARG(&crap, flags) = flags;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to set first/last here too. (I fixed it already).


if (flags & LINUX_CLOSE_RANGE_UNSHARE) {
fdp = fd_copy();
fd_free();
l->l_proc->p_fd = fdp;
l->l_fd = fdp;
}

last = MIN(SCARG(uap, last), l->l_proc->p_fd->fd_lastfile);
for (fd = SCARG(uap, first); fd <= last; fd++) {
fp = fd_getfile(fd);
if (fp == NULL)
continue;

if (flags & LINUX_CLOSE_RANGE_CLOEXEC) {
fd_set_exclose(l, fd, true);
fd_putfile(fd);
} else
fd_close(fd);
}

return 0;
return sys_close_range(l, &crap, retval);
}

/*
Expand Down
9 changes: 5 additions & 4 deletions sys/kern/init_sysent.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: init_sysent.c,v 1.346 2024/10/09 16:29:10 christos Exp $ */
/* $NetBSD$ */

/*
* System call switch table.
Expand All @@ -8,7 +8,7 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: init_sysent.c,v 1.346 2024/10/09 16:29:10 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD$");

#ifdef _KERNEL_OPT
#include "opt_modular.h"
Expand Down Expand Up @@ -2483,8 +2483,9 @@ struct sysent sysent[] = {
.sy_call = (sy_call_t *)sys_nomodule
}, /* 506 = semtimedop */
{
.sy_call = sys_nosys,
}, /* 507 = filler */
ns(struct sys_close_range_args),
.sy_call = (sy_call_t *)sys_close_range
}, /* 507 = close_range */
{
.sy_call = sys_nosys,
}, /* 508 = filler */
Expand Down
34 changes: 34 additions & 0 deletions sys/kern/sys_descrip.c
Original file line number Diff line number Diff line change
Expand Up @@ -731,3 +731,37 @@ sys_pipe2(struct lwp *l, const struct sys_pipe2_args *uap, register_t *retval)
retval[0] = 0;
return 0;
}

int
sys_close_range(struct lwp *l, const struct sys_close_range_args *uap, register_t *retval)
{
/* {
syscallarg(unsigned int) first;
syscallarg(unsigned int) last;
syscallarg(int) flags;
} */
const unsigned int flags = SCARG(uap, flags);
unsigned int fd, last;
file_t *fp;

if (flags & ~CLOSE_RANGE_CLOEXEC)
return EINVAL;

if (SCARG(uap, first) > SCARG(uap, last))
return EINVAL;

last = MIN(SCARG(uap, last), l->l_proc->p_fd->fd_lastfile);
for (fd = SCARG(uap, first); fd <= last; fd++) {
fp = fd_getfile(fd);
if (fp == NULL)
continue;

if (flags & CLOSE_RANGE_CLOEXEC) {
fd_set_exclose(l, fd, true);
fd_putfile(fd);
} else
fd_close(fd);
}

return 0;
}
8 changes: 4 additions & 4 deletions sys/kern/syscalls.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: syscalls.c,v 1.334 2024/10/09 16:29:11 christos Exp $ */
/* $NetBSD$ */

/*
* System call names.
Expand All @@ -8,7 +8,7 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: syscalls.c,v 1.334 2024/10/09 16:29:11 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD$");

#if defined(_KERNEL_OPT)
#ifdef _KERNEL_OPT
Expand Down Expand Up @@ -557,7 +557,7 @@ const char *const syscallnames[] = {
/* 504 */ "epoll_pwait2",
/* 505 */ "__dup3100",
/* 506 */ "semtimedop",
/* 507 */ "# filler",
/* 507 */ "close_range",
/* 508 */ "# filler",
/* 509 */ "# filler",
/* 510 */ "# filler",
Expand Down Expand Up @@ -1094,7 +1094,7 @@ const char *const altsyscallnames[] = {
/* 504 */ NULL, /* epoll_pwait2 */
/* 505 */ "dup3",
/* 506 */ NULL, /* semtimedop */
/* 507 */ NULL, /* filler */
/* 507 */ NULL, /* close_range */
/* 508 */ NULL, /* filler */
/* 509 */ NULL, /* filler */
/* 510 */ NULL, /* filler */
Expand Down
2 changes: 2 additions & 0 deletions sys/kern/syscalls.master
Original file line number Diff line number Diff line change
Expand Up @@ -1068,3 +1068,5 @@
506 STD MODULAR sysv_ipc { int|sys||semtimedop(int semid, \
struct sembuf *sops, size_t nsops, \
struct timespec *timeout); }
507 STD { int|sys||close_range(u_int first, u_int last, \
int flags); }
4 changes: 2 additions & 2 deletions sys/kern/syscalls_autoload.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: syscalls_autoload.c,v 1.50 2024/10/09 16:29:11 christos Exp $ */
/* $NetBSD$ */

/*
* System call autoload table.
Expand All @@ -8,7 +8,7 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: syscalls_autoload.c,v 1.50 2024/10/09 16:29:11 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD$");

#ifdef _KERNEL_OPT
#include "opt_modular.h"
Expand Down
32 changes: 31 additions & 1 deletion sys/kern/systrace_args.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: systrace_args.c,v 1.56 2024/10/09 16:29:11 christos Exp $ */
/* $NetBSD$ */

/*
* System call argument to DTrace register array conversion.
Expand Down Expand Up @@ -3954,6 +3954,15 @@ systrace_args(register_t sysnum, const void *params, uintptr_t *uarg, size_t *n_
*n_args = 4;
break;
}
/* sys_close_range */
case 507: {
const struct sys_close_range_args *p = params;
uarg[0] = SCARG(p, first); /* u_int */
uarg[1] = SCARG(p, last); /* u_int */
iarg[2] = SCARG(p, flags); /* int */
*n_args = 3;
break;
}
default:
*n_args = 0;
break;
Expand Down Expand Up @@ -10683,6 +10692,22 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
/* sys_close_range */
case 507:
switch(ndx) {
case 0:
p = "u_int";
break;
case 1:
p = "u_int";
break;
case 2:
p = "int";
break;
default:
break;
};
break;
default:
break;
};
Expand Down Expand Up @@ -12920,6 +12945,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
/* sys_close_range */
case 507:
if (ndx == 0 || ndx == 1)
p = "int";
break;
default:
break;
};
Expand Down
2 changes: 1 addition & 1 deletion sys/rump/include/rump/rump_syscalls.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: rump_syscalls.h,v 1.133 2024/10/09 16:29:11 christos Exp $ */
/* $NetBSD$ */

/*
* System call protos in rump namespace.
Expand Down
7 changes: 3 additions & 4 deletions sys/rump/librump/rumpkern/rump_syscalls.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: rump_syscalls.c,v 1.164 2024/10/09 16:29:11 christos Exp $ */
/* $NetBSD$ */

/*
* System call vector and marshalling for rump.
Expand All @@ -15,7 +15,7 @@

#ifdef __NetBSD__
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rump_syscalls.c,v 1.164 2024/10/09 16:29:11 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD$");

#include <sys/fstypes.h>
#include <sys/proc.h>
Expand Down Expand Up @@ -8664,9 +8664,8 @@ struct sysent rump_sysent[] = {
.sy_call = (sy_call_t *)(void *)rumpns_sys_nomodule,
}, /* 506 = semtimedop */
{
.sy_flags = SYCALL_NOSYS,
.sy_call = (sy_call_t *)(void *)rumpns_enosys,
}, /* 507 = filler */
}, /* 507 = close_range */
{
.sy_flags = SYCALL_NOSYS,
.sy_call = (sy_call_t *)(void *)rumpns_enosys,
Expand Down
7 changes: 5 additions & 2 deletions sys/sys/syscall.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: syscall.h,v 1.329 2024/10/09 16:29:11 christos Exp $ */
/* $NetBSD$ */

/*
* System call numbers.
Expand Down Expand Up @@ -1425,6 +1425,9 @@
/* syscall: "semtimedop" ret: "int" args: "int" "struct sembuf *" "size_t" "struct timespec *" */
#define SYS_semtimedop 506

#define SYS_MAXSYSCALL 507
/* syscall: "close_range" ret: "int" args: "u_int" "u_int" "int" */
#define SYS_close_range 507

#define SYS_MAXSYSCALL 508
#define SYS_NSYSENT 512
#endif /* _SYS_SYSCALL_H_ */
13 changes: 12 additions & 1 deletion sys/sys/syscallargs.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: syscallargs.h,v 1.312 2024/10/09 16:29:11 christos Exp $ */
/* $NetBSD$ */

/*
* System call argument lists.
Expand Down Expand Up @@ -3419,6 +3419,15 @@ struct sys_semtimedop_args {
check_syscall_args(sys_semtimedop)
#endif /* !RUMP_CLIENT */

#ifndef RUMP_CLIENT
struct sys_close_range_args {
syscallarg(u_int) first;
syscallarg(u_int) last;
syscallarg(int) flags;
};
check_syscall_args(sys_close_range)
#endif /* !RUMP_CLIENT */

/*
* System call prototypes.
*/
Expand Down Expand Up @@ -4357,5 +4366,7 @@ int sys___dup3100(struct lwp *, const struct sys___dup3100_args *, register_t *)

int sys_semtimedop(struct lwp *, const struct sys_semtimedop_args *, register_t *);

int sys_close_range(struct lwp *, const struct sys_close_range_args *, register_t *);

#endif /* !RUMP_CLIENT */
#endif /* _SYS_SYSCALLARGS_H_ */
5 changes: 5 additions & 0 deletions sys/sys/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,9 @@
/* configurable system strings */
#define _CS_PATH 1

/*
* close_range(2) options
*/
#define CLOSE_RANGE_CLOEXEC (1<<2)

#endif /* !_SYS_UNISTD_H_ */
Loading