Merge tag 'linux_kselftest-next-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull kselftest updates from Shuah Khan:

 - kbuild kselftest-merge target fixes

 - fixes to several tests

 - resctrl test fixes and enhancements

 - ksft_perror() helper and reporting improvements

 - printf attribute to kselftest prints to improve reporting

 - documentation and clang build warning fixes

The bulk of the patches are for resctrl fixes and enhancements.

* tag 'linux_kselftest-next-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (51 commits)
  selftests/resctrl: Fix MBM test failure when MBA unavailable
  selftests/clone3: Report descriptive test names
  selftests:modify the incorrect print format
  selftests/efivarfs: create-read: fix a resource leak
  selftests/ftrace: Add riscv support for kprobe arg tests
  selftests/ftrace: add loongarch support for kprobe args char tests
  selftests/amd-pstate: Added option to provide perf binary path
  selftests/amd-pstate: Fix broken paths to run workloads in amd-pstate-ut
  selftests/resctrl: Move run_benchmark() to a more fitting file
  selftests/resctrl: Fix schemata write error check
  selftests/resctrl: Reduce failures due to outliers in MBA/MBM tests
  selftests/resctrl: Fix feature checks
  selftests/resctrl: Refactor feature check to use resource and feature name
  selftests/resctrl: Move _GNU_SOURCE define into Makefile
  selftests/resctrl: Remove duplicate feature check from CMT test
  selftests/resctrl: Extend signal handler coverage to unmount on receiving signal
  selftests/resctrl: Fix uninitialized .sa_flags
  selftests/resctrl: Cleanup benchmark argument parsing
  selftests/resctrl: Remove ben_count variable
  selftests/resctrl: Make benchmark command const and build it with pointers
  ...
