Repository navigation
Expand file tree
/
Copy pathparse.c
More file actions
178 lines (152 loc) · 3.53 KB
/
Copy pathparse.c
File metadata and controls
178 lines (152 loc) · 3.53 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/**
* @author Dylan Scott dsco9564
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdbool.h>
#include "unbourne.h"
#include "parse.h"
#include "builtins.h"
#include "redirect.h"
/* parse
*
* interpret a command line and take the appropriate action.
*
* arguments:
* line - the command line to interpret
*
* returns:
* nothing
*/
void parse(char *line)
{
/* wait for child process */
bool wait = true;
/* input file for child program */
char *in_file = NULL;
/* output file for child program */
char *out_file = NULL;
/* append mode false by default */
bool append = false;
/* list of arguments */
char *args[ARGS_SIZE];
/* pointer to current argument */
char **arg = args;
/* start tokenising the arguments */
*arg++ = strtok(line, DELIMITERS);
/* tokenise the remaining argumetns */
while((*arg++ = strtok(NULL, DELIMITERS)));
arg = args;
/* check arguments for redirection and background commands */
while(*arg)
{
/* if input redirect requested */
if(strcmp(*arg, IN_REDIRECT_CMD) == 0)
{
/* set this argument to null and move to the next */
*arg++ = NULL;
/* set input file */
in_file = *arg;
}
/* if output redirect requested */
else if(strcmp(*arg, OUT_REDIRECT_CMD) == 0)
{
/* set this argument to null and move to the next */
*arg++ = NULL;
/* set output file */
out_file = *arg;
}
/* if output redirect requested */
else if(strcmp(*arg, APPEND_REDIRECT_CMD) == 0)
{
/* set this argument to null and move to the next */
*arg++ = NULL;
/* set output file */
out_file = *arg;
/* set append mode */
append = true;
}
/* if background requested */
else if(strcmp(*arg, BACKGROUND_CMD) == 0)
{
/* set this argument to null and move to the next */
*arg++ = NULL;
/* do not wait for child process */
wait = false;
}
arg++;
}
/* if there are some arguments */
if(*args != NULL)
{
/* the command is the first argument */
char *cmd = args[0];
/* pointer to current built-in command */
struct builtin *builtin = builtins;
/* try to match the cmd with the internal commands */
while(builtin->cmd != NULL && builtin->func != NULL)
{
/* if cmd matches a built-in command */
if(strcmp(cmd, builtin->cmd) == 0)
{
break;
}
/* move to the next built in command */
builtin++;
}
/* if we could not find an internal command or the command is a fork command */
if(builtin->func == NULL || builtin->fork == true)
{
/* create another process */
switch(child_pid = fork())
{
/* fork error */
case -1:
/* show error */
perror("fork");
/* this process is the child process */
case 0:
/* do any redirects */
redirect(in_file, out_file, append);
/* set parent variable */
setenv(PARENT_VAR, getenv(SHELL_VAR), 1);
/* if this is not a built-in command */
if(builtin->func == NULL)
{
/* switch process */
if(execvp(args[0], args) == -1)
{
perror("exec");
abort();
}
}
/* if this is a built-in command */
else
{
/* run the built-in function */
builtin->func(args);
exit(EXIT_SUCCESS);
}
/* this process is the parent process */
default:
/* if wait is requested */
if(wait)
{
/* wait for child process */
waitpid(child_pid, NULL, 0);
}
child_pid = 0;
}
}
else
{
/* run the built-in command */
builtin->func(args);
}
}
}