/
apps.c
104 lines (87 loc) · 1.88 KB
/
apps.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <stdbool.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include "sched.h"
#include "usyscall.h"
#include "pool.h"
static int g_retcode;
#define APPS_X(X) \
X(echo) \
X(retcode) \
#define DECLARE(X) static int X(int, char *[]);
APPS_X(DECLARE)
#undef DECLARE
static const struct app {
const char *name;
int (*fn)(int, char *[]);
} app_list[] = {
#define ELEM(X) { # X, X },
APPS_X(ELEM)
#undef ELEM
};
static int os_printf(const char *fmt, ...) {
char buf[128];
va_list ap;
va_start(ap, fmt);
int ret = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
return os_write(1, buf, ret);
}
static int echo(int argc, char *argv[]) {
for (int i = 1; i < argc; ++i) {
printf("%s%c", argv[i], i == argc - 1 ? '\n' : ' ');
}
fflush(stdout);
return argc - 1;
}
static int retcode(int argc, char *argv[]) {
printf("%d\n", g_retcode);
fflush(stdout);
return 0;
}
static int exec(int argc, char *argv[]) {
const struct app *app = NULL;
for (int i = 0; i < ARRAY_SIZE(app_list); ++i) {
if (!strcmp(argv[0], app_list[i].name)) {
app = &app_list[i];
break;
}
}
if (!app) {
printf("Unknown command\n");
return 1;
}
g_retcode = app->fn(argc, argv);
return g_retcode;
}
int shell(int argc, char *argv[]) {
char line[256];
while (fgets(line, sizeof(line), stdin)) {
const char *comsep = "\n;";
char *stcmd;
char *cmd = strtok_r(line, comsep, &stcmd);
while (cmd) {
const char *argsep = " \t";
char *starg;
char *arg = strtok_r(cmd, argsep, &starg);
char *argv[256];
int argc = 0;
while (arg && arg[0] != '#') {
argv[argc++] = arg;
arg = strtok_r(NULL, argsep, &starg);
}
argv[argc] = NULL;
if (!argc) {
break;
}
exec(argc, argv);
cmd = strtok_r(NULL, comsep, &stcmd);
}
}
return 0;
}