简体   繁体   中英

Redirect both stdout and stderr to a single file and keep message order

I'm trying to redirect both stdout and stderr to a single file with a C program.

Here is my code:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int redirectOutputs();

int main()
{
    redirectOutputs();
    printf("OUT : test\n");
    perror("ERR : test");
    printf("OUT : test 2\n");


    int t = 23;
    printf("OUT : again\n");
    perror("ERR : again");

}

int redirectOutputs()
{
    int log = open("err.log", O_RDWR|O_CREAT|O_APPEND, 0600);
    if (log == -1)
    {
        perror("opening err.log");
        return -1;
    }
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
    dup2(log, STDOUT_FILENO);
    dup2(log, STDERR_FILENO);
    close(log);
}

And the output file:

ERR : test: Success
ERR : again: Success
OUT : test
OUT : test 2
OUT : again

They are both redirected well, but it seems that the all stderr is written and then the all stdout . I would like to keep the order of messages in the file. I should have the following file:

OUT : test
ERR : test: Success
OUT : test 2
OUT : again
ERR : again: Success

Do you know what is the problem in my code?

The problem is that output through stdout is buffered while stderr is unbuffered .

You either have to make stdout unbuffered like stderr , or make stderr buffered like stdout . You set buffering and mode by using setvbuf .

You could also call fflush on stdout after each output to it.

Your issue is buffering . The simplest solution is to call fflush() after each output. You could of course explicitly set buffering to line buffered with setvbuf() .


That said, it would probably be a better idea to have an explicit logging interface that just optionally catches stderr and stdout as well. And a final remark, some of your close() calls are redundant, dup2() automatically closes the new fd before duplicating.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM