2

I have a C program with 9 calls to printf and I need it to run on a remote server for several days. So I decided to redirect the stdout to a file to check the progresses:

FILE *foutput=freopen("output.txt","w",stdout);

After some debugging I found this and used

fflush(foutput)

and from what I can see in the link, all the buffering are right to me (I have a newline command at the end of each print): right in the sense that I expect the print to be effectively executed and to find them on output.txt, but this is not happening.

What may be the problem?

I want you to note that following works:

  foutput=freopen("output.txt", "w", stdout);
  printf("first print\n");
  fflush(foutput);
  fclose(foutput);

but I'd like to avoid the call to freopen each time.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
GRquanti
  • 527
  • 8
  • 23
  • 1
    "but this is not happening." --> what is happening? How did you determine what is happening as the file appears to not be closed when you are testing the text? I suspect your output file is not a _share-able_ mode. – chux - Reinstate Monica Aug 04 '17 at 13:50
  • why not let your OS deal with the output? If you're using linux/mac you could use tmux or screen to run your code in the remote location. With these programs you can scroll through the output. Or just use a redirection like `$ my-program > mylog.txt` and when you log in, you just inspect `mylog.txt`. – Pablo Aug 04 '17 at 13:51
  • @chux is not happening that the output is printed on the file: I open it and there's nothing. – GRquanti Aug 04 '17 at 13:54
  • @Pablo I'm not familiar with the > command. I'm gonna take a look. – GRquanti Aug 04 '17 at 13:55
  • There are program buffers and there are OS buffers. Reading from MSVC documentation, it seems that `fflush` flushes the program buffers but by default does not instruct the OS to flush the OS buffers for the file. However, upon an `fclose` the locks on the file are removed and the file is available for anyone else. Hence the OS flushes its buffers now too. – Paul Ogilvie Aug 04 '17 at 13:58
  • I'd go with the solution using `fclose` each time. Why is this a problem? – Jabberwocky Aug 04 '17 at 13:59
  • @PaulOgilvie Thank you for the explanation. Is there a way to force the OS buffers to be flushed? However, I can't understand why in the link I posted the simple solution was working. – GRquanti Aug 04 '17 at 14:00
  • From MSVC: "_...turn buffering off with the `setvbuf` function..._" – Paul Ogilvie Aug 04 '17 at 14:03
  • @MichaelWalz It is not very elegant and, most iportant, ther's always the risk for the file to be not opened – GRquanti Aug 04 '17 at 14:05
  • What happens if you open the file with `fopen` instead of `freopen` and write to it with `fprintf` instead of `printf`? Maybe it makes a difference. What is your operating system? – Jabberwocky Aug 04 '17 at 14:06
  • I'm on Ubuntu 14.04. However, your idea works. I was just seeking for an explanation of something that seems correct but doesn't work. – GRquanti Aug 04 '17 at 14:10
  • Interesting, on my Windows 10 it works exactly as you expect. – Jabberwocky Aug 04 '17 at 14:12
  • On Ubuntu, your program ought to be able to call `fsync()` after `fflush()` to ensure that the OS-level buffers are also flushed. However, I find it surprising that such an action would be needed, to the extent that I suspect some other factor is involved. Even without the `fsync()`, the system should not keep the data buffered long, and Linux does not implement or require file "sharing modes" such as Windows has. (`fsync()` is a POSIX function, not one specified by C istelf.) – John Bollinger Aug 04 '17 at 14:16
  • @PaulOgilvie, `setvbuf()` controls C-level stream buffers. It has nothing to do with OS-level buffering (or at least C does not specify anything at that level). Thus, turning off buffering via `setvbuf()` would remove the need for an `fflush()`, but there's no reason to expect it to help when `fflush()` is being called anyway. – John Bollinger Aug 04 '17 at 14:23

0 Answers0