好的,在这段代码中我有两个主要问题。
1:父母在返回主要和打印之前不等待孩子打印。我包括了一个waitpid(),但它似乎没有按照我的预期工作。
此功能的流程:
输入一个字符串,检查该字符串的尾随& (如果存在,则删除它并更新背景标志。)
然后将字符串标记为' |'
每个令牌都被标记为'<'和'>'
然后,每个字符串都被标记为' '
生成的char **执行时输出/输入根据上述标记的结果重定向。
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);
}
}