Misha
Misha

Reputation: 5380

Redirecting stdout to file stops in the middle. Linux

My program launches two binaries using "system" command the following way:

int status = system("binaryOne &");
int status = system("binaryTwo &");

Since all three binaries write to the same stdout, all the output is mixed and not understandable. So I changed launch command to redirect stdout of two binaries to different files on which I do tail -f:

int status = system("binaryOne > oneOut.txt &");
int status = system("binaryTwo > twoOut.txt &");

The problem is that writing to files stops at some point. Sometimes it freezes, buffered somewhere and than part of it thrown back and again. Most of time it just stops.

I verified that binaries continue to run and write to stdout.

Upvotes: 1

Views: 700

Answers (2)

Duck
Duck

Reputation: 27572

You can avoid most of this by using popen(). Each popen call will set up a separate pipe for your main program to read and the output won't be intertwined as it is having everything directed to stdout. Also obviously a lot less clumsy than writing to and tailing files. Whether this is better than fork/exec for your purposes only you can say.

Upvotes: 1

Sergey L.
Sergey L.

Reputation: 22552

Here is how you could try it with fork + exec

pid_t child_pid = fork();

if (!child_pid) {
    // child goes here

    char * args[] = {"binaryOne", NULL};

    int fd = open("oneOut.txt", O_WRONLY | O_CREAT | O_TRUNC);

    if (!fd) {
        perror("open");
        exit(-1);
    }

    // map fd onto stdout
    dup2(fd, 1);

    // keep in mind that the children will retain the parent's stdin and stderr
    // this will fix those too:
    /*
    fd = open("/dev/null", O_RDWR);
    if (!fd) {
        perror("open");
        exit(-1);
    }

    // disable stdin
    dup2(fd, 0);
    // disable stderr
    dup2(fd, 2);
    */

    execvp(*args, args);

    // will only return if exec fails for whatever reason
    // for instance file not found

    perror("exec");

    exit(-1);
}

// parent process continues here

if(child_pid == -1) {
    perror("fork");
}

Edit Important: forgot to set write flag for open.

Upvotes: 1

Related Questions