Я пытаюсь написать программу безымянного канала, используя 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;
}