131 lines
2.5 KiB
C
131 lines
2.5 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, "sig")) {
|
|
if (kill(1, 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, "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))) {
|
|
printf("%c %s\n", ent->d_type == DT_DIR ? 'D' : '-', ent->d_name);
|
|
}
|
|
|
|
closedir(dir);
|
|
|
|
return 0;
|
|
}
|
|
|
|
printf("Unknown command: \"%s\"\n", cmd);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
char linebuf[512];
|
|
char c;
|
|
size_t l = 0;
|
|
|
|
// Install dummy handler for SIGABRT
|
|
signal(SIGABRT, dummy_handler);
|
|
|
|
printf("> ");
|
|
while (1) {
|
|
if (read(STDIN_FILENO, &c, 1) < 0) {
|
|
break;
|
|
}
|
|
|
|
if (c == '\n') {
|
|
write(STDOUT_FILENO, &c, 1);
|
|
linebuf[l] = 0;
|
|
|
|
if (!strcmp(linebuf, "exit")) {
|
|
break;
|
|
}
|
|
|
|
l = 0;
|
|
cmd_exec(linebuf);
|
|
printf("> ");
|
|
continue;
|
|
}
|
|
|
|
linebuf[l++] = c;
|
|
write(STDOUT_FILENO, &c, 1);
|
|
}
|
|
|
|
return -1;
|
|
}
|