0% found this document useful (0 votes)
52 views6 pages

Shell

Uploaded by

api-744403598
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
52 views6 pages

Shell

Uploaded by

api-744403598
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

1 //prog4.

c
2 //UISH (University of Idaho Shell)
3 //CS 240 Assignment 4 by Carson Gustavel
4
5 #include<stdio.h>
6 #include<stdlib.h>
7 #include <ctype.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10 #include <sys/wait.h>
11 #include <string.h>
12
13 int makearg(char *s, char ***args);
14 int makepath(char *s, char ***args);
15 void runExec( char**, int , char* );
16
17 int main(){
18
19 int cont = 1; //when zero, close down shell
20
21 //get path, make path vector:
22 char* path = getenv( "PATH" );
23 //printf( "Path: %s\n" , path );
24 char** pathv;
25 int pathc = makepath( path , &pathv );
26 /*
27 for( int i = 0; i < pathc; i++ ){
28 printf("|%s|\n", pathv[i]);
29 }
30 */
31
32 //shell variables storage:
33 char** variableNames;
34 char** variableContents;
35 int variableNum = 0;
36 variableNames = (char**)malloc( 256 * sizeof(char*));
37 variableContents = (char**)malloc( 256 * sizeof(char*));
38
39
40 while( cont ){ //main loop
41
42 int bg = 0; //run command in background?
43
44 printf( "$ " );
45
46 //get user input
47 char input[1024];
48 fgets( input , 1024 , stdin );
49
50 //process user input:
51 char **argv;
52 int argc = makearg( input , &argv );
53 //run in background?
54 for ( int i = 0; i < argc ; i++ ){
55 if ( strcmp ( argv[i] , "&" ) == 0 && ( argv[i+1] == NULL ) ){
56 // printf("Running in background\n");
57 bg = 1;
58 argv[i] = NULL;
59 }
60 }
61 //is command trying to create a shell variable?
62 if ( argc == 1 ){
63 int seperatorIndex = 0;
64 for ( int i = 0; argv[0][i] != '\0' ; i++ ){
65 if ( argv[0][i] == '=' ){
66 seperatorIndex = i;
67 break;
68 }
69 }
70 if ( seperatorIndex == 0 ) {
71
72 } else {
73 //does it already exist?
74 //printf("Checking if variable already exists:\n");
75 int exists = 0;
76 char temp[seperatorIndex];
77 for ( int i = 0; i < seperatorIndex ; i++ ){
78 temp[i] = argv[0][i];
79 }
80 temp[seperatorIndex] = '\0';
81 if ( variableNum > 0 ){
82 //printf("Does the shell variable |%s| already exist?\n" , temp);
83 for ( int i = 0; i < variableNum ; i++ ){
84 //printf("|\n");
85 if ( strcmp( temp , variableNames[i] ) == 0 ){
86 exists = i+1;
87 //printf("Variable Exists at index %d\n" , exists-1);
88 }
89 }
90 }
91 if ( exists ){ //if it exists already:
92 //printf( "Variable |%s|, already exists at index |%d|\n" , temp ,
exists-1);
93 exists--;
94 free ( variableContents[exists] );
95 variableContents[exists] = (char*)malloc( ( strlen( argv[0] ) -
seperatorIndex + 1 ) * sizeof(char) );
96 int counter = 0;
97 for ( int i = seperatorIndex + 1; i < strlen( argv[0] ) ; i++ ){
98 variableContents[exists][counter] = argv[0][i];
99 counter++;
100 }
101 variableContents[exists][strlen( argv[0] ) - seperatorIndex - 1] = '\0';
102 } else { //create new shell var:
103 //printf( "Variable |%s|, does not exists, creating at index |%d|\n" ,
temp , variableNum );
104 //printf( "Seperator Index: %d\n" , seperatorIndex );
105 variableNames[variableNum] = (char*)malloc( ( seperatorIndex + 1 ) * sizeof
(char) );
106 //printf("|");
107 variableContents[variableNum] = (char*)malloc( ( strlen( argv[0] ) -
seperatorIndex + 1 ) * sizeof(char) );
108 //printf("Filling in variable name\n");
109 for ( int i = 0; i < seperatorIndex; i++ ){
110 variableNames[variableNum][i] = argv[0][i];
111 }
112 variableNames[variableNum][seperatorIndex] = '\0';
113
114 //printf("Filling in variable contents\n");
115 int counter = 0;
116 for ( int i = seperatorIndex+1; i < strlen( argv[0] ) ; i++ ){
117 variableContents[variableNum][counter] = argv[0][i];
118 counter++;
119 }
120 variableContents[variableNum][strlen( argv[0] ) - seperatorIndex] = '\0';
121
122 variableNum++;
123 }
124 }
125 }
126 //is command trying to read a path variable?
127 if ( variableNum > 0 ){
128 for ( int i = 0; i < argc; i++ ){
129 if ( argv[i][0] == '$' ){
130 //printf( "Shell Variable %s Detected\n" , argv[i] );
131 char temp[strlen( argv[i] )];
132 for ( int j = 0; j < strlen(argv[i]) ; j++ ){
133 temp[j] = argv[i][j+1];
134 }
135
136 //printf( "Comparing value: |%s|\n" , temp );
137 for ( int j = 0; j < variableNum; j++ ){
138 if ( strcmp( temp , variableNames[j] ) == 0 ){
139 //printf( "Replacing |%s| with |%s|\n" , argv[i] ,
variableContents[j] );
140 free( argv[i] );
141 argv[i] = (char*)malloc( ( strlen( variableContents[j] ) + 1 ) *
sizeof(char) );
142 strncpy( argv[i] , variableContents[j] , strlen(variableContents[j])
+ 1 );
143 argv[i][strlen(variableContents[j])] = '\0';
144 }
145 }
146 }
147 }
148 }
149
150 //run command:
151 pid_t p = fork();
152
153 if( p != 0 ){ //I am a parent
154 //parenting stuff
155 } else { //I am a child
156 //child stuff:
157 //run exec
158 // int error = execvp( argv[0] , argv);
159 for ( int i = 0; i < pathc; i++ ){
160 runExec( argv , argc , pathv[i] );
161 }
162 // printf("\n-uish: Command not found\n$ ", input);
163 exit(0);
164 }
165
166 //run in background?
167 if ( bg == 0 ){
168 wait( NULL );
169 } else {
170 //run in background
171 }
172
173 //clear memory for argv:
174 // printf("Freeing Argv");
175 for (int i = 0; i < argc; i++) {
176 free(argv[i]);
177 }
178 free(argv);
179
180 }
181
182 //printf("Freeing pathv");
183 //clear memory for argv:
184 for (int i = 0; i < pathc; i++) {
185 free(pathv[i]);
186 }
187 free(pathv);
188
189 //clear memory for variableNames:
190 for (int i = 0; i < variableNum; i++) {
191 free(variableNames[i]);
192 }
193 free(variableNames);
194 //clear memory for variableContents:
195 for (int i = 0; i < variableNum; i++) {
196 free(variableContents[i]);
197 }
198 free(variableContents);
199
200 }
201
202 //makearg
203 //Takes a character array (string) and an empty triple character pointer,
204 //tokenizes the string,
205 //storing it as a 2d array of characters inside of the pointer,
206 //memory will be dynamically declared to store the values
207 //returns the number of tokens in the array as an integer
208 int makearg(char *s, char ***args){
209
210 int argc = 0; //
211
212 int k = 0; //counter
213 while ( s[k] != '\0' ) { //loop until end of string, inclusive of \0 terminator
214 if ( s[k] == ' ' ){
215 argc++;
216 }
217 k++;
218 }
219 argc++;
220
221 // printf("There are %d arguments\n", argc);
222
223 *args = (char**)malloc( (argc + 1) * sizeof(char*));
224 // printf("Memory for args allocated\n");
225 //String counters:
226 int counter = 0;
227 int bookmark = 0;
228
229 for ( int currentArg = 0; currentArg < argc ; currentArg++ ){ //for each argument
230 // printf( "Scanning argument #%d\n" , currentArg );
231 while( !isspace(s[counter]) && s[counter] != '\0' ){
232 // printf("Scanning character #%d\n" , counter );
233 counter++;
234 }
235 if ( s[counter] != '\0') {
236 counter++;
237 }
238 // printf( "Token #%d is %d characters long\n" , currentArg , (counter - bookmark)
);
239 // printf( "It starts at index %d, and ends at index %d\n", bookmark, counter );
240 (*args)[currentArg] = (char*)malloc( ( counter - bookmark + 1 ) * sizeof(char) );
241 memset((*args)[currentArg], '\0', ( counter - bookmark + 1 ) * sizeof(char));
242 // printf("Memory for arg #%d allocated\n" , currentArg );
243 for ( int i = 0; i < ( counter - bookmark ); i++ ){
244 if (s[bookmark + i] == ' ' || s[bookmark + i] == '\n' ) {
245 continue;
246 } //strip white space
247 (*args)[currentArg][i] = s[ bookmark + i ];
248 // printf( "Copying character %c\n" , s[ bookmark + i ] );
249 // printf( "Successfully copied %c\n" , (*args)[currentArg][i] );
250 }
251 //strncpy ( (*args)[currentArg] , &s[bookmark], counter-bookmark-1 );
252 // printf("done with tranfering #%d\n", currentArg);
253 (*args)[currentArg][counter-bookmark] = '\0'; //ensure the final index has a null
terminator
254 bookmark = counter;
255 }
256
257 return argc;
258
259 }
260
261 //makearg
262 //Takes a character array (string) and an empty triple character pointer,
263 //tokenizes the string,
264 //storing it as a 2d array of characters inside of the pointer,
265 //memory will be dynamically declared to store the values
266 //returns the number of tokens in the array as an integer
267 int makepath(char *s, char ***args){
268
269 int argc = 0; //
270
271 int k = 0; //counter
272 while ( s[k] != '\0' ) { //loop until end of string, inclusive of \0 terminator
273 if ( s[k] == ':' ){
274 argc++;
275 }
276 k++;
277 }
278 argc++;
279
280 // printf("There are %d arguments\n", argc);
281
282 *args = (char**)malloc( (argc + 1) * sizeof(char*));
283 // printf("Memory for args allocated\n");
284 //String counters:
285 int counter = 0;
286 int bookmark = 0;
287
288 for ( int currentArg = 0; currentArg < argc ; currentArg++ ){ //for each argument
289 // printf( "Scanning argument #%d\n" , currentArg );
290 while( s[counter] != ':' && s[counter] != '\0' ){
291 // printf("Scanning character #%d\n" , counter );
292 counter++;
293 }
294 if ( s[counter] != '\0') {
295 counter++;
296 }
297 // printf( "Token #%d is %d characters long\n" , currentArg , (counter - bookmark)
);
298 // printf( "It starts at index %d, and ends at index %d\n", bookmark, counter );
299 (*args)[currentArg] = (char*)malloc( ( counter - bookmark + 1 ) * sizeof(char) );
300 memset((*args)[currentArg], '\0', ( counter - bookmark + 1 ) * sizeof(char));
301 // printf("Memory for arg #%d allocated\n" , currentArg );
302 for ( int i = 0; i < ( counter - bookmark ); i++ ){
303 if (s[bookmark + i] == ':' || s[bookmark + i] == '\n') {
304 continue;
305 } //strip white space
306 (*args)[currentArg][i] = s[ bookmark + i ];
307 // printf( "Copying character %c\n" , s[ bookmark + i ] );
308 // printf( "Successfully copied %c\n" , (*args)[currentArg][i] );
309 }
310 //strncpy ( (*args)[currentArg] , &s[bookmark], counter-bookmark-1 );
311 // printf("done with tranfering #%d\n", currentArg);
312 (*args)[currentArg][counter-bookmark] = '\0'; //ensure the final index has a null
terminator
313 bookmark = counter;
314 }
315
316 return argc;
317
318 }
319
320 void runExec( char** argv , int argc , char* path ){
321
322 int n = strlen( argv[0] );
323 n += strlen(path);
324 n += 2;
325
326 char temp[n];
327 strncpy( temp , path , n );
328 strncat( temp , "/" , n );
329 strncat( temp , argv[0] , n );
330 temp[n-1] = '\0';
331 /*
332 printf( "Temp: |%s|" , temp );
333 for ( int i = 0; i < argc; i++ ){
334 printf( "Argv[%d]: |%s|\n" , i , argv[i] );
335 }
336 */
337 // printf("Attempting execv");
338 execv( temp , argv );
339 // printf("execv appears to have failed.");
340
341 return;
342
343 }
344

You might also like