I'm trying to print a 2D table to my terminal using this code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <sys/wait.h>
char getch()
{
char ch;
struct termios old, new;
tcgetattr(0, &old); // grab old terminal i/o settings
new = old; // new settings = old settings
new.c_lflag &= ~ICANON; // disable buffered i/o
new.c_lflag &= ~ECHO; //set echo mode
tcsetattr(0, TCSANOW, &new); // use these new terminal i/o settings now
ch = getchar();
tcsetattr(0, TCSANOW, &old); //restore old settings
return ch;
}
void readPBM(char *output)
{
char tmp[1024];
int fd[2] = {0,0};
int pid;
//Open the pipe for inter-process communication
pipe(&fd[0]);
//Fork and test if we are child or parent process
pid = fork();
if(pid) //Parent process
{
wait(NULL); //Wait for child's end
close(fd[1]);//Close pipe's write stream
close(0);//Close stdin
dup(fd[0]);//Duplicate stdout
close(fd[0]);//Close old stdout
strcpy(output, "");// Init output at 0
while(fgets(tmp, 1024, stdin) != NULL) //Put remaining entry in output
{
strcat(output, tmp);
}
}
else if(pid == 0) //Child process
{
close(fd[0]);//Close pipe's read stream
close(1);//Close stdout
dup(fd[1]);//Duplicate stdin
close(fd[1]);//Close old stdin
printf("A random string ...\n");
}
else //Print error if fork failed
{
printf("Error creating a new process");
exit(EXIT_FAILURE);
}
}
int main(int argc, char *argv[])
{
int i, j;
char *str = NULL;
char c;
str = malloc(512 * sizeof(char*));
readPBM(str);
printf("%s", str);
fflush(stdout);
c = getch();
}
I have a UNIX implementation of getch().
My problem is that my program is waiting for an input to print the table. I tried to fflush(stdout)
and to disable terminal buffering with ICANON but it's still not working.
PS: it's not working neither with getchar, scanf, ...
EDIT: So I came up to this minimal example; it seems to be pipe-related.
This is because you forgot to terminate the child process when it has done its work, so after printing
A random string ...
to the pipe it continues, returning fromreadPBM()
and eventually executing thec = getch()
at the end ofmain()
. The remedy is to callexit(0)
at the end of theif(pid == 0) //Child process
block.