Skip to content

Commit

Permalink
Merge pull request #1897 from ghaerr/sysctl
Browse files Browse the repository at this point in the history
[kernel,cmds] Add sysctl system call and option get/set command
  • Loading branch information
ghaerr authored May 8, 2024
2 parents fdc58de + 36d4855 commit 3c9b431
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 3 deletions.
2 changes: 1 addition & 1 deletion elks/arch/i86/kernel/strace.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ struct sc_info elks_table1[] = {
ENTRY("sbrk", packinfo(1, P_SSHORT, P_NONE, P_NONE )),
ENTRY("ustatfs", packinfo(3, P_USHORT, P_PDATA, P_SSHORT )), // 70
ENTRY("setitimer", packinfo(3, P_SSHORT, P_PDATA, P_PDATA )),
ENTRY(0, packinfo(0, P_NONE, P_NONE, P_NONE )),
ENTRY("sysctl", packinfo(3, P_SSHORT, P_STR, P_SSHORT )),
ENTRY(0, packinfo(0, P_NONE, P_NONE, P_NONE )),
ENTRY("uname", packinfo(1, P_PDATA, P_NONE, P_NONE )), // 74
};
Expand Down
1 change: 1 addition & 0 deletions elks/arch/i86/kernel/syscall.dat
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ setsid +68 0
sbrk +69 2 * Legacy number from Linux
ustatfs +70 3
setitimer +71 3
sysctl +72 3 . ELKS
uname +74 1 . was knlvsn
#
# From /usr/include/asm-generic/unistd.h
Expand Down
1 change: 1 addition & 0 deletions elks/include/linuxmt/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

extern char running_qemu;
extern dev_t dev_console;
extern int dprintk_on;

extern void do_exit(int) noreturn;

Expand Down
12 changes: 12 additions & 0 deletions elks/include/linuxmt/sysctl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef __LINUXMT_SYSCTL_H
#define __LINUXMT_SYSCTL_H

/* sysctl(2) parameters */

#define CTL_MAXNAMESZ 32 /* max size of option name */

#define CTL_LIST 0 /* get option list from index */
#define CTL_GET (-1) /* get option value by name */
#define CTL_SET (-2) /* set option value by name */

#endif
1 change: 0 additions & 1 deletion elks/init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ static char *envp_init[MAX_INIT_ENVS+1];
static unsigned char options[OPTSEGSZ];

extern int boot_rootdev;
extern int dprintk_on;
static char * INITPROC root_dev_name(int dev);
static int INITPROC parse_options(void);
static void INITPROC finalize_options(void);
Expand Down
2 changes: 1 addition & 1 deletion elks/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ include $(BASEDIR)/Makefile-rules

# unused: wait.o lock.o
OBJS = sched.o printk.o sleepwake.o version.o sys.o sys2.o fork.o \
exit.o time.o signal.o
exit.o time.o signal.o sysctl.o

#########################################################################
# Commands:
Expand Down
63 changes: 63 additions & 0 deletions elks/kernel/sysctl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <linuxmt/mm.h>
#include <linuxmt/errno.h>
#include <linuxmt/string.h>
#include <linuxmt/sysctl.h>

#include <linuxmt/trace.h>
#include <linuxmt/kernel.h>

struct sysctl {
const char *name;
int *value;
};

static int malloc_debug;
static int net_debug;

struct sysctl sysctl[] = {
{ "kern.debug", &dprintk_on }, /* debug (^P) on/off */
{ "kern.strace", &tracing }, /* strace=1, kstack=2 */
{ "kern.console", (int *)&dev_console }, /* console */
{ "malloc.debug", &malloc_debug },
{ "net.debug", &net_debug },
};

static char ctlname[CTL_MAXNAMESZ];

#define ARRAYLEN(a) (sizeof(a)/sizeof(a[0]))

