tutorial slide
[tsh-lab.git] / simple_shell.c
blobbcaea2fb26cc1541f80451371741b5d947f44469
1 #include <unistd.h>
2 #include <sys/time.h>
3 #include <sys/resource.h>
4 #include <stdio.h>
5 #include <sys/types.h>
6 #include <sys/wait.h>
7 #include <stdarg.h>
8 #include <stdlib.h>
9 #include <string.h>
11 #define MAXLINE 100
12 #define MAXARGS 20
14 int parseline(const char *cmdline, char **argv);
15 void do_bgfg(char *cmdline);
17 void eval (char *cmdline) {
18 char *argv[MAXARGS];
19 int bg;
20 pid_t pid;
22 bg = parseline(cmdline, argv);
23 if ((pid = fork()) == 0) { /* child runs command */
24 if (execvp(argv[0], argv) < 0) {
25 perror("Command not found");
26 exit(0);
29 if (!bg) { /* parent waits for fg job to terminate */
30 int status;
31 if (waitpid(pid, &status, 0) < 0) {
32 perror("waitfg: waitpid error");
35 else { /* otherwise, don’t wait for bg job */
36 printf("%d %s\n", pid, cmdline);
40 int main () {
41 char cmdline[MAXLINE];
42 while (1) {
43 /* read */
44 printf("> ");
45 fgets(cmdline, MAXLINE, stdin);
46 if (feof(stdin)) {
47 exit(0);
49 /* evaluate */
50 eval(cmdline);
51 } /* loop! */
52 return 0;
55 int parseline(const char *cmdline, char **argv)
57 static char array[MAXLINE]; /* holds local copy of command line */
58 char *buf = array; /* ptr that traverses command line */
59 char *delim; /* points to first space delimiter */
60 int argc; /* number of args */
61 int bg; /* background job? */
63 strcpy(buf, cmdline);
64 buf[strlen(buf)-1] = ' '; /* replace trailing '\n' with space */
65 while (*buf && (*buf == ' ')) /* ignore leading spaces */
66 buf++;
68 /* Build the argv list */
69 argc = 0;
70 if (*buf == '\'') {
71 buf++;
72 delim = strchr(buf, '\'');
74 else {
75 delim = strchr(buf, ' ');
78 while (delim) {
79 argv[argc++] = buf;
80 *delim = '\0';
81 buf = delim + 1;
82 while (*buf && (*buf == ' ')) /* ignore spaces */
83 buf++;
85 if (*buf == '\'') {
86 buf++;
87 delim = strchr(buf, '\'');
89 else {
90 delim = strchr(buf, ' ');
93 argv[argc] = NULL;
95 if (argc == 0) /* ignore blank line */
96 return 0;
98 /* should the job run in the background? */
99 if ((bg = (*argv[argc-1] == '&')) != 0) {
100 argv[--argc] = NULL;
102 return bg;
104 void do_bgfg(char *cmdline){