Compare commits
8 Commits
02a5d8b418
...
c0f91dcced
| Author | SHA1 | Date | |
|---|---|---|---|
| c0f91dcced | |||
| 0d05abf282 | |||
| 7d81e39de5 | |||
| 257f494b0c | |||
| fc97d56eb5 | |||
| ee93463c64 | |||
| d92a652024 | |||
| b717387adb |
@ -2,3 +2,4 @@ mkalias pctl base:/bin/pctl
|
||||
mkalias tb base:/bin/tb
|
||||
mkalias fs base:/bin/fs
|
||||
mkalias dev base:/bin/dev
|
||||
mkalias rc base:/bin/rc
|
||||
|
||||
@ -19,6 +19,7 @@ size_t hal_strspn(const char *s, const char *accept);
|
||||
char *hal_strcpy(char *dest, const char *src);
|
||||
char *hal_strchr(const char *s, int c);
|
||||
void hal_wait(uint32_t ms);
|
||||
int32_t hal_randnum(void);
|
||||
|
||||
#define HAL_PAGE_SIZE 0x1000
|
||||
#include "x86_64/vmm.h"
|
||||
|
||||
13
kernel/hal/x86_64/randnum.S
Normal file
13
kernel/hal/x86_64/randnum.S
Normal file
@ -0,0 +1,13 @@
|
||||
.global hal_randnum
|
||||
hal_randnum:
|
||||
mov $100, %ecx
|
||||
xor %eax, %eax
|
||||
|
||||
.retry:
|
||||
rdrand %eax
|
||||
jc .done
|
||||
loop .retry
|
||||
.fail:
|
||||
mov $-1, %eax
|
||||
.done:
|
||||
ret
|
||||
@ -3,6 +3,7 @@
|
||||
#include "uniqid.h"
|
||||
#include "atomic.h"
|
||||
#include "spinlock/spinlock.h"
|
||||
#include "hal/hal.h"
|
||||
|
||||
static const char *base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
@ -22,6 +23,22 @@ uint32_t uniqmix32(uint32_t x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
void uniqseed(void) {
|
||||
if (uniqstate != 0u)
|
||||
return;
|
||||
|
||||
uint32_t seed = 0;
|
||||
int32_t r = hal_randnum();
|
||||
if (r != -1) {
|
||||
seed = (uint32_t)r;
|
||||
} else {
|
||||
uintptr_t p = (uintptr_t)(void *)&uniqstate;
|
||||
seed = (uint32_t)(p ^ (p>>32)) ^ 0x9E3779B9u;
|
||||
}
|
||||
|
||||
uniqstate = seed ? seed : 1u;
|
||||
}
|
||||
|
||||
void randcrypto_gen_uniqid(char *out, size_t n) {
|
||||
if (!out || n == 0) {
|
||||
return;
|
||||
@ -29,14 +46,10 @@ void randcrypto_gen_uniqid(char *out, size_t n) {
|
||||
|
||||
spinlock_acquire(&uniqstate_spinlock);
|
||||
|
||||
if (uniqstate == 0u) {
|
||||
uintptr_t p = (uintptr_t)(void *)&uniqstate;
|
||||
uint32_t seed = (uint32_t)(p ^ (p >> 16));
|
||||
uniqstate = seed ^ 0x9E3779B9u;
|
||||
if (uniqstate == 0u) {
|
||||
uniqstate = 1u;
|
||||
}
|
||||
}
|
||||
uniqseed();
|
||||
|
||||
int32_t r = hal_randnum();
|
||||
uint32_t extra = (r != -1) ? (uint32_t)r : uniqstate * 0x27d4eb2dU;
|
||||
|
||||
uniqstate += 0x9E3779B1u;
|
||||
uint32_t v = uniqmix32(uniqstate);
|
||||
@ -44,7 +57,7 @@ void randcrypto_gen_uniqid(char *out, size_t n) {
|
||||
spinlock_release(&uniqstate_spinlock);
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
v = uniqmix32(v + i * 0x27d4eb2dU);
|
||||
v = uniqmix32(v + i * 0x85ebca6bU);
|
||||
out[i] = base62[v % 62u];
|
||||
}
|
||||
out[n] = '\0';
|
||||
|
||||
8
kernel/syscall/randcrypto.c
Normal file
8
kernel/syscall/randcrypto.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "hal/hal.h"
|
||||
#include "syscall.h"
|
||||
|
||||
int32_t SYSCALL0(sys_rand) {
|
||||
return hal_randnum();
|
||||
}
|
||||
8
kernel/syscall/randcrypto.h
Normal file
8
kernel/syscall/randcrypto.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef SYSCALL_RANDCRYPTO_H_
|
||||
#define SYSCALL_RANDCRYPTO_H_
|
||||
|
||||
#include "syscall.h"
|
||||
|
||||
int32_t SYSCALL0(sys_rand);
|
||||
|
||||
#endif // SYSCALL_RANDCRYPTO_H_
|
||||
@ -9,6 +9,7 @@
|
||||
#include "mman.h"
|
||||
#include "sched.h"
|
||||
#include "devctl.h"
|
||||
#include "randcrypto.h"
|
||||
|
||||
int32_t SYSCALL1(sys_debugprint, string) {
|
||||
char *p = (char *)string;
|
||||
@ -25,4 +26,5 @@ SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = {
|
||||
[SYS_MMAN_UNMAP] = &sys_mman_unmap,
|
||||
[SYS_SCHEDRELEASE] = &sys_schedrelease,
|
||||
[SYS_DEVCTL] = &sys_devctl,
|
||||
[SYS_RAND] = &sys_rand,
|
||||
};
|
||||
|
||||
@ -9,5 +9,6 @@
|
||||
#define SYS_MMAN_UNMAP 6
|
||||
#define SYS_SCHEDRELEASE 7
|
||||
#define SYS_DEVCTL 8
|
||||
#define SYS_RAND 9
|
||||
|
||||
#endif // SHARE_HDRS_SYSCALL_H_
|
||||
|
||||
@ -39,3 +39,7 @@ int32_t schedrelease(void) {
|
||||
int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t extra) {
|
||||
return syscall(SYS_DEVCTL, (uint64_t)devh, cmd, (uint64_t)buffer, (uint64_t)len, (uint64_t)extra, 0);
|
||||
}
|
||||
|
||||
int32_t rand(void) {
|
||||
return syscall(SYS_RAND, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
@ -13,5 +13,6 @@ int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint
|
||||
int32_t mman_unmap(uint8_t *addr);
|
||||
int32_t schedrelease(void);
|
||||
int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t extra);
|
||||
int32_t rand(void);
|
||||
|
||||
#endif // ULIB_SYSTEM_SYSTEM_H_
|
||||
|
||||
@ -2,6 +2,29 @@
|
||||
#include <stdint.h>
|
||||
#include <ulib.h>
|
||||
|
||||
struct {
|
||||
bool plain;
|
||||
bool names;
|
||||
bool sizes;
|
||||
bool types;
|
||||
bool humsz;
|
||||
} FS_FETCH_CONFIG = {
|
||||
.plain = false,
|
||||
.names = true,
|
||||
.sizes = true,
|
||||
.types = true,
|
||||
.humsz = true,
|
||||
};
|
||||
|
||||
static Arg ARGS[] = {
|
||||
ARG("-p", ARG_BOOL, &FS_FETCH_CONFIG.plain),
|
||||
ARG("-n", ARG_BOOL, &FS_FETCH_CONFIG.names),
|
||||
ARG("-s", ARG_BOOL, &FS_FETCH_CONFIG.sizes),
|
||||
ARG("-t", ARG_BOOL, &FS_FETCH_CONFIG.types),
|
||||
ARG("-h", ARG_BOOL, &FS_FETCH_CONFIG.humsz),
|
||||
ARG_END(),
|
||||
};
|
||||
|
||||
void fs_fetch(void) {
|
||||
if (argslen() < 2) {
|
||||
uprintf("fs: Not enough arguments\n");
|
||||
@ -10,6 +33,17 @@ void fs_fetch(void) {
|
||||
|
||||
char *path = *(args()+1);
|
||||
|
||||
int32_t ret;
|
||||
if ((ret = parse_args(args()+2, argslen()-2, ARGS)) < 0) {
|
||||
uprintf("fs: could not parse args: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if (FS_FETCH_CONFIG.plain) {
|
||||
FS_FETCH_CONFIG.sizes = false;
|
||||
FS_FETCH_CONFIG.types = false;
|
||||
}
|
||||
|
||||
IoctlStat statbuf; ZERO(&statbuf);
|
||||
if (ioctl(IOCTL_NOHANDLE, IOCTL_STAT, (uint64_t)&statbuf, (uint64_t)path, 0) != E_OK) {
|
||||
uprintf("fs: could not stat %s\n", path);
|
||||
@ -44,22 +78,51 @@ void fs_fetch(void) {
|
||||
|
||||
IoctlDirent *dirent = &dirents[i];
|
||||
|
||||
|
||||
if (dirent->stat.type == IOCTLSTAT_FILE) {
|
||||
char *membuf = umalloc(20);
|
||||
uprintf("%-30s %-15s %-1s\n",
|
||||
dirent->name,
|
||||
human_size(dirent->stat.size, membuf, 20),
|
||||
"F"
|
||||
);
|
||||
ufree(membuf);
|
||||
} else if (dirent->stat.type == IOCTLSTAT_DIR) {
|
||||
uprintf("%-30s %-15s %-1s\n",
|
||||
dirent->name,
|
||||
"-",
|
||||
"D"
|
||||
);
|
||||
if (FS_FETCH_CONFIG.names) {
|
||||
if (FS_FETCH_CONFIG.plain) {
|
||||
uprintf("%s ", dirent->name);
|
||||
} else {
|
||||
uprintf("%-30s ", dirent->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (FS_FETCH_CONFIG.sizes) {
|
||||
if (dirent->stat.type == IOCTLSTAT_FILE) {
|
||||
if (FS_FETCH_CONFIG.humsz) {
|
||||
char *membuf = umalloc(20);
|
||||
|
||||
if (FS_FETCH_CONFIG.plain) {
|
||||
uprintf("%s ", human_size(dirent->stat.size, membuf, 20));
|
||||
} else {
|
||||
uprintf("%-15s ", human_size(dirent->stat.size, membuf, 20));
|
||||
}
|
||||
|
||||
ufree(membuf);
|
||||
} else {
|
||||
if (FS_FETCH_CONFIG.plain) {
|
||||
uprintf("%zu ", dirent->stat.size);
|
||||
} else {
|
||||
uprintf("%-15zu ", dirent->stat.size);
|
||||
}
|
||||
}
|
||||
} else if (dirent->stat.type == IOCTLSTAT_DIR) {
|
||||
if (FS_FETCH_CONFIG.plain) {
|
||||
uprintf("- ");
|
||||
} else {
|
||||
uprintf("%-15c ", '-');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FS_FETCH_CONFIG.types) {
|
||||
if (dirent->stat.type == IOCTLSTAT_FILE) {
|
||||
uprintf("%c ", 'F');
|
||||
} else if (dirent->stat.type == IOCTLSTAT_DIR) {
|
||||
uprintf("%c ", 'D');
|
||||
}
|
||||
}
|
||||
|
||||
uprintf("\n");
|
||||
}
|
||||
|
||||
ufree(dirents);
|
||||
|
||||
2
user/rc/.gitignore
vendored
Normal file
2
user/rc/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.o
|
||||
rc
|
||||
24
user/rc/Makefile
Normal file
24
user/rc/Makefile
Normal file
@ -0,0 +1,24 @@
|
||||
include $(ROOT)/mk/grabsrc.mk
|
||||
include ../Makefile.inc
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
TARGET := rc
|
||||
|
||||
LDFLAGS += -L$(ROOT)/ulib -l:libulib.a
|
||||
|
||||
SRCFILES := $(call GRABSRC, .)
|
||||
CFILES := $(call GET_CFILES, $(SRCFILES))
|
||||
OBJ := $(call GET_OBJ, $(SRCFILES))
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJ)
|
||||
$(LD) $^ $(LDFLAGS) -o $@
|
||||
echo $$(realpath $(TARGET)) >> $(FILES)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) $(TARGET)
|
||||
24
user/rc/main.c
Normal file
24
user/rc/main.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <ulib.h>
|
||||
|
||||
#define CMDS(X) \
|
||||
X(rr) \
|
||||
|
||||
void main(void) {
|
||||
if (argslen() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *cmd = args()[0];
|
||||
|
||||
#define X(name) if (string_strcmp(cmd, #name) == 0) { \
|
||||
extern void rc_ ## name(void); \
|
||||
rc_ ## name(); \
|
||||
return; \
|
||||
}
|
||||
CMDS(X)
|
||||
#undef X
|
||||
|
||||
uprintf("rc: unknown command %s\n", cmd);
|
||||
}
|
||||
50
user/rc/rr.c
Normal file
50
user/rc/rr.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ulib.h>
|
||||
|
||||
int32_t rr(int32_t min, int32_t max) {
|
||||
if (max <= min)
|
||||
return min;
|
||||
|
||||
uint32_t range = (uint32_t)(max - min + 1);
|
||||
uint32_t val;
|
||||
int32_t rnd;
|
||||
|
||||
for (size_t i = 0; i < 10; i++) {
|
||||
rnd = rand();
|
||||
if (rnd == -1)
|
||||
continue;
|
||||
|
||||
val = (uint32_t)rnd;
|
||||
|
||||
uint32_t limit = (uint32_t)(-range) % range;
|
||||
if (val >= limit) {
|
||||
return min + (val % range);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void rc_rr(void) {
|
||||
if (argslen() < 3) {
|
||||
uprintf("rc: Not enough arguments\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char *beginstr = *(args()+1);
|
||||
char *endstr = *(args()+2);
|
||||
|
||||
char *endb;
|
||||
long begin = string_conv_strtol(beginstr, &endb, 10);
|
||||
char *ende;
|
||||
long end = string_conv_strtol(endstr, &ende, 10);
|
||||
|
||||
int32_t r = rr(begin, end);
|
||||
if (r == -1) {
|
||||
uprintf("rc: failed to generate random number in range\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uprintf("%d\n", r);
|
||||
}
|
||||
Reference in New Issue
Block a user