1
0
src/wip/nutshell.c
2023-11-18 15:10:00 -07:00

106 lines
1.8 KiB
C

#include <ctype.h> /* isspace(3) */
#include <stddef.h> /* NULL */
#include <stdio.h> /* getc(3) */
#include <stdlib.h> /* getenv(3), rand(3), srand(3) */
#include <string.h> /* strcmp(3) */
#include <sys/wait.h> /* wait(2) */
#include <time.h> /* time(3) */
#include <unistd.h> /* fork(2), write(2) */
#include "libio.h"
#include "usefulmacros.h"
#include "nutshell.h"
#include "nutshell_builtins.c"
static int
parse_argv(char *buffer, char **argv, int argc_max){
int i;
int j;
int s;
for(i = 0, j = 0, s = 1; buffer[i] != '\0' && j < argc_max; ++i){
while(isspace(buffer[i])){
s = 1;
buffer[i++] = '\0';
}
if(s)
argv[j++] = buffer + i;
}
return j;
}
static char *
read_buffer(char *buf, size_t buf_s){
int i;
for(i = 0; ; ++i){
/* ..., '\0', buf_s */
/* This isn't perfect but is simple and doesn't matter for
* longer buffers that much. */
if(i == buf_s - 1 - 1){
buf[i] = '\0';
break;
}
buf[i] = getc(stdin);
if(buf[i] == EOF)
return NULL;
else if(buf[i] == '\n'){
buf[i + 1] = '\0';
break;
}
}
return buf;
}
static int
run(char *buf){
int argc;
static char *argv[ARGV_MAX];
int i;
/* get argv and argc */
for(i = 0; i < ARRAYLEN(argv); ++i){
if(argv[i] == NULL)
break;
argv[i] = NULL;
}
argc = parse_argv(buf, argv, ARRAYLEN(argv));
/* builtins get priority */
if((i = isbuiltin(argv[0])) != 0)
return builtins[i - 1].f(argc, argv);
if(state.jailed)
goto runerr;
runerr:
/* This is what busybox ash(1) does. */
return 127;
}
int main(int argc, char *argv[]){
static char buf[BUF_MAX];
static char prompt[] = DEFAULT_PROMPT;
builtin_init(0, empty_argv);
for(;;){
write(1, prompt, ARRAYLEN(prompt));
if(read_buffer(buf, ARRAYLEN(buf)) == NULL){
write(1, "EOF\n", 4);
state.status = 0;
break;
}
state.status = run(buf);
}
return state.status;
}