int sys_sysctl(int op, char *name, int *value)
{
int error, n;
struct sysctl *sc;

if (op >= CTL_LIST) {
if (!name)
return -EFAULT;
if (op >= ARRAYLEN(sysctl))
return -ENOTDIR;
sc = &sysctl[op];
return verified_memcpy_tofs(name, (void *)sc->name, strlen(sc->name)+1);
}

n = strlen_fromfs(name, CTL_MAXNAMESZ) + 1;
if (n >= CTL_MAXNAMESZ) return -EFAULT;
error = verified_memcpy_fromfs(ctlname, name, n);
if (error) return error;
error = verfy_area(value, sizeof(int));
if (error) return error;

for (sc = sysctl;; sc++) {
if (sc >= &sysctl[ARRAYLEN(sysctl)]) return -ENOTDIR;
if (!strcmp(sc->name, ctlname))
break;
}

if (op == CTL_GET)
put_user(*sc->value, value);
else if (op == CTL_SET)
*sc->value = get_user(value);
else
return -EINVAL;
return 0;
}
1 change: 1 addition & 0 deletions elkscmd/Applications
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ sys_utils/console :sysutil :1200k
sys_utils/unreal16 :sysutil :1440c
sys_utils/beep :sysutil :1200k
sys_utils/decomp :sysutil :360c :1440k
sys_utils/sysctl :sysutil :1200k
screen/screen :screen :1200k
cron/cron :cron :1200k
cron/crontab :cron :1200k
Expand Down
1 change: 1 addition & 0 deletions elkscmd/sys_utils/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ps
reboot
sercat
shutdown
sysctl
umount
unreal16
who
4 changes: 4 additions & 0 deletions elkscmd/sys_utils/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ PRGS = \
console \
makeboot \
decomp \
sysctl \
# EOL

HOSTPRGS = hostdecomp
Expand Down Expand Up @@ -125,6 +126,9 @@ unreal.o: $(ELKS_LIB)/unreal.S
beep: beep.o
$(LD) $(LDFLAGS) -o beep beep.o $(LDLIBS)

sysctl: sysctl.o
$(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)

unreal16: unreal16.o unreal.o
$(LD) -melks-libc -mcmodel=small -c unreal16.S -o unreal16.o
$(LD) -melks-libc -mcmodel=small -nostdlib -o unreal16 unreal16.o unreal.o
Expand Down
105 changes: 105 additions & 0 deletions elkscmd/sys_utils/sysctl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* sysctl - system control utility for ELKS
*
* 8 May 2024 Greg Haerr
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
#include <sys/sysctl.h>

#define errmsg(str) write(STDERR_FILENO, str, sizeof(str) - 1)

static int digit(char c, int base)
{
int d;
if (c <= '9') {
d = c - '0';
} else if (c < 'A') { /* NEATLIBC bugfix */
return -1;
} else if (c <= 'Z') {
d = 10 + c - 'A';
} else {
d = 10 + c - 'a';
}
return d < base ? d : -1;
}

static int strtoi(const char *s)
{
int num;
int dig;
int base;
int sgn = 1;

if (*s == '-')
sgn = ',' - *s++;
if (*s == '0') {
if (s[1] == 'x' || s[1] == 'X') {
base = 16;
s += 2;
} else
base = 8;
} else {
base = 10;
}
for (num = 0; (dig = digit(*s, base)) >= 0; s++)
num = num*base + dig;
num *= sgn;
return num;
}

static void msg(int fd, const char *s, ...)
{
va_list va;

va_start(va, s);
do {
write(fd, s, strlen(s));
s = va_arg(va, const char *);
} while (s);
va_end(va);
}

int main(int ac, char **av)
{
int i, ret, val;
char name[CTL_MAXNAMESZ];

if (ac < 2) {
errmsg("usage: sysctl [-a] [name[=value]]\n");
exit(-1);
}

if (av[1][0] == '-' && av[1][1] == 'a') {
for (i = 0;; i++) {
ret = sysctl(CTL_LIST+i, name, 0);
if (ret) exit(0);
ret = sysctl(CTL_GET, name, &val);
msg(STDOUT_FILENO, name, "=", itoa(val), "\n", 0);
}
}

for (i = 1; i < ac; i++) {
char *p = strchr(av[i], '=');
if (p) {
*p = '\0';
val = strtoi(p+1);
ret = sysctl(CTL_SET, av[i], &val);
if (ret) {
msg(STDOUT_FILENO, "Unknown option: ", av[i], "\n", 0);
continue;
}
}
ret = sysctl(CTL_GET, av[i], &val);
if (ret)
msg(STDERR_FILENO, "Invalid option: ", av[i], "\n", 0);
else {
msg(STDOUT_FILENO, av[i], "=", itoa(val), "\n", 0);
}
}
return ret;
}
9 changes: 9 additions & 0 deletions libc/include/sys/sysctl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef __SYS_SYSCTL_H
#define __SYS_SYSCTL_H

#include <features.h>
#include __SYSINC__(sysctl.h)

int sysctl(int op, char *name, int *value);

#endif

0 comments on commit 3c9b431

Please sign in to comment.