开发者

Streams printing and redirection

开发者 https://www.devze.com 2023-03-29 02:53 出处:网络
I have a program which prints (by printf) to the stdout some data and also calls to function *foo* which also prints to the stdout some data [the way (implementation) of how printing is done from foo

I have a program which prints (by printf) to the stdout some data and also calls to function *foo* which also prints to the stdout some data [the way (implementation) of how printing is done from foo is unknown and I can`t see the code of foo].

I have to redirect everything from stdout to buffer or file. I tried to do it in several ways

  1. freopen(file.txt, stdout) - only my code prints are written to the file.txt. What was printed from foo is lost.
  2. setbuf(buffer, stdout) - only my code prints are written to the buffer. What was printed from foo is appears in the stdout.(It appears on the screen)

What can explain this behavior? How can the problem be solved?

Note:This code has to work in cross-OS( lunux/wind && mac OS).I use gcc in order compile the code and I have 开发者_StackOverflow中文版cygwin


It's likely that foo isn't using stdio for printing and directly calling the OS for this.

I don't know about win32, but on POSIX you could use dup2 to take care of it.

/* Before the function foo is called, make `STDOUT_FILENO` refer to `fd` */
int fd;
fd = open(...);
dup2(fd, STDOUT_FILENO);

EDIT

Much to my surprise, win32 has _dup2 but it does something else.


How do you know that foo() is printing to stdout? Have you tried redirecting standard output to a file at the shell and seeing whether the output from foo() still appears on the screen?

If the file redirection sends foo()'s output to the file, then you may have to rejig the file descriptor level, as in cnicutar's answer.

If the file redirection does not send foo()'s output to the file, then it may be writing to stderr or it may be opening and using /dev/tty or something similar. You can test for stderr by redirecting it separately from stdout:

your_program >/tmp/stdout.me 2>/tmp/stderr.me

If it is opening /dev/tty, the output will still appear on your screen.

Which platform are you on? If you can track system calls (strace on Linux, truss on Solaris, ...), then you may be able to see in that what the foo() function is doing. You can help things by writing a message before and after calling the function, and ensuring you flush the output:

printf("About to call foo()\n");
fflush(0);
foo();
printf("Returned from foo()\n");
fflush(0);

The printf/fflush calls will be visible in the trace output, so what appears between is done by foo().


What can explain this behavior?

I have seen this sort of behavior when the code you are calling into uses a different C library than yours. On Windows I used to see this sort of thing when one DLL is compiled with GCC and another with Visual C++. The implementation of stdio for these is apparently different enough such that this can be problematic.

Another is that the code you are calling is not using stdio. If you are on Unix you can use dup2 to get around this, eg. dup2(my_file_descriptor, 1). On many implementations if you have a FILE* you can say dup2(fileno(f), 1). This may not be portable.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号