Skip to content

Commit b2edaad

Browse files
kragnizt-8ch
authored andcommitted
tools/nolibc: add support for openat(2)
openat is useful to avoid needing to construct relative paths, so expose a wrapper for using it directly. Signed-off-by: Louis Taylor <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Thomas Weißschuh <[email protected]>
1 parent cb839e0 commit b2edaad

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

tools/include/nolibc/sys.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,31 @@ int mount(const char *src, const char *tgt,
765765
return __sysret(sys_mount(src, tgt, fst, flags, data));
766766
}
767767

768+
/*
769+
* int openat(int dirfd, const char *path, int flags[, mode_t mode]);
770+
*/
771+
772+
static __attribute__((unused))
773+
int sys_openat(int dirfd, const char *path, int flags, mode_t mode)
774+
{
775+
return my_syscall4(__NR_openat, dirfd, path, flags, mode);
776+
}
777+
778+
static __attribute__((unused))
779+
int openat(int dirfd, const char *path, int flags, ...)
780+
{
781+
mode_t mode = 0;
782+
783+
if (flags & O_CREAT) {
784+
va_list args;
785+
786+
va_start(args, flags);
787+
mode = va_arg(args, mode_t);
788+
va_end(args);
789+
}
790+
791+
return __sysret(sys_openat(dirfd, path, flags, mode));
792+
}
768793

769794
/*
770795
* int open(const char *path, int flags[, mode_t mode]);

tools/testing/selftests/nolibc/nolibc-test.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,22 @@ int test_rlimit(void)
10281028
return 0;
10291029
}
10301030

1031+
int test_openat(void)
1032+
{
1033+
int dev, null;
1034+
1035+
dev = openat(AT_FDCWD, "/dev", O_DIRECTORY);
1036+
if (dev < 0)
1037+
return -1;
1038+
1039+
null = openat(dev, "null", O_RDONLY);
1040+
close(dev);
1041+
if (null < 0)
1042+
return -1;
1043+
1044+
close(null);
1045+
return 0;
1046+
}
10311047

10321048
/* Run syscall tests between IDs <min> and <max>.
10331049
* Return 0 on success, non-zero on failure.
@@ -1116,6 +1132,7 @@ int run_syscall(int min, int max)
11161132
CASE_TEST(mmap_munmap_good); EXPECT_SYSZR(1, test_mmap_munmap()); break;
11171133
CASE_TEST(open_tty); EXPECT_SYSNE(1, tmp = open("/dev/null", 0), -1); if (tmp != -1) close(tmp); break;
11181134
CASE_TEST(open_blah); EXPECT_SYSER(1, tmp = open("/proc/self/blah", 0), -1, ENOENT); if (tmp != -1) close(tmp); break;
1135+
CASE_TEST(openat_dir); EXPECT_SYSZR(1, test_openat()); break;
11191136
CASE_TEST(pipe); EXPECT_SYSZR(1, test_pipe()); break;
11201137
CASE_TEST(poll_null); EXPECT_SYSZR(1, poll(NULL, 0, 0)); break;
11211138
CASE_TEST(poll_stdout); EXPECT_SYSNE(1, ({ struct pollfd fds = { 1, POLLOUT, 0}; poll(&fds, 1, 0); }), -1); break;

0 commit comments

Comments
 (0)