mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
tools/nolibc: add support for uname(2)
All supported kernels are assumed to use struct new_utsname. This is validated in test_uname(). uname(2) can for example be used in ksft_min_kernel_version() from the kernels selftest framework. Link: https://lore.kernel.org/lkml/20240412123536.GA32444@redhat.com/ Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Acked-by: Willy Tarreau <w@1wt.eu>
This commit is contained in:
parent
e93b912ecf
commit
0adab2b6b7
@ -22,6 +22,7 @@
|
||||
#include <linux/stat.h> /* for statx() */
|
||||
#include <linux/prctl.h>
|
||||
#include <linux/resource.h>
|
||||
#include <linux/utsname.h>
|
||||
|
||||
#include "arch.h"
|
||||
#include "errno.h"
|
||||
@ -1139,6 +1140,32 @@ int umount2(const char *path, int flags)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* int uname(struct utsname *buf);
|
||||
*/
|
||||
|
||||
struct utsname {
|
||||
char sysname[65];
|
||||
char nodename[65];
|
||||
char release[65];
|
||||
char version[65];
|
||||
char machine[65];
|
||||
char domainname[65];
|
||||
};
|
||||
|
||||
static __attribute__((unused))
|
||||
int sys_uname(struct utsname *buf)
|
||||
{
|
||||
return my_syscall1(__NR_uname, buf);
|
||||
}
|
||||
|
||||
static __attribute__((unused))
|
||||
int uname(struct utsname *buf)
|
||||
{
|
||||
return __sysret(sys_uname(buf));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* int unlink(const char *path);
|
||||
*/
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
@ -780,6 +781,45 @@ int test_stat_timestamps(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_uname(void)
|
||||
{
|
||||
struct utsname buf;
|
||||
char osrelease[sizeof(buf.release)];
|
||||
ssize_t r;
|
||||
int fd;
|
||||
|
||||
memset(&buf.domainname, 'P', sizeof(buf.domainname));
|
||||
|
||||
if (uname(&buf))
|
||||
return 1;
|
||||
|
||||
if (strncmp("Linux", buf.sysname, sizeof(buf.sysname)))
|
||||
return 1;
|
||||
|
||||
fd = open("/proc/sys/kernel/osrelease", O_RDONLY);
|
||||
if (fd == -1)
|
||||
return 1;
|
||||
|
||||
r = read(fd, osrelease, sizeof(osrelease));
|
||||
if (r == -1)
|
||||
return 1;
|
||||
|
||||
close(fd);
|
||||
|
||||
if (osrelease[r - 1] == '\n')
|
||||
r--;
|
||||
|
||||
/* Validate one of the later fields to ensure field sizes are correct */
|
||||
if (strncmp(osrelease, buf.release, r))
|
||||
return 1;
|
||||
|
||||
/* Ensure the field domainname is set, it is missing from struct old_utsname */
|
||||
if (strnlen(buf.domainname, sizeof(buf.domainname)) == sizeof(buf.domainname))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_mmap_munmap(void)
|
||||
{
|
||||
int ret, fd, i, page_size;
|
||||
@ -985,6 +1025,8 @@ int run_syscall(int min, int max)
|
||||
CASE_TEST(stat_fault); EXPECT_SYSER(1, stat(NULL, &stat_buf), -1, EFAULT); break;
|
||||
CASE_TEST(stat_timestamps); EXPECT_SYSZR(1, test_stat_timestamps()); break;
|
||||
CASE_TEST(symlink_root); EXPECT_SYSER(1, symlink("/", "/"), -1, EEXIST); break;
|
||||
CASE_TEST(uname); EXPECT_SYSZR(proc, test_uname()); break;
|
||||
CASE_TEST(uname_fault); EXPECT_SYSER(1, uname(NULL), -1, EFAULT); break;
|
||||
CASE_TEST(unlink_root); EXPECT_SYSER(1, unlink("/"), -1, EISDIR); break;
|
||||
CASE_TEST(unlink_blah); EXPECT_SYSER(1, unlink("/proc/self/blah"), -1, ENOENT); break;
|
||||
CASE_TEST(wait_child); EXPECT_SYSER(1, wait(&tmp), -1, ECHILD); break;
|
||||
|
Loading…
Reference in New Issue
Block a user