mkfifo()를 사용하여 여러 개의 FIFO 파이프를 만들어 운영 체제 셸 프로젝트에서 파이프 라이닝을 구현하려고합니다. 현재,이 프로그램은 첫 번째 FIFO를 쓰기 위해 열어 둔 것처럼 보입니다. 또한 FIFO는 작업 디렉토리에서 ls를 수행 할 때 나타납니다. 이 인스턴스에서 freopen()을 잘못 사용하고 있습니까? 일반적으로프로그램이 FIFO (명명 된 파이프)에 연결을 끊습니다.
void execute_external()
{
int backgrounding = 0;
if (raw_command[strlen(raw_command)-1] == '&')
{
pmesg(2, "Backgrounding requested.\n");
raw_command[strlen(raw_command)-1] = '\0';
raw_command = realloc(raw_command, strlen(raw_command)-1);
backgrounding = 1;
}
int numCommands = 1;
char **commands;
commands = malloc(sizeof(char *));
if(strstr(raw_command, "|") != NULL)
{
numCommands = separate_pipeline_commands(commands);
}
else
{
commands[0] = malloc(strlen(raw_command) * sizeof(char));
commands[0] = raw_command;
}
int i;
char *fifo = malloc(MAXFIFOLEN);
for (i = 0; i < numCommands; i++)
{
char **parameters_array = malloc(strlen(commands[i]) * sizeof(char *));
int num_params;
num_params = str_to_str_array(commands[i], parameters_array);
pmesg(2, "Command is %s.\n", commands[i]);
if (numCommands > 1)
{
int j;
for (j = 0; j < numCommands - 1; j++)
{
sprintf(fifo, "fifo%i", j);
mkfifo(fifo, S_IWUSR | S_IRUSR);
}
}
pid_t pid = fork();
pmesg(2, "Process forked. ID = %i. \n", pid);
if (pid < 0)
{
fprintf(to_write_to, "Could not fork a process to complete the external command.\n");
exit(EXIT_FAILURE);
}
int status;
if (pid == 0) // This is the child process
{
pmesg(1, "input: [%s] output: [%s] input: %d, output: %d backgrounding is %d\n",input_file_name, output_file_name, redirect_input, redirect_output, backgrounding);
if (numCommands > 1 && i == 0) // we may be pipelining and this is the first process
{
sprintf(fifo, "%s%i", "fifo", i);
printf("Initial output: %s.\n", fifo);
freopen(fifo, "w", stdout);
//~ unlink(fifo);
}
else if (numCommands > 1 && i !=0 && (i != numCommands-1)) // we are pipelining and this is not the first or last process
{
sprintf(fifo, "%s%i", "fifo", i-1);
printf("Input for process %i: %s.\n", i, fifo);
freopen(fifo, "r", stdin);
//~ unlink(fifo);
sprintf(fifo, "%s%i", "fifo", i+1);
printf("Output for process %i: %s.\n", i, fifo);
freopen(fifo, "w", stdout);
//~ unlink(fifo_2);
}
else if (numCommands != 1 &&i == numCommands)
{
char *fifo = malloc(strlen("fifo")+2);
sprintf(fifo, "%s%i", "fifo", i);
freopen(fifo, "r", stdin);
free(fifo);
}
if(redirect_output == 1)
{
freopen(output_file_name, "w", stdout);
}
if(redirect_input == 1)
{
freopen(input_file_name, "r", stdin);
}
if (backgrounding != 0)
{
freopen("/dev/null", "w", stdout);
}
pmesg(2, "This is the child process, running execlp.\n");
pmesg(1, "Command: [%s]\n", parameters_array[0]);
if (execvp(parameters_array[0], parameters_array) < 0)
{
fprintf(to_write_to, "Could not execute the external command. errno: %i.\n", errno);
exit(EXIT_FAILURE);
}
else { pmesg(2, "Executed the child process.\n");}
}
else
{
if (backgrounding != 0)
{
enqueue(&process_queue, pid, clock(), 0, 0);
printQueue(process_queue);
}
if (backgrounding == 0) { while(wait(&status) != pid); }// Wait for the child to finish executing
}
pmesg(1, "The child has finished executing.\n");
free(parameters_array);
}
free(commands);
}
자세한 메모를 보내 주셔서 감사합니다. 자식 프로세스 부분에서이 코드는 실제로 루프에서 호출됩니다. 주변의 코드를 일부 명확하게 남겨두기를 희망하면서 질문에서 제외되었습니다. 분명히 최선의 결정이 아닙니다. –
@Alex, 아하! 때로는 가능한 가장 작은 "재생기"로 문제를 줄이는 것이 실수를 찾는 데 중요하며 때로는 기본 문제를 찾기가 훨씬 어려워집니다. :) 가장 작은 재생기를 찾는 것은 그 자체로 예술 형식입니다. 나는 당신의 원래 문제가 잘 진행되기를 희망한다. – sarnold
쉘이 만기가되기 전날 밤 나는이 일을 맡았습니다 ... 프로젝트 파트너는 마지막 순간까지 그것을 할 수 있다고 생각했습니다. 기능을 종료 한 채로 끝났습니다. 그래도 도와 줘서 고마워! –