Hello. I am trying to write a shell program, one that takes in 2 UNIX commands and executes it. the format for input is:
<command> | <command>
My problem is that for some reason, the execv call is erroring out each time. Relevant parts of my code are below. I removed the parts for the second command, as well as creating a pipe since I know those are working correctly. I know my problem is with calling execv.
Code:
#include <unistd.h>
#include <stdio.h>
#define WRITE 1
#define READ 0
#define BUFFSIZE 200
#define FILENAME "Pipe"
#define CHECK(FUNCTION, STATUS) if(STATUS < 0) \
{\
printf("\nfailed to %s %s. code returned was: %d\n", FUNCTION, FILENAME, STATUS); \
return 0; \
}
int main(int argc, char** argv) {
int check;
char buffer[BUFFSIZE];
do {
printf("shell-prompt>> ");
gets(buffer);
if(buffer[0] == '@') {
break;
}
char firstargs[10][BUFFSIZE];
char secondargs[10][BUFFSIZE];
firstargs[0][0] = '/'; //initializing first argument so that it executes from /bin
firstargs[0][1] = 'b';
firstargs[0][2] = 'i';
firstargs[0][3] = 'n';
firstargs[0][4] = '/';
//getting part 1
int i = 0, countr = 0, countc = 5;
while(*(buffer+i) == ' ' || *(buffer+i) == '\t') { //while we see leading whitespace
i++; //skip it
} //end whitespace loop
while(*(buffer+i) != '|' && *(buffer+i) != '\0') { //while we have not see a bar or end of string (sanity check)
//check for whitespace
int whitecount = 0;
while(*(buffer+i) == ' ' || *(buffer+i) == '\t') { //while we see whitespace
i++; //skip it
if(whitecount == 0) { //if this was the first whitespace seen
firstargs[countr][countc] = NULL; //null terminate old arg
countr++; //increment argc number
whitecount = 1; //no longer see first whitecount
countc = 0; //reset position on new argument
}
} //end whitespace loop
//after whitespace
if(*(buffer+i) == '|') {
break;
}
firstargs[countr][countc] = buffer[i]; //copy character
countc++; //increment position in arg
i++; //increment position in buffer
}
firstargs[countr][countc] = NULL; //null terminate old arg
firstargs[countr+1][0] = NULL; //null terminate last string
/* now we have arguments for first and second process*/
//DEBUG PRINTING
int printtemp = 0;
while(firstargs[printtemp][0] != 0) {
printf("firstargs[%d]: %s\n", printtemp, firstargs[printtemp]);
printtemp++;
}
int childA, childB;
childA = fork();
CHECK("fork", childA)
if(childA == 0) {
printf("I am process A\n");
check = execv(firstargs[0], firstargs);
CHECK("execv", check);
exit(0);
}
int childreturn;
//waits for 2 children to finish
check = wait(&childreturn);
CHECK("wait", check);
free(firstargs);
} while(1);
exit(0);
}
Judging by the warning message gcc gives me, I think the problem is with the second argument of execv, but I honestly have no clue what it doesn't like, since it is a char[][].
Any help or nudges in the right direction would be greatly appreciated. Thanks!