Add initial implementation of sysctl(8)

Needs a bit of cleanup (avoiding magic numbers etc.).
This commit is contained in:
sin 2014-04-17 15:18:38 +01:00
parent c354e5e1d3
commit 8b32decb6f
5 changed files with 151 additions and 2 deletions

View File

@ -47,6 +47,7 @@ SRC = \
swapoff.c \ swapoff.c \
swapon.c \ swapon.c \
switch_root.c \ switch_root.c \
sysctl.c \
truncate.c \ truncate.c \
umount.c \ umount.c \
unshare.c \ unshare.c \
@ -92,6 +93,7 @@ MAN8 = \
swapoff.8 \ swapoff.8 \
swapon.8 \ swapon.8 \
switch_root.8 \ switch_root.8 \
sysctl.8 \
umount.8 umount.8
OBJ = $(SRC:.c=.o) $(LIB) OBJ = $(SRC:.c=.o) $(LIB)

2
README
View File

@ -9,7 +9,7 @@ The following programs are currently implemented:
chvt clear ctrlaltdel df dmesg eject fallocate free getty halt id chvt clear ctrlaltdel df dmesg eject fallocate free getty halt id
insmod killall5 lsmod lsusb mknod mkswap mount mountpoint pagesize insmod killall5 lsmod lsusb mknod mkswap mount mountpoint pagesize
pidof pivot_root ps respawn rmmod stat su swapoff swapon pidof pivot_root ps respawn rmmod stat su swapoff swapon
switch_root truncate umount unshare uptime watch who switch_root sysctl truncate umount unshare uptime watch who
The complement of ubase is sbase[1] which mostly follows POSIX and The complement of ubase is sbase[1] which mostly follows POSIX and
provides all the portable tools. Together they are intended to form a provides all the portable tools. Together they are intended to form a

1
TODO
View File

@ -6,7 +6,6 @@ Tools
* swaplabel(8) * swaplabel(8)
* last(1) * last(1)
* losetup(8) * losetup(8)
* sysctl
* lspci * lspci
* mkswap [-L] * mkswap [-L]
* passwd * passwd

9
sysctl.8 Normal file
View File

@ -0,0 +1,9 @@
.TH SYSCTL 8 ubase-VERSION
.SH NAME
\fBsysctl\fR - Configure kernel parameters at runtime
.SH SYNOPSIS
\fBsysctl\fR \fIvariable\fR[=\fIvalue\fR]...
.SH DESCRIPTION
\fBsysctl\fR modifies kernel parameters at runtime. The parameters available
are those listed under \fI/proc/sys/\fR. Procfs is required for sysctl support
in Linux. You can use \fBsysctl\fR to both read and write sysctl data.

139
sysctl.c Normal file
View File

@ -0,0 +1,139 @@
/* See LICENSE file for copyright and license details. */
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "util.h"
static int
getsysctl(char *variable, char **value)
{
char path[PATH_MAX];
char *p;
char *buf;
int fd;
ssize_t n;
for (p = variable; *p; p++)
if (*p == '.')
*p = '/';
strlcpy(path, "/proc/sys/", sizeof(path));
if (strlcat(path, variable, sizeof(path)) >= sizeof(path))
return -1;
fd = open(path, O_RDONLY);
if (fd < 0)
return -1;
buf = malloc(1024);
if (!buf) {
close(fd);
return -1;
}
n = read(fd, buf, 1023);
if (n <= 0) {
close(fd);
free(buf);
return -1;
}
buf[n] = '\0';
p = strrchr(buf, '\n');
if (p)
*p = '\0';
*value = buf;
close(fd);
return 0;
}
static int
setsysctl(char *variable, char *value)
{
char path[PATH_MAX];
char *p;
int fd;
ssize_t n;
for (p = variable; *p; p++)
if (*p == '.')
*p = '/';
strlcpy(path, "/proc/sys/", sizeof(path));
if (strlcat(path, variable, sizeof(path)) >= sizeof(path))
return -1;
fd = open(path, O_WRONLY);
if (fd < 0)
return -1;
n = write(fd, value, strlen(value));
if (n != (ssize_t)strlen(value)) {
close(fd);
return -1;
}
close(fd);
return 0;
}
static void
usage(void)
{
eprintf("usage: %s variable[=value]...\n", argv0);
}
int
main(int argc, char *argv[])
{
char *variable;
char *value;
char *p;
int i;
argv0 = argv[0];
argv++;
argc--;
if (argc < 1)
usage();
for (i = 0; i < argc; i++) {
value = NULL;
variable = argv[i];
p = strchr(variable, '=');
if (p) {
if (p[1] == '\0') {
weprintf("malformed sysctl: %s\n", argv[i]);
continue;
}
*p = '\0';
value = &p[1];
}
if (variable) {
if (value) {
if (setsysctl(variable, value) < 0) {
weprintf("failed to set sysctl for %s\n", variable);
continue;
}
}
else {
if (getsysctl(variable, &value) < 0) {
weprintf("failed to get sysctl for %s\n", variable);
continue;
}
printf("%s = %s\n", variable, value);
free(value);
}
}
}
return EXIT_SUCCESS;
}