#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINE_LEN 80
#define MAX_ARGS 64
#define MAX_ARG_LEN 16
#define MAX_PATHS 64
#define MAX_PATH_LEN 96
#define DELIM " *.,\t\n"
#ifndef NULL
#define NULL ...
#endif
struct command_t {
char *name;
int argc;
char *argv[MAX_ARGS]; };
char *lookupPath(char **, char **);
int parseCommand(char *, struct command_t *);
int parsePath(char **);
void printPrompt();
void readCommand(char *);
/******************************************************************/
void printPrompt() {
/* This code simply prints the shell prompt to standard out */
char prompt[] = "jSh > ";
printf("%s",prompt);
}
/******************************************************************/
void readCommand(char *buffer) {
/* This code reads the entire command line into the buffer */
fgets(buffer,LINE_LEN,stdin);
}
/******************************************************************/
int parsePath(char *dirs[]) {
/* This function reads the PATH variable for the environment and
then builds an array of all the directories in PATH */
char *pathEnvVar;
char *thePath;
char *tmp;
int i;
int k;
for(i=0; i<MAX_PATHS; i++)
dirs[i] = NULL;
pathEnvVar = (char *) getenv("PATH");
if (pathEnvVar == NULL)
return 0;
thePath = (char *) malloc(strlen(pathEnvVar) + 1);
strcpy(thePath, pathEnvVar);
/* Parse thePath and construct dirs array while parsing*/
for(tmp=strtok(thePath,":"); tmp!=NULL; strtok(NULL,":")) {
dirs[k] = malloc(strlen(tmp)+1);
/* Need to break out if k is NULL */
if (dirs[k] == NULL)
break;
strcpy(dirs[k],tmp);
k = k+1;
}
/* Return array size */
return k;
}
/******************************************************************/
char *lookupPath(char **argv, char **dirs) {
/* This function searches for program names within dirs */
char *tmp;
char *result;
int i;
/* Base case, see if file name is absolute path name */
if(*argv[0] == '/') {
result = argv[0];
return result;
}
/* Look in PATH directories using access() to check for file */
for(i=0;i<MAX_PATHS;i++) {
if(dirs[i] == NULL)
continue;
/* Construct string for full PATH name */
tmp = (char *) malloc(MAX_PATH_LEN*20);
strcpy(tmp,dirs[i]);
strncat(tmp,"/",MAX_PATH_LEN);
strncat(tmp,argv[0],MAX_PATH_LEN);
/* Check to see if file is in PATH and is executable */
if(access(dirs[i],X_OK) == 0) {
result = tmp;
return result;
}
}
/* Account for file not being found in any directories */
fprintf(stderr,"%s: command not found\n",argv[0]);
return NULL;
}
/******************************************************************/
int parseCommand(char *cLine, struct command_t *cmd) {
/* parses a command from standard input and creates a command struct */
int argc;
int count;
char **clPtr;
clPtr = &cLine;
argc = 0;
/* Need to fill up argv[] with all of the tokens */
cmd->argv[argc] = (char *) malloc(MAX_ARG_LEN);
while((cmd->argv[argc] = strsep(clPtr,DELIM)) != NULL) {
cmd->argv[++argc] = (char *) malloc(MAX_ARG_LEN);
}
/* need to decrement argc to reflect actual # of command args */
cmd->argc = argc-1;
/* create memory for name of command to be called, and store it in name */
cmd->name = (char *) malloc(sizeof(cmd->argv[0]));
strcpy(cmd->name,cmd->argv[0]);
/* test for exit condition */
if(strncasecmp(cmd->name,"exit",4)==0) {
exit(0);
}
/* for testing purposes */
printf("The command \"%s\" has %d argument(s)\n", cmd->name,cmd->argc);
printf("argv0 = %s\n",cmd->argv[0]);
for(count=0;count<argc;++count) {
printf("argv[%d] = %s\n",count,cmd->argv[count]);
}
return 1;
}
/******************************************************************/
int main() {
/* TEST */
printf("inside main");
char *pathv[MAX_PATHS];
char commandLine[LINE_LEN];
struct command_t command;
int chPID;
int status;
pid_t childPID;
/* TEST */
printf("almost to parsePath()");
/* Get all the PATH directories */
parsePath(pathv);
/* TEST */
printf("got to parsePath()");
/* loop to accept lines from standard input and parse them */
while(1) {
printPrompt();
readCommand(commandLine);
parseCommand(commandLine, &command);
command.argv[command.argc] = NULL;
/* Get the full pathname for the file */
command.name = lookupPath(command.argv, pathv);
if(command.name == NULL) {
fprintf(stderr,"command \"%s\" unknown",command.name);
continue;
}
/* Create child and execute the command */
if((chPID = fork()) == 0) {
printf("Child executing: %s\n", command.name);
execvp(command.name, command.argv);
}
/* Wait for the child to terminate */
printf("Parent waiting for child to terminate\n");
childPID = wait(&status);
/* Free dynamic storage in command structure */
free(command.name);
}
/* Shell termination */
return 0;
}
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:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
by: ozoPosted on 2008-02-11 at 15:55:04ID: 20871493
I don't see k initialized before doing dirs[k] = malloc(strlen(tmp)+1);