reading and writing to pipes, file descriptors, and file streams
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
reading and writing to pipes, file descriptors, and file streams
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
void close_pipes(int **the_pipe, const int side, const int rows){
int i;
for (i = 0; i < rows; ++i){
int handle= the_pipe[i][side];
if (close(handle) == -1){
fprintf (stderr, "ERROR WHILE CLOSING PIPE %d (i=%d, side=%d, rows=%d) errno=%d: %s\n",
handle, i, side, rows, errno, strerror (errno));
}
}
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.