-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshellexe.c
More file actions
160 lines (116 loc) · 2.39 KB
/
shellexe.c
File metadata and controls
160 lines (116 loc) · 2.39 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
/*
* by wangyanpeng@gmail.com
* 2014.12.07
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXARGS 128
#define MAXLINE 8192
void unix_error(char *msg)
{
fprintf(stderr, "%s \n", msg);
exit(0);
}
pid_t Fork(void)
{
pid_t pid;
if ((pid = fork()) < 0)
unix_error("Fork error");
return pid;
}
extern char **environ; /* defined by libc */
void app_err(char * msg)
{
fprintf(stderr, "%s\n", msg);
exit(0);
}
char * Fgets(char * ptr, int n, FILE * stream)
{
char * rptr;
if (((rptr = fgets(ptr, n, stream)) == NULL) && ferror(stream))
app_err("Fgets error!");
return rptr;
}
void eval(char *cmdline);
int parseline(char *buf, char **argv, int *arg_n);
int buildin_command(char **argv);
int main()
{
char cmdline[MAXARGS];
printf("===command you input should with its absolute path name.===\n");
while (1) {
printf("> ");
Fgets(cmdline, MAXLINE, stdin);
if (feof(stdin))
exit(0);
eval(cmdline);
}
}
void eval(char *cmdline)
{
char *argv[MAXARGS];
char buf[MAXLINE];
int bg;
int arg_num;
pid_t pid;
strcpy(buf, cmdline);
bg = parseline(buf, argv, &arg_num);
/* printf("bg = %d, arg_nmu=%d\n", bg, arg_num); */
if (argv[0] == NULL)
return; /* Ignore empty line */
if (!builtin_command(argv)) {
if ((pid = Fork()) == 0) { /* Child process run user job */
if (execve(argv[0], argv, environ) < 0) {
printf("%s: Command not found.\n", argv[0]);
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);
}
return;
}
int parseline(char *buf, char **argv, int *arg_n)
{
char *delim;
int argc;
int bg;
buf[strlen(buf)-1] = ' '; /* Replace trailing '\n' with space */
while (*buf && (*buf == ' '))
buf++;
/* Build the argv list */
argc = 0;
while ((delim = strchr(buf, ' '))) {
argv[argc++] = buf;
*delim = '\0';
buf = delim + 1;
while (*buf && (*buf == ' ')) /* Ignore spaces */
buf++;
}
argv[argc] = NULL;
if (argc == 0) /* Ignore blank line */
{
*arg_n = 0;
return 0;
}
/* Should the job run in background? */
if ((bg = (*argv[argc-1] == '&')) != 0)
argv[--argc] = NULL;
*arg_n = argc;
return bg;
}
int builtin_command(char **argv)
{
if (!strcmp(argv[0], "quit"))
exit(0);
if (!strcmp(argv[0], "&"))
return 1;
return 0;
}