forked from dpocheng2/sparkling-roaring-lion
-
Notifications
You must be signed in to change notification settings - Fork 0
/
shellex.c
141 lines (119 loc) · 3.53 KB
/
shellex.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
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
/* $begin shellmain */
#include "csapp.h"
#define MAXARGS 128
/* function prototypes */
void eval(char *cmdline);
int parseline(char *buf, char **argv);
int builtin_command(char **argv);
int main()
{
char cmdline[MAXLINE]; /* Command line */
while (1) {
/* Read */
printf("prompt> ");
Fgets(cmdline, MAXLINE, stdin);
if (feof(stdin)) {
exit(0);
}
/* Evaluate */
eval(cmdline);
}
}
/* $end shellmain */
/* $begin eval */
/* eval - Evaluate a command line */
void eval(char *cmdline)
{
char *argv[MAXARGS]; /* Argument list execve() */
char buf[MAXLINE]; /* Holds modified command line */
int bg; /* Should the job run in bg or fg? */
pid_t pid; /* Process id */
int ip, op;
strcpy(buf, cmdline);
bg = parseline(buf, argv);
if (argv[0] == NULL) {
return; /* Ignore empty lines */
}
if (!builtin_command(argv)) {
if ((pid = Fork()) == 0) { /* Child runs user job */
if (execve(argv[0], argv, environ) < 0) {
printf("%s: Command not found.\n", argv[0]);
exit(0);
}
/*if (execve(argv[1], argv, environ) < 0) {
printf("%s: Command not found.\n", argv[1]);
exit(0);
}*/
}
/* Parent waits for foreground job to terminate */
if (!bg) {
int status;
if (waitpid(pid, &status, 0) < 0) {
unix_error("waitfg: waitpid error");
}
}
else {
printf("%d %s", pid, cmdline);
// WNOHANG|WUNTRACED: Return immediately, with a return value of 0, if
// the child process has stopped or terminated, or with a return value
// equal to the child process pid if the child process stopped or terminated
int childStatus;
waitpid(pid, &childStatus, WNOHANG|WUNTRACED);
}
/*if(*argv[1] == '<') {
//dup2(ip, op);
//read(ip, cmdline, 1);
printf("testing\n");
}
else if (*argv[1] == '>') {
}*/
}
return;
}
/* If first arg is a builtin command, run it and return true */
int builtin_command(char **argv)
{
/* quit command */
if (!strcmp(argv[0], "quit")) {
exit(0);
}
/* Ignore singleton & */
if (!strcmp(argv[0], "&")) {
return 1;
}
/* Not a builtin command */
return 0;
}
/* $end eval */
/* $begin parseline */
/* parseline - Parse the command line and build the argv array */
int parseline(char *buf, char **argv)
{
char *delim; /* Points to first space delimiter */
int argc; /* Number of args */
int bg; /* Background job? */
buf[strlen(buf)-1] = ' '; /* Replace trailing '\n' with space */
while (*buf && (*buf == ' ')) {
buf++; /* Ignore leading spaces */
}
/* Build the argv list */
argc = 0;
while ((delim = strchr(buf, ' '))) {
argv[argc++] = buf;
*delim = '\0';
buf = delim + 1;
while (*buf && (*buf == ' ')) {
buf++; /* Ignore spaces */
}
}
argv[argc] = NULL;
if (argc == 0) {
return 1; /* Ignore blank line */
}
/* Should the job run in the background? */
if ((bg = (*argv[argc-1] == '&')) != 0) {
argv[--argc] = NULL;
}
return bg;
}
/* $end parseline */