The assignment I am working on requires making a text parser that sends words to multiple child processes that call sort. The sort children have to send their data to a process call suppersor that removes duplicate words from printing.
I know in order for data to be read/writen unused pipes need to be closed. I do with the function close_pipes. I can run the program without segfaults. I have run the program through gdb following child and parent and get no segfaults. When I run the program I get no text from the input file showing up. All i get is ERROR WHILE CLOSING PIPE.
How can I check that the 2D array of pipe file descriptors are valid? I don't understand why in the child process it would be failing to close the pipe.
Code:
/**
* @brief pipe from sort to suppressor
*/
int **pipe1;
/**
* @brief pipe from parser to sort.
*/
int **pipe2;
sort_count = atoi(argv[1]);
pipe1 = build_pipe_table(sort_count);
pipe2 = build_pipe_table(sort_count);
/* closing pipes here causes no probelm */
/* fork sort */
int i;
for (i = 0; i < sort_count; ++i){
switch(fork()){
case -1:
fprintf(stderr, "forking sort %d process failed\n", i);
break;
case 0:
/* child tasks */
fprintf(stderr,"in sort child code\n");
dup2(pipe1[i][0], STDIN_FILENO);
dup2(pipe2[i][1], STDOUT_FILENO);
close_pipes(pipe1, 0, sort_count);
close_pipes(pipe1, 1, sort_count);
close_pipes(pipe2, 0, sort_count);
close_pipes(pipe2, 1, sort_count);
/* free the pipe array? */
execl("/usr/bin/sort", "sort", (char*) NULL);
break;
default:
break;
}
}
Code:
/**
* @brief Constructs the dynamic two dimenisional array for holding the pipes.
* @param rows the number of rows in the 2D array.
* @return pointer to the created 2D array.
*/
int** build_pipe_table(const int rows){
int i;
int **temp;
temp = (int**)malloc(rows * sizeof(int*));
if (temp == NULL){
fprintf(stderr, "failed to allocate pipe table\n");
exit(EXIT_FAILURE);
}
for (i = 0; i < rows; ++i){
/* 2 for write read of pipe fd array */
temp[i] = (int*)malloc(2 * sizeof(int));
if (temp[i] == NULL){
fprintf(stderr, "failed to allocate pipe table\n");
exit(EXIT_FAILURE);
}
errno = 0;
if (pipe(temp[i]) == -1){
fprintf(stderr, "failed to create pipe. errno = %d\n", errno);
exit(EXIT_FAILURE);
}
}
return temp;
}
Code:
/**
* @breif closes one side of a pipe for all pipes in 2D array.
* @param the_pipe pointer to the 2D array of pipes.
* @param side which side of the pipe to close 0 = read, 1 = write side
* @param rows the number for sorts children.
*/
void close_pipes(int **the_pipe, const int side, const int rows){
int i;
for (i = 0; i < rows; ++i){
errno = 0;
if (close(the_pipe[i][side]) == -1){
fprintf(stderr, "ERROR WHILE CLOSING PIPE\n");
}
}
}
Sample output
Quote:
in sort child code
in sort child code
in supressor code
in sort child code
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
ERROR WHILE CLOSING PIPE
|