Files
kernel/usr/init.c
T
2019-12-30 04:26:16 +02:00

237 lines
4.7 KiB
C

#include <sys/fcntl.h>
#include <signal.h>
#include <dirent.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
static void dummy_handler(int signum) {
printf("Yay, no crash for this one\n");
}
static int cmd_exec(const char *cmd) {
if (!strcmp(cmd, "fork")) {
int pid = fork();
if (pid == 0) {
printf("Hello from child!\n");
exit(1);
} else {
printf("Child's PID is %d\n", pid);
return 0;
}
}
if (!strcmp(cmd, "pid")) {
printf("%d\n", getpid());
return 0;
}
if (!strcmp(cmd, "raise")) {
if (raise(SIGABRT) != 0) {
return -1;
}
return 0;
}
if (!strcmp(cmd, "crash")) {
uint32_t *value_ptr = (uint32_t *) 0;
*value_ptr = 123;
return 0;
}
if (!strcmp(cmd, "fork-crash")) {
int pid = fork();
if (pid == 0) {
printf("Crashing child\n");
uint32_t *value_ptr = (uint32_t *) 0;
*value_ptr = 123;
printf("Shouldn't run\n");
exit(-1);
}
return 0;
}
if (!strcmp(cmd, "hello")) {
int res;
if ((res = fork()) == 0) {
printf("In child\n");
res = execve("/hello", NULL, NULL);
if (res < 0) {
perror("execve()");
}
exit(-1);
}
return 0;
}
if (!strcmp(cmd, "cd") || !strncmp(cmd, "cd ", 3)) {
const char *path = cmd[2] ? cmd + 3 : "/";
int res = chdir(path);
if (res < 0) {
perror(path);
}
return res;
}
if (!strcmp(cmd, "pwd")) {
char buf[512];
if (getcwd(buf, sizeof(buf))) {
puts(buf);
}
return 0;
}
if (!strcmp(cmd, "ls") || !strncmp(cmd, "ls ", 3)) {
const char *path = cmd[2] ? cmd + 3 : ".";
DIR *dir;
struct dirent *ent;
if (!(dir = opendir(path))) {
perror(path);
return -1;
}
while ((ent = readdir(dir))) {
char type;
switch (ent->d_type) {
case DT_REG:
type = '-';
break;
case DT_DIR:
type = 'D';
break;
case DT_BLK:
type = 'b';
break;
case DT_CHR:
type = 'c';
break;
default:
type = '?';
break;
}
printf("%c %s\n", type, ent->d_name);
}
closedir(dir);
return 0;
}
if (!strncmp(cmd, "cat ", 4)) {
const char *path = cmd + 4;
char buf[512];
int fd;
ssize_t bread;
if ((fd = open(path, O_RDONLY, 0)) < 0) {
perror(path);
return -1;
}
printf("--- Begin ---\n");
while ((bread = read(fd, buf, sizeof(buf))) > 0) {
write(STDOUT_FILENO, buf, bread);
}
printf("\n--- End ---\n");
close(fd);
return 0;
}
if (!strcmp(cmd, "walk")) {
char c;
printf("\033[s");
while (read(STDIN_FILENO, &c, 1) >= 0) {
if (c == 'q') {
break;
}
switch (c) {
case 'j':
printf("\033[B");
break;
case 'k':
printf("\033[A");
break;
case 'h':
printf("\033[D");
break;
case 'l':
printf("\033[C");
break;
case 'p':
printf("\033[43;33m \033[0m\033[D");
break;
}
}
printf("\033[u");
return 0;
}
printf("Unknown command: \"%s\"\n", cmd);
return 0;
}
static void prompt(void) {
printf("\033[36mygg\033[0m > ");
}
int main(int argc, char **argv) {
char linebuf[512];
char c;
size_t l = 0;
// Install dummy handler for SIGABRT
signal(SIGABRT, dummy_handler);
prompt();
while (1) {
if (read(STDIN_FILENO, &c, 1) < 0) {
break;
}
if (c == '\b') {
if (l) {
linebuf[--l] = 0;
printf("\033[D \033[D");
}
continue;
}
if (c == '\n') {
write(STDOUT_FILENO, &c, 1);
linebuf[l] = 0;
if (!strcmp(linebuf, "exit")) {
break;
}
l = 0;
cmd_exec(linebuf);
prompt();
continue;
}
linebuf[l++] = c;
write(STDOUT_FILENO, &c, 1);
}
return -1;
}