Question

I faced a nasty problem:

Suppose I have one program, let's name it HelloProgram which code is very simple:

void print_bullshit() {
 int i;
 for (i = 0; i < 10; ++i) {
  printf("hello!");
  sleep(3);
 }
 printf("bye!");
}

And I have another program, let's name it Redirector, which code is a bit complicated:

#define READ_END 0
#define WRITE_END 1

int pipe_fd[2];
void child_proc(const char* prg_name) {
 close(pipe_fd[READ_END]);

 dup2(pipe_fd[WRITE_END], STDOUT_FILENO));
 execl("/bin/sh", "sh", "-c", prg_name, NULL);
 //error
 exit(1);
}

void parent_proc() {
 close(pipe_fd[WRITE_END]);
 char buffer[256];
 while (read(pipe_fd[READ_END], buffer, sizeof(buffer)) > 0) {
  printf(buffer);
 }

 wait(NULL);
}

int main(int argc, const char* argv[]) {
 pipe(pipe_fd);
 pid_t chpid = fork();
 if (chpid != 0) {
  parent_proc();
 } else {
  child_proc(argv[1]);
 }

 return 0;
}

Some error-checks are not stated there, that's to make code more simple. I still can't understand this thing:

When Redirector is used with HelloProgram to redirect it's output, all the 'Hello' text is given to the console screen only after 3 * 10 (== number of iterations) == 30 seconds,

what the hell is that? I supposed it would be some kind of parallel, so I got each 'Hello' string displayed on the console after every 3 second.

Help me, please.

Was it helpful?

Solution

If you want the output in HelloProgram to appear timely, you have to either include a newline at the end of each printf(), or use fflush() to force it out. If the output from HelloProgram is going to a terminal, newlines are sufficient; if it is going to a pipe, you need fflush().

Hence:

void print_bullshit(void)
{
    int i;
    for (i = 0; i < 10; ++i)
    { 
        printf("hello!\n");
        fflush(stdout);
        sleep(3);
    }
    printf("bye!\n");
    fflush(stdout);
}

This will send material to its standard output as timely as possible.

In your other code, you have:

void child_proc(const char* prg_name)
{
    close(pipe_fd[READ_END]);
    dup2(pipe_fd[WRITE_END], STDOUT_FILENO));
    execl("/bin/sh", "sh", "-c", prg_name, NULL);
    //error
    exit(1);
}

You need, in general, to add:

close(pipe_fd[WRITE_END]);

after the dup2() call. In this case, it may not matter, but in general, you don't want it left open. Arguably, the code in parent_proc() should close the read end of the pipe when it has read EOF. However, in this program, that won't matter either.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top