Fflush does not write buffered text

103 Views Asked by At

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.

1

There are 1 best solutions below

0
On

My problem is that my program is waiting for an input to print the table.

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 from readPBM() and eventually executing the c = getch() at the end of main(). The remedy is to call exit(0) at the end of the if(pid == 0) //Child process block.