我试图使用fork,pipe,dup2和execvp编写无名管道程序。 程序应该从命令行获取第一个命令,并分叉子进程。父进程应执行命令并将输出传递给子进程。孩子应该继续下一个命令(令牌是' - '而不是常规的管道标志' |')并在父母的输入上进行,依此类推,所以每个父节点的输出传递给子节点,直到最后一个应该在主节点和节点上执行的命令。 出于某种原因,该程序似乎在打印之前停止在dup2" parent2!"。 提前感谢所有的帮助:)
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h> // for open flags
#include <time.h> // for time measurement
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define LINE_MAX 1024
char* buffer[LINE_MAX];
void np_exec(char* cmd, char** argv)
{
int i,len=0,ret_p,ret_c;
int mypipefd[2];
/* count how many args till NULL to know how much space to allocate */
for(i=0;argv[i]!=NULL;i++)
len++;
if (len == 0)
{
printf("ERROR_CMD\n");
exit(EXIT_FAILURE);
}
char* par[len+1];
par[len] = NULL;
/* creat parameters array */
for(i=0;argv[i]!=NULL;i++)
par[i] = argv[i];
/* creat pipe */
if (pipe(mypipefd)==-1)
{
printf("ERROR_PIPE: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
pid_t cpid;
cpid = fork();
if (cpid == -1)
{
printf("FORK_ERROR: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
/* child process */
else if (cpid==0)
{
printf("child!\n");//TODO delete
dup2(mypipefd[0], STDIN_FILENO);
close(mypipefd[1]);
if(read(STDIN_FILENO,buffer,LINE_MAX)<0) //read output from pipe.
{
printf("READ_ERROR: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("child2!\n");//TODO delete
}
/* parent process */
else
{
printf("parent!\n");//TODO delete
dup2(mypipefd[1], STDOUT_FILENO);
printf("parent2!\n");//TODO delete
close(mypipefd[0]); //Closes read side of pipe
if (execvp(cmd,par) == -1)
{
printf("EXECVP_ERROR: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
}
}
int main(int argc, char** argv)
{
/* last char is not '-' */
assert(strcmp(argv[argc-1], "-"));
/*The program then parses the arguments,
* calling the function np_exec for each separate set of arguments except the last,
* i.e., list of arguments that end with a minus character.*/
int i;
for (i = 1; i < argc; ++i) {
if (!strcmp(argv[i], "-")) {
argv[i] = NULL;
np_exec(argv[1], &argv[1]);
/* support milti pipes */
argv = &argv[i];
argc -= i;
i = 0;
}
}
/* array for the final program in the arguments */
char* args[argc];
args[argc-1] = NULL;
/* let it start from index 0 */
for (i = 1; i < argc; ++i) {
args[i-1] = argv[i];
}
printf("finish!!!\n");//TODO delete
/* execute the final program in the arguments using execvp */
if (execvp(args[0], args) == -1)
perror("execvp failed");
return;
}