-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathbuiltins.c
More file actions
124 lines (104 loc) · 2.13 KB
/
builtins.c
File metadata and controls
124 lines (104 loc) · 2.13 KB
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/* see LICENSE file for copyright and license details */
/* user commands built directly into s */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#ifdef __linux__
#include <linux/limits.h>
#endif
#include "reporting.h"
#include "region.h"
#include "stringport.h"
#include "tokenizer.h"
#include "variables.h"
#include "parser.h"
#include "interpreter.h"
#include "builtins.h"
#include "util.h"
char cwd[PATH_MAX];
char owd[PATH_MAX];
Builtin builtins[] = {
{ "source", &builtin_source },
{ "cd", &builtin_cd },
{ "set", &builtin_set },
{ "unset", &builtin_unset },
{ "exit", &builtin_exit },
};
int
perform_builtin(struct AST *n)
{
size_t i;
if (n->type != NODE_COMMAND || !n->node.tokens[0])
return 0;
for (i = 0; i < LEN(builtins); i++)
if (!strcmp(builtins[i].name, n->node.tokens[0])) {
(*builtins[i].func)(n->node.tokens);
return 1;
}
return 0;
}
void
builtin_source(char **argv)
{
FILE *f;
int mode;
if (!argv[1])
reportret(,"%s: argument required", argv[0]);
if (!(f = fopen(argv[1], "r")))
reportret(,"%s: %s: could not load file", argv[0], argv[1]);
mode = interactive_mode;
interactive_mode = 0;
vars_set(argv);
interpreter_loop(f);
interactive_mode = mode;
}
void
builtin_cd(char **argv)
{
char *dir;
int isowd = 0;
if (!(dir = argv[1])) {
if (!(dir = getenv("HOME")))
reportret(,"%s: invalid $HOME", argv[0]);
} else if (strcmp(dir, "-") == 0) {
if (!(dir = getenv("OWD")))
reportret(,"%s: invalid $OWD", argv[0]);
isowd = 1;
}
getcwd(owd, PATH_MAX);
if (chdir(dir)) {
report("%s: %s: could not change to directory", argv[0], dir);
} else {
getcwd(cwd, PATH_MAX);
setenv("PWD", cwd, 1);
setenv("OWD", owd, 1);
if (isowd)
printf("%s\n", dir);
}
}
void
builtin_set(char **argv)
{
if (argv[1] && argv[2])
setenv(argv[1], argv[2], INT_MAX);
else
report("%s: two arguments required", argv[0]);
}
void
builtin_unset(char **argv)
{
if (argv[1])
unsetenv(argv[1]);
else
report("%s: argument required", argv[0]);
}
void
builtin_exit(char **argv)
{
if (!argv[1])
exit(0);
else
exit(strtol(argv[1], NULL, 0));
}