Ok, in this code I have 2 primary problems.
1: The parent doesn't wait for the child to print before returning to main and printing. I included a waitpid() but it doesn't seem to be working how I expected.
- When I redirect, I create the file fine, but nano and vim don't "see" the file, Gedit however can (so I know my output is being sent correctly)
The flow of this function:
A string is input, the string is checked for a trailing & (if it exists, it is removed and the background flag is updated).
Then the string is tokenized on '|'
Each token is tokenized on '<' and '>'
Then each string from that is tokenized on ' '
The resulting char ** is executed with the output/input being redirected based off the results of the above tokenizations.
void execute_command(char * s)
{
printf("\n");
int fd[3][2]; // since we are guaranteed each type of redirection will be used only once, I only need 3 pipes: < > and |
//int fd[2];
int res;
pid_t pid;
int status;
int stdin_c = dup(0);
int stdout_c = dup(1);
int i;
int background = 0;
for(i = 0; s[i] != '\0'; i++);
if(s[i-1] == '&')
{
background = 1;
s[i-1] = '\0';
}
char ** piped = token_pipe(s);
char ** left_a;
char ** right_a;
int output = 0;
int input = 0;
for(i = 0; piped[i] != NULL; i++)
{
left_a = token_leftarrow(piped[i]);
right_a = token_rightarrow(piped[i]);
if(left_a[1] != NULL)
{
free(piped[i]);
piped[i] = calloc(strlen(left_a[0]) + 1, sizeof(char));
strcpy(piped[i], left_a[0]);
fd[0][0] = open(left_a[1], O_RDONLY);
input = i;
}
if(right_a[1] != NULL)
{
free(piped[i]);
piped[i] = calloc(strlen(left_a[0]) + 1, sizeof(char));
strcpy(piped[i], right_a[0]);
fd[1][1] = open(right_a[1], O_WRONLY | O_CREAT, 0666);
output = i;
}
}
char ** spaced = token_space(piped[0]);
char ** spaced2 = NULL;
if(piped[1] != NULL)
{
spaced2 = token_space(piped[1]);
res = pipe(fd[2]);
if(res < 0)
{
printf("Pipe Failure\n");
exit(-1);
}// end if
}
if(fork() == 0)
{
if(background == 1)
setpgid(0, 0);
if(piped[1] != NULL)
{
close(fd[2][1]);
close(0);
dup(fd[2][0]);
if(output == 1 && right_a[1] != NULL)
{
dup2(fd[1][1], 1);
close(fd[1][1]);
}
execvp(spaced2[0], spaced2);
perror("Invalid Command");
exit(-1);
}
else
{
if(input == 0 || output == 0)
{
if(right_a[1] != NULL)
{
dup2(fd[1][1], 1);
close(fd[1][1]);
}
if(left_a[1] != NULL)
{
dup2(fd[0][0], 0);
close(fd[0][0]);
}
}
execvp(spaced[0], spaced);
perror("Invalid command\n");
exit(-1);
}
}
else
{
if(piped[1] != NULL)
{
if((pid = fork()) == 0)
{
close(fd[2][0]);
close(1);
dup(fd[2][1]);
if(input == 0 && left_a[1] != NULL)
{
dup2(fd[0][0], 0);
close(fd[0][0]);
}
execvp(spaced[0], spaced);
perror("Invalid Command");
exit(-1);
}
else
if(background == 0)
waitpid(pid, &status, WNOHANG);
}
else
if(background == 0)
wait(NULL);
close(fd[2][0]);
close(fd[2][1]);
close(fd[0][0]);
close(fd[1][1]);
dup2(stdin_c, 0);
dup2(stdout_c, 1);
}
}