kernel: add boot argument parsing
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
#include <socks/pmap.h>
|
#include <socks/pmap.h>
|
||||||
#include <socks/device.h>
|
#include <socks/device.h>
|
||||||
|
#include <socks/arg.h>
|
||||||
#include <socks/tty.h>
|
#include <socks/tty.h>
|
||||||
#include <socks/kext.h>
|
#include <socks/kext.h>
|
||||||
#include <socks/clock.h>
|
#include <socks/clock.h>
|
||||||
@@ -104,6 +105,8 @@ int ml_init(uintptr_t arg)
|
|||||||
{
|
{
|
||||||
multiboot_info_t *mb = (multiboot_info_t *)arg;
|
multiboot_info_t *mb = (multiboot_info_t *)arg;
|
||||||
|
|
||||||
|
parse_cmdline(PTR32(mb->cmdline));
|
||||||
|
|
||||||
init_bootfb(mb);
|
init_bootfb(mb);
|
||||||
|
|
||||||
bootstrap_cpu_init();
|
bootstrap_cpu_init();
|
||||||
|
|||||||
14
include/socks/arg.h
Normal file
14
include/socks/arg.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef SOCKS_ARG_H_
|
||||||
|
#define SOCKS_ARG_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <socks/status.h>
|
||||||
|
|
||||||
|
#define CMDLINE_MAX 4096
|
||||||
|
|
||||||
|
extern kern_status_t parse_cmdline(const char *cmdline);
|
||||||
|
|
||||||
|
extern const char *arg_value(const char *arg_name);
|
||||||
|
extern bool arg_is_set(const char *arg_name);
|
||||||
|
|
||||||
|
#endif
|
||||||
125
kernel/arg.c
Normal file
125
kernel/arg.c
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#include <socks/arg.h>
|
||||||
|
#include <socks/libc/string.h>
|
||||||
|
#include <socks/libc/ctype.h>
|
||||||
|
|
||||||
|
static char g_cmdline[CMDLINE_MAX + 1] = {0};
|
||||||
|
|
||||||
|
static kern_status_t remove_quotes(char *s, size_t max)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < max) {
|
||||||
|
if (s[i] != '"') {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t start = i;
|
||||||
|
size_t end = i + 1;
|
||||||
|
while (s[end] != '"' && end < max) {
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s[end] != '"') {
|
||||||
|
return KERN_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* length of quoted string (excluding quotes) */
|
||||||
|
size_t len = end - start - 1;
|
||||||
|
|
||||||
|
/* remove trailing quote */
|
||||||
|
s[end] = 0;
|
||||||
|
|
||||||
|
/* add 1 to len to include the null terminator */
|
||||||
|
memmove(s + start, s + start + 1, len + 1);
|
||||||
|
|
||||||
|
i = end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t parse_cmdline(const char *cmdline)
|
||||||
|
{
|
||||||
|
strncpy(g_cmdline, cmdline, sizeof g_cmdline - 1);
|
||||||
|
g_cmdline[sizeof g_cmdline - 1] = 0;
|
||||||
|
|
||||||
|
bool in_string = false;
|
||||||
|
|
||||||
|
for (size_t i = 0; g_cmdline[i]; i++) {
|
||||||
|
char c = g_cmdline[i];
|
||||||
|
|
||||||
|
if (c == '"') {
|
||||||
|
in_string = !in_string;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isspace(c) && !in_string) {
|
||||||
|
g_cmdline[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_string) {
|
||||||
|
/* unterminated string on command line */
|
||||||
|
return KERN_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_quotes(g_cmdline, sizeof g_cmdline);
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *advance_to_next_arg(char *s, char *max)
|
||||||
|
{
|
||||||
|
while (*s && s < max) {
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!*s && s < max) {
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *arg_value(const char *arg_name)
|
||||||
|
{
|
||||||
|
char *s = g_cmdline;
|
||||||
|
char *end = s + sizeof g_cmdline;
|
||||||
|
|
||||||
|
while (s < end) {
|
||||||
|
size_t len = strlen(s);
|
||||||
|
size_t name_len = strcspn(s, "=");
|
||||||
|
|
||||||
|
if (!strncmp(s, arg_name, name_len)) {
|
||||||
|
if (len == name_len) {
|
||||||
|
/* arg has no value */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s + name_len + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = advance_to_next_arg(s, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool arg_is_set(const char *arg_name)
|
||||||
|
{
|
||||||
|
char *s = g_cmdline;
|
||||||
|
char *end = s + sizeof g_cmdline;
|
||||||
|
|
||||||
|
while (s < end) {
|
||||||
|
size_t name_len = strcspn(s, "=");
|
||||||
|
|
||||||
|
if (!strncmp(s, arg_name, name_len)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = advance_to_next_arg(s, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user