This commit is contained in:
Linus Torvalds
2023-11-01 17:08:10 -10:00
59 changed files with 698 additions and 560 deletions
+3 -3
View File
@@ -112,7 +112,7 @@ You can specify multiple tests to skip::
You can also specify a restricted list of tests to run together with a
dedicated skiplist::
$ make TARGETS="bpf breakpoints size timers" SKIP_TARGETS=bpf kselftest
$ make TARGETS="breakpoints size timers" SKIP_TARGETS=size kselftest
See the top-level tools/testing/selftests/Makefile for the list of all
possible targets.
@@ -165,7 +165,7 @@ To see the list of available tests, the `-l` option can be used::
The `-c` option can be used to run all the tests from a test collection, or
the `-t` option for specific single tests. Either can be used multiple times::
$ ./run_kselftest.sh -c bpf -c seccomp -t timers:posix_timers -t timer:nanosleep
$ ./run_kselftest.sh -c size -c seccomp -t timers:posix_timers -t timer:nanosleep
For other features see the script usage output, seen with the `-h` option.
@@ -210,7 +210,7 @@ option is supported, such as::
tests by using variables specified in `Running a subset of selftests`_
section::
$ make -C tools/testing/selftests gen_tar TARGETS="bpf" FORMAT=.xz
$ make -C tools/testing/selftests gen_tar TARGETS="size" FORMAT=.xz
.. _tar's auto-compress: https://www.gnu.org/software/tar/manual/html_node/gzip.html#auto_002dcompress
+2 -2
View File
@@ -1367,8 +1367,8 @@ kselftest-%: headers FORCE
PHONY += kselftest-merge
kselftest-merge:
$(if $(wildcard $(objtree)/.config),, $(error No .config exists, config your kernel first!))
$(Q)find $(srctree)/tools/testing/selftests -name config | \
xargs $(srctree)/scripts/kconfig/merge_config.sh -m $(objtree)/.config
$(Q)find $(srctree)/tools/testing/selftests -name config -o -name config.$(UTS_MACHINE) | \
xargs $(srctree)/scripts/kconfig/merge_config.sh -y -m $(objtree)/.config
$(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig
# ---------------------------------------------------------------------------
@@ -30,8 +30,7 @@ import getopt
import Gnuplot
from numpy import *
from decimal import *
sys.path.append('../intel_pstate_tracer')
#import intel_pstate_tracer
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "intel_pstate_tracer"))
import intel_pstate_tracer as ipt
__license__ = "GPL version 2"
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Testing and monitor the cpu desire performance, frequency, load,
@@ -66,12 +66,15 @@ post_clear_gitsource()
install_gitsource()
{
if [ ! -d $git_name ]; then
if [ ! -d $SCRIPTDIR/$git_name ]; then
pushd $(pwd) > /dev/null 2>&1
cd $SCRIPTDIR
printf "Download gitsource, please wait a moment ...\n\n"
wget -O $git_tar $gitsource_url > /dev/null 2>&1
printf "Tar gitsource ...\n\n"
tar -xzf $git_tar
popd > /dev/null 2>&1
fi
}
@@ -79,12 +82,14 @@ install_gitsource()
run_gitsource()
{
echo "Launching amd pstate tracer for $1 #$2 tracer_interval: $TRACER_INTERVAL"
./amd_pstate_trace.py -n tracer-gitsource-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 &
$TRACER -n tracer-gitsource-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 &
printf "Make and test gitsource for $1 #$2 make_cpus: $MAKE_CPUS\n"
cd $git_name
perf stat -a --per-socket -I 1000 -e power/energy-pkg/ /usr/bin/time -o ../$OUTFILE_GIT.time-gitsource-$1-$2.log make test -j$MAKE_CPUS > ../$OUTFILE_GIT-perf-$1-$2.log 2>&1
cd ..
BACKUP_DIR=$(pwd)
pushd $BACKUP_DIR > /dev/null 2>&1
cd $SCRIPTDIR/$git_name
$PERF stat -a --per-socket -I 1000 -e power/energy-pkg/ /usr/bin/time -o $BACKUP_DIR/$OUTFILE_GIT.time-gitsource-$1-$2.log make test -j$MAKE_CPUS > $BACKUP_DIR/$OUTFILE_GIT-perf-$1-$2.log 2>&1
popd > /dev/null 2>&1
for job in `jobs -p`
do
+15 -6
View File
@@ -8,9 +8,12 @@ else
FILE_MAIN=DONE
fi
source basic.sh
source tbench.sh
source gitsource.sh
SCRIPTDIR=`dirname "$0"`
TRACER=$SCRIPTDIR/../../../power/x86/amd_pstate_tracer/amd_pstate_trace.py
source $SCRIPTDIR/basic.sh
source $SCRIPTDIR/tbench.sh
source $SCRIPTDIR/gitsource.sh
# amd-pstate-ut only run on x86/x86_64 AMD systems.
ARCH=$(uname -m 2>/dev/null | sed -e 's/i.86/x86/' -e 's/x86_64/x86/')
@@ -22,6 +25,7 @@ OUTFILE=selftest
OUTFILE_TBENCH="$OUTFILE.tbench"
OUTFILE_GIT="$OUTFILE.gitsource"
PERF=/usr/bin/perf
SYSFS=
CPUROOT=
CPUFREQROOT=
@@ -151,6 +155,7 @@ help()
[-p <tbench process number>]
[-l <loop times for tbench>]
[-i <amd tracer interval>]
[-b <perf binary>]
[-m <comparative test: acpi-cpufreq>]
\n"
exit 2
@@ -158,7 +163,7 @@ help()
parse_arguments()
{
while getopts ho:c:t:p:l:i:m: arg
while getopts ho:c:t:p:l:i:b:m: arg
do
case $arg in
h) # --help
@@ -189,6 +194,10 @@ parse_arguments()
TRACER_INTERVAL=$OPTARG
;;
b) # --perf-binary
PERF=`realpath $OPTARG`
;;
m) # --comparative-test
COMPARATIVE_TEST=$OPTARG
;;
@@ -202,8 +211,8 @@ parse_arguments()
command_perf()
{
if ! command -v perf > /dev/null; then
echo $msg please install perf. >&2
if ! $PERF -v; then
echo $msg please install perf or provide perf binary path as argument >&2
exit $ksft_skip
fi
}
+2 -2
View File
@@ -64,11 +64,11 @@ post_clear_tbench()
run_tbench()
{
echo "Launching amd pstate tracer for $1 #$2 tracer_interval: $TRACER_INTERVAL"
./amd_pstate_trace.py -n tracer-tbench-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 &
$TRACER -n tracer-tbench-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 &
printf "Test tbench for $1 #$2 time_limit: $TIME_LIMIT procs_num: $PROCESS_NUM\n"
tbench_srv > /dev/null 2>&1 &
perf stat -a --per-socket -I 1000 -e power/energy-pkg/ tbench -t $TIME_LIMIT $PROCESS_NUM > $OUTFILE_TBENCH-perf-$1-$2.log 2>&1
$PERF stat -a --per-socket -I 1000 -e power/energy-pkg/ tbench -t $TIME_LIMIT $PROCESS_NUM > $OUTFILE_TBENCH-perf-$1-$2.log 2>&1
pid=`pidof tbench_srv`
kill $pid
@@ -27,7 +27,7 @@ static const char * const dev_files[] = {
void print_cachestat(struct cachestat *cs)
{
ksft_print_msg(
"Using cachestat: Cached: %lu, Dirty: %lu, Writeback: %lu, Evicted: %lu, Recently Evicted: %lu\n",
"Using cachestat: Cached: %llu, Dirty: %llu, Writeback: %llu, Evicted: %llu, Recently Evicted: %llu\n",
cs->nr_cache, cs->nr_dirty, cs->nr_writeback,
cs->nr_evicted, cs->nr_recently_evicted);
}
@@ -2,7 +2,7 @@
TEST_GEN_FILES := validate_cap
TEST_GEN_PROGS := test_execve
CFLAGS += -O2 -g -std=gnu99 -Wall
CFLAGS += -O2 -g -std=gnu99 -Wall $(KHDR_INCLUDES)
LDLIBS += -lcap-ng -lrt -ldl
include ../lib.mk
@@ -20,14 +20,6 @@
#include "../kselftest.h"
#ifndef PR_CAP_AMBIENT
#define PR_CAP_AMBIENT 47
# define PR_CAP_AMBIENT_IS_SET 1
# define PR_CAP_AMBIENT_RAISE 2
# define PR_CAP_AMBIENT_LOWER 3
# define PR_CAP_AMBIENT_CLEAR_ALL 4
#endif
static int nerrs;
static pid_t mpid; /* main() pid is used to avoid duplicate test counts */
@@ -9,14 +9,6 @@
#include "../kselftest.h"
#ifndef PR_CAP_AMBIENT
#define PR_CAP_AMBIENT 47
# define PR_CAP_AMBIENT_IS_SET 1
# define PR_CAP_AMBIENT_RAISE 2
# define PR_CAP_AMBIENT_LOWER 3
# define PR_CAP_AMBIENT_CLEAR_ALL 4
#endif
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 19)
# define HAVE_GETAUXVAL
#endif
+194 -75
View File
@@ -7,6 +7,7 @@
#include <inttypes.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -103,8 +104,8 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode)
return 0;
}
static void test_clone3(uint64_t flags, size_t size, int expected,
enum test_mode test_mode)
static bool test_clone3(uint64_t flags, size_t size, int expected,
enum test_mode test_mode)
{
int ret;
@@ -114,92 +115,210 @@ static void test_clone3(uint64_t flags, size_t size, int expected,
ret = call_clone3(flags, size, test_mode);
ksft_print_msg("[%d] clone3() with flags says: %d expected %d\n",
getpid(), ret, expected);
if (ret != expected)
ksft_test_result_fail(
if (ret != expected) {
ksft_print_msg(
"[%d] Result (%d) is different than expected (%d)\n",
getpid(), ret, expected);
else
ksft_test_result_pass(
"[%d] Result (%d) matches expectation (%d)\n",
getpid(), ret, expected);
return false;
}
return true;
}
typedef bool (*filter_function)(void);
typedef size_t (*size_function)(void);
static bool not_root(void)
{
if (getuid() != 0) {
ksft_print_msg("Not running as root\n");
return true;
}
return false;
}
static size_t page_size_plus_8(void)
{
return getpagesize() + 8;
}
struct test {
const char *name;
uint64_t flags;
size_t size;
size_function size_function;
int expected;
enum test_mode test_mode;
filter_function filter;
};
static const struct test tests[] = {
{
.name = "simple clone3()",
.flags = 0,
.size = 0,
.expected = 0,
.test_mode = CLONE3_ARGS_NO_TEST,
},
{
.name = "clone3() in a new PID_NS",
.flags = CLONE_NEWPID,
.size = 0,
.expected = 0,
.test_mode = CLONE3_ARGS_NO_TEST,
.filter = not_root,
},
{
.name = "CLONE_ARGS_SIZE_VER0",
.flags = 0,
.size = CLONE_ARGS_SIZE_VER0,
.expected = 0,
.test_mode = CLONE3_ARGS_NO_TEST,
},
{
.name = "CLONE_ARGS_SIZE_VER0 - 8",
.flags = 0,
.size = CLONE_ARGS_SIZE_VER0 - 8,
.expected = -EINVAL,
.test_mode = CLONE3_ARGS_NO_TEST,
},
{
.name = "sizeof(struct clone_args) + 8",
.flags = 0,
.size = sizeof(struct __clone_args) + 8,
.expected = 0,
.test_mode = CLONE3_ARGS_NO_TEST,
},
{
.name = "exit_signal with highest 32 bits non-zero",
.flags = 0,
.size = 0,
.expected = -EINVAL,
.test_mode = CLONE3_ARGS_INVAL_EXIT_SIGNAL_BIG,
},
{
.name = "negative 32-bit exit_signal",
.flags = 0,
.size = 0,
.expected = -EINVAL,
.test_mode = CLONE3_ARGS_INVAL_EXIT_SIGNAL_NEG,
},
{
.name = "exit_signal not fitting into CSIGNAL mask",
.flags = 0,
.size = 0,
.expected = -EINVAL,
.test_mode = CLONE3_ARGS_INVAL_EXIT_SIGNAL_CSIG,
},
{
.name = "NSIG < exit_signal < CSIG",
.flags = 0,
.size = 0,
.expected = -EINVAL,
.test_mode = CLONE3_ARGS_INVAL_EXIT_SIGNAL_NSIG,
},
{
.name = "Arguments sizeof(struct clone_args) + 8",
.flags = 0,
.size = sizeof(struct __clone_args) + 8,
.expected = 0,
.test_mode = CLONE3_ARGS_ALL_0,
},
{
.name = "Arguments sizeof(struct clone_args) + 16",
.flags = 0,
.size = sizeof(struct __clone_args) + 16,
.expected = -E2BIG,
.test_mode = CLONE3_ARGS_ALL_0,
},
{
.name = "Arguments sizeof(struct clone_arg) * 2",
.flags = 0,
.size = sizeof(struct __clone_args) + 16,
.expected = -E2BIG,
.test_mode = CLONE3_ARGS_ALL_0,
},
{
.name = "Arguments > page size",
.flags = 0,
.size_function = page_size_plus_8,
.expected = -E2BIG,
.test_mode = CLONE3_ARGS_NO_TEST,
},
{
.name = "CLONE_ARGS_SIZE_VER0 in a new PID NS",
.flags = CLONE_NEWPID,
.size = CLONE_ARGS_SIZE_VER0,
.expected = 0,
.test_mode = CLONE3_ARGS_NO_TEST,
.filter = not_root,
},
{
.name = "CLONE_ARGS_SIZE_VER0 - 8 in a new PID NS",
.flags = CLONE_NEWPID,
.size = CLONE_ARGS_SIZE_VER0 - 8,
.expected = -EINVAL,
.test_mode = CLONE3_ARGS_NO_TEST,
},
{
.name = "sizeof(struct clone_args) + 8 in a new PID NS",
.flags = CLONE_NEWPID,
.size = sizeof(struct __clone_args) + 8,
.expected = 0,
.test_mode = CLONE3_ARGS_NO_TEST,
.filter = not_root,
},
{
.name = "Arguments > page size in a new PID NS",
.flags = CLONE_NEWPID,
.size_function = page_size_plus_8,
.expected = -E2BIG,
.test_mode = CLONE3_ARGS_NO_TEST,
},
{
.name = "New time NS",
.flags = CLONE_NEWTIME,
.size = 0,
.expected = 0,
.test_mode = CLONE3_ARGS_NO_TEST,
},
{
.name = "exit signal (SIGCHLD) in flags",
.flags = SIGCHLD,
.size = 0,
.expected = -EINVAL,
.test_mode = CLONE3_ARGS_NO_TEST,
},
};
int main(int argc, char *argv[])
{
uid_t uid = getuid();
size_t size;
int i;
ksft_print_header();
ksft_set_plan(19);
ksft_set_plan(ARRAY_SIZE(tests));
test_clone3_supported();
/* Just a simple clone3() should return 0.*/
test_clone3(0, 0, 0, CLONE3_ARGS_NO_TEST);
for (i = 0; i < ARRAY_SIZE(tests); i++) {
if (tests[i].filter && tests[i].filter()) {
ksft_test_result_skip("%s\n", tests[i].name);
continue;
}
/* Do a clone3() in a new PID NS.*/
if (uid == 0)
test_clone3(CLONE_NEWPID, 0, 0, CLONE3_ARGS_NO_TEST);
else
ksft_test_result_skip("Skipping clone3() with CLONE_NEWPID\n");
if (tests[i].size_function)
size = tests[i].size_function();
else
size = tests[i].size;
/* Do a clone3() with CLONE_ARGS_SIZE_VER0. */
test_clone3(0, CLONE_ARGS_SIZE_VER0, 0, CLONE3_ARGS_NO_TEST);
ksft_print_msg("Running test '%s'\n", tests[i].name);
/* Do a clone3() with CLONE_ARGS_SIZE_VER0 - 8 */
test_clone3(0, CLONE_ARGS_SIZE_VER0 - 8, -EINVAL, CLONE3_ARGS_NO_TEST);
/* Do a clone3() with sizeof(struct clone_args) + 8 */
test_clone3(0, sizeof(struct __clone_args) + 8, 0, CLONE3_ARGS_NO_TEST);
/* Do a clone3() with exit_signal having highest 32 bits non-zero */
test_clone3(0, 0, -EINVAL, CLONE3_ARGS_INVAL_EXIT_SIGNAL_BIG);
/* Do a clone3() with negative 32-bit exit_signal */
test_clone3(0, 0, -EINVAL, CLONE3_ARGS_INVAL_EXIT_SIGNAL_NEG);
/* Do a clone3() with exit_signal not fitting into CSIGNAL mask */
test_clone3(0, 0, -EINVAL, CLONE3_ARGS_INVAL_EXIT_SIGNAL_CSIG);
/* Do a clone3() with NSIG < exit_signal < CSIG */
test_clone3(0, 0, -EINVAL, CLONE3_ARGS_INVAL_EXIT_SIGNAL_NSIG);
test_clone3(0, sizeof(struct __clone_args) + 8, 0, CLONE3_ARGS_ALL_0);
test_clone3(0, sizeof(struct __clone_args) + 16, -E2BIG,
CLONE3_ARGS_ALL_0);
test_clone3(0, sizeof(struct __clone_args) * 2, -E2BIG,
CLONE3_ARGS_ALL_0);
/* Do a clone3() with > page size */
test_clone3(0, getpagesize() + 8, -E2BIG, CLONE3_ARGS_NO_TEST);
/* Do a clone3() with CLONE_ARGS_SIZE_VER0 in a new PID NS. */
if (uid == 0)
test_clone3(CLONE_NEWPID, CLONE_ARGS_SIZE_VER0, 0,
CLONE3_ARGS_NO_TEST);
else
ksft_test_result_skip("Skipping clone3() with CLONE_NEWPID\n");
/* Do a clone3() with CLONE_ARGS_SIZE_VER0 - 8 in a new PID NS */
test_clone3(CLONE_NEWPID, CLONE_ARGS_SIZE_VER0 - 8, -EINVAL,
CLONE3_ARGS_NO_TEST);
/* Do a clone3() with sizeof(struct clone_args) + 8 in a new PID NS */
if (uid == 0)
test_clone3(CLONE_NEWPID, sizeof(struct __clone_args) + 8, 0,
CLONE3_ARGS_NO_TEST);
else
ksft_test_result_skip("Skipping clone3() with CLONE_NEWPID\n");
/* Do a clone3() with > page size in a new PID NS */
test_clone3(CLONE_NEWPID, getpagesize() + 8, -E2BIG,
CLONE3_ARGS_NO_TEST);
/* Do a clone3() in a new time namespace */
test_clone3(CLONE_NEWTIME, 0, 0, CLONE3_ARGS_NO_TEST);
/* Do a clone3() with exit signal (SIGCHLD) in flags */
test_clone3(SIGCHLD, 0, -EINVAL, CLONE3_ARGS_NO_TEST);
ksft_test_result(test_clone3(tests[i].flags, size,
tests[i].expected,
tests[i].test_mode),
"%s\n", tests[i].name);
}
ksft_finished();
}
@@ -27,9 +27,7 @@
#include "../kselftest_harness.h"
#include "clone3_selftests.h"
#ifndef MAX_PID_NS_LEVEL
#define MAX_PID_NS_LEVEL 32
#endif
static void child_exit(int ret)
{
@@ -16,10 +16,6 @@
#include "../kselftest.h"
#include "clone3_selftests.h"
#ifndef CLONE_CLEAR_SIGHAND
#define CLONE_CLEAR_SIGHAND 0x100000000ULL
#endif
static void nop_handler(int signo)
{
}
@@ -15,10 +15,6 @@
#define ptr_to_u64(ptr) ((__u64)((uintptr_t)(ptr)))
#ifndef CLONE_INTO_CGROUP
#define CLONE_INTO_CGROUP 0x200000000ULL /* Clone into a specific cgroup given the right permissions. */
#endif
#ifndef __NR_clone3
#define __NR_clone3 -1
#endif
@@ -32,18 +28,9 @@ struct __clone_args {
__aligned_u64 stack;
__aligned_u64 stack_size;
__aligned_u64 tls;
#ifndef CLONE_ARGS_SIZE_VER0
#define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */
#endif
__aligned_u64 set_tid;
__aligned_u64 set_tid_size;
#ifndef CLONE_ARGS_SIZE_VER1
#define CLONE_ARGS_SIZE_VER1 80 /* sizeof second published struct */
#endif
__aligned_u64 cgroup;
#ifndef CLONE_ARGS_SIZE_VER2
#define CLONE_ARGS_SIZE_VER2 88 /* sizeof third published struct */
#endif
};
static pid_t sys_clone3(struct __clone_args *args, size_t size)
@@ -23,9 +23,7 @@
#include "../kselftest.h"
#include "clone3_selftests.h"
#ifndef MAX_PID_NS_LEVEL
#define MAX_PID_NS_LEVEL 32
#endif
static int pipe_1[2];
static int pipe_2[2];
@@ -16,34 +16,6 @@
#include "../kselftest_harness.h"
#include "../clone3/clone3_selftests.h"
#ifndef __NR_close_range
#if defined __alpha__
#define __NR_close_range 546
#elif defined _MIPS_SIM
#if _MIPS_SIM == _MIPS_SIM_ABI32 /* o32 */
#define __NR_close_range (436 + 4000)
#endif
#if _MIPS_SIM == _MIPS_SIM_NABI32 /* n32 */
#define __NR_close_range (436 + 6000)
#endif
#if _MIPS_SIM == _MIPS_SIM_ABI64 /* n64 */
#define __NR_close_range (436 + 5000)
#endif
#elif defined __ia64__
#define __NR_close_range (436 + 1024)
#else
#define __NR_close_range 436
#endif
#endif
#ifndef CLOSE_RANGE_UNSHARE
#define CLOSE_RANGE_UNSHARE (1U << 1)
#endif
#ifndef CLOSE_RANGE_CLOEXEC
#define CLOSE_RANGE_CLOEXEC (1U << 2)
#endif
static inline int sys_close_range(unsigned int fd, unsigned int max_fd,
unsigned int flags)
{
View File
View File
View File
View File

Some files were not shown because too many files have changed in this diff Show More