From ed10e85afcdd677543a63c2f0917147b3194f59d Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 4 Jul 2023 18:10:54 +0800 Subject: [PATCH] samples: posix: uname: add toy uname cmd Added `uname` shell cmd, basically copied from nuttx. Signed-off-by: Yong Cong Sin --- samples/posix/uname/prj.conf | 2 + samples/posix/uname/src/main.c | 157 +++++++++++++++++++++++++++++++-- 2 files changed, 154 insertions(+), 5 deletions(-) diff --git a/samples/posix/uname/prj.conf b/samples/posix/uname/prj.conf index b1c2aa0433a336b..47e3b82e5ce925c 100644 --- a/samples/posix/uname/prj.conf +++ b/samples/posix/uname/prj.conf @@ -1 +1,3 @@ CONFIG_POSIX_API=y +CONFIG_SHELL=y +CONFIG_SHELL_GETOPT=y diff --git a/samples/posix/uname/src/main.c b/samples/posix/uname/src/main.c index f19487f185a11c6..be818e5374806d6 100644 --- a/samples/posix/uname/src/main.c +++ b/samples/posix/uname/src/main.c @@ -5,7 +5,9 @@ */ #include +#include #include +#include int main(void) { @@ -14,15 +16,160 @@ int main(void) uname(&info); printk("\nPrinting everything in utsname...\n"); - printk("sysname[%ld]: %s\n", sizeof(info.sysname), info.sysname); - printk("nodename[%ld]: %s\n", sizeof(info.nodename), info.nodename); - printk("release[%ld]: %s\n", sizeof(info.release), info.release); - printk("version[%ld]: %s\n", sizeof(info.version), info.version); - printk("machine[%ld]: %s\n", sizeof(info.machine), info.machine); + printk("sysname[%lu]: %s\n", (unsigned long)sizeof(info.sysname), info.sysname); + printk("nodename[%lu]: %s\n", (unsigned long)sizeof(info.nodename), info.nodename); + printk("release[%lu]: %s\n", (unsigned long)sizeof(info.release), info.release); + printk("version[%lu]: %s\n", (unsigned long)sizeof(info.version), info.version); + printk("machine[%lu]: %s\n", (unsigned long)sizeof(info.machine), info.machine); return 0; } +#define UNAME_KERNEL (1 << 0) +#define UNAME_NODE (1 << 1) +#define UNAME_RELEASE (1 << 2) +#define UNAME_VERSION (1 << 3) +#define UNAME_MACHINE (1 << 4) +#define UNAME_PLATFORM (1 << 5) +#define UNAME_UNKNOWN (1 << 6) +#define UNAME_ALL \ + (UNAME_KERNEL | UNAME_NODE | UNAME_RELEASE | UNAME_VERSION | UNAME_MACHINE | UNAME_PLATFORM) +void getopt_init(void); +static int uname_cmd_handler(const struct shell *sh, size_t argc, char **argv) +{ + struct utsname info; + unsigned int set; + int option; + bool badarg; + bool first; + int ret; + int i; + + set = 0; + badarg = false; + + /* Get the uname options */ + + optind = 1; + while ((option = getopt(argc, argv, "asonrvmpi")) != -1) { + switch (option) { + case 'a': + set = UNAME_ALL; + break; + + case 'o': + case 's': + set |= UNAME_KERNEL; + break; + + case 'n': + set |= UNAME_NODE; + break; + + case 'r': + set |= UNAME_RELEASE; + break; + + case 'v': + set |= UNAME_VERSION; + break; + + case 'm': + set |= UNAME_MACHINE; + break; + + case 'p': + if (set != UNAME_ALL) { + set |= UNAME_UNKNOWN; + } + break; + + case 'i': + set |= UNAME_PLATFORM; + break; + + case '?': + default: + badarg = true; + break; + } + } + + /* If a bad argument was encountered, then return without processing the + * command + */ + + if (badarg) { + struct getopt_state *state = getopt_state_get(); + + shell_error(sh, "uname: illegal option -- %c", state->optopt); + shell_print(sh, "usage: uname [-asonrvmpi]"); + return -1; + } + + /* If nothing is provided on the command line, the default is -s */ + + if (set == 0) { + set = UNAME_KERNEL; + } + + /* Get uname data */ + + ret = uname(&info); + if (ret < 0) { + shell_error(sh, "uname: returned %d", ret); + return -1; + } + + /* Process each option */ + + first = true; + for (i = 0; set != 0; i++) { + unsigned int mask = (1 << i); + + if ((set & mask) != 0) { + set &= ~mask; + switch (i) { + case 0: /* print the kernel/operating system name */ + shell_fprintf(sh, SHELL_NORMAL, "%s", info.sysname); + break; + + case 1: /* Print nodename */ + shell_fprintf(sh, SHELL_NORMAL, "%s", info.nodename); + break; + + case 2: /* Print the kernel release */ + shell_fprintf(sh, SHELL_NORMAL, "%s", info.release); + break; + + case 3: /* Print the kernel version */ + shell_fprintf(sh, SHELL_NORMAL, "%s", info.version); + break; + + case 4: /* Print the machine hardware name */ + shell_fprintf(sh, SHELL_NORMAL, "%s", info.machine); + break; + + case 5: /* Print the machine platform name */ + shell_fprintf(sh, SHELL_NORMAL, "%s", CONFIG_BOARD); + break; + + case 6: /* Print "unknown" */ + shell_fprintf(sh, SHELL_NORMAL, "%s", "unknown"); + break; + + default: + shell_error(sh, "uname: illegal option -- %d", i); + return -1; + } + + shell_fprintf(sh, SHELL_NORMAL, " "); + } + } + + shell_fprintf(sh, SHELL_NORMAL, "\n"); return 0; } + +SHELL_CMD_REGISTER(uname, NULL, NULL, uname_cmd_handler);