builtins.c (1396B) download
1#include <errno.h>
2#include <fmt.h>
3#include <stdio.h>
4#include <string.h>
5#include <unistd.h>
6
7#define MAXENV 256
8
9
10extern char* envp[];
11extern int envc;
12
13int envset(char* s) {
14 char* l;
15
16 if (!(l = strchr(s, '='))) return -1;
17
18 for (int i = 0; i < envc && envp[i]; i++)
19 if (strncmp(envp[i], s, l - s) == 0) {
20 envp[i] = s;
21 return 0;
22 }
23
24 if (envc < MAXENV) {
25 envp[envc++] = s;
26 envp[envc] = 0;
27 return 0;
28 }
29 return -1;
30}
31
32
33int chdir_builtin(int argc, char** argv) {
34 if (argc != 2) {
35 fprint(1, "usage: %s <path>\n", argv[0]);
36 return 1;
37 }
38
39 if (chdir(argv[1]) == -1) {
40 fprint(1, "%s: unable to change dir to '%s': %s\n", argv[0], argv[1], strerror(errno));
41 return 1;
42 }
43 return 0;
44}
45
46int export_builtin(int argc, char** argv) {
47 if (argc == 1) {
48 for (int i = 0; i < envc; i++)
49 print("%s\n", envp[i]);
50 return 0;
51 }
52
53 for (int i = 1; i < argc; i++) {
54 if (envset(argv[i]) == -1)
55 return 1;
56 }
57 return 0;
58}
59
60int execute(FILE*);
61
62int source_builtin(int argc, char** argv) {
63 FILE* f;
64 if (argc != 2) {
65 fprint(1, "source <file>\n");
66 return 1;
67 }
68 THROW_NULL(f = fopen(argv[1], "r"), "unable to open %s", 1, argv[1]);
69 return execute(f);
70}
71
72const struct builtin {
73 const char* name;
74 int (*func)(int argv, char** argc);
75} builtins[] = {
76 { "cd", chdir_builtin },
77 { "export", export_builtin },
78 { ".", source_builtin },
79 { "source", source_builtin },
80 { 0 }
81};