Link to home
Start Free TrialLog in
Avatar of PhilC
PhilC

asked on

using O_SYNC, but still need fsync()

At the start of my app, depending on a command line parameter, I may redirect stdout and stderr to a file (see below)
all of my output is done using printf's....so the app can be run in verbose or quiet mode to a file.  It is necessary for me to be able to check the contents of the log as the program progresses.  Currently nothing shows until I call fsync().  I though opening with O_SYNC would force data to be written to disk.  I considered O_DIRECT until I noticed it's definiation "/* direct disk access hint - currently ignored */"
Is there way other than following every printf() with an fsync() to get data writting to disk real time?
Thank You

  iStdOutAndErr = open("myfile",O_CREAT|O_TRUNC|O_APPEND|O_RDWR|O_SYNC,S_IRWXG|S_IRWXU|S_IRWXO);
   if (iStdOutAndErr) {
      int iFileToClose;

      iFileToClose = fileno(stdout);
      if (iFileToClose) {
       close(iFileToClose);
       dup2(iStdOutAndErr,iFileToClose);
      }
      iFileToClose = fileno(stderr);
      if (iFileToClose) {
       close(iFileToClose);
       dup2(iStdOutAndErr,iFileToClose);
      }
   } // if could open the file
Avatar of ravenpl
ravenpl
Flag of Poland image

For disk access use O_DIRECT flag, but then, be aware, that operations has to be aligned to 512 bytes. size of r/w has to be multiply of 512, buffer memory has to have aligned address(man posix_memalign).
For sockets pipes etc it's ignored as well.
Avatar of PhilC
PhilC

ASKER

I was hoping to avoid wrapping all my printf()'s in order to handle screen or file output...the alignment requirement would make this necessary too.
Is there any other way to runtime optionally redirect stdout and stderr to a file?
Thank you very much
Avatar of Duncan Roe
I believe your problem is this: you are using streams(3) calls (like printf) but operating on raw file entities (like dup2(2)).
You need to eliminate the normal streams buffering of printf() &c. This is actually quite easy - man setvbuf for details. You want _IONBUF so every printf causes immediate calls of write()
Odd how fsync() works for you though - maybe it is gratuitously calling fflush() for you(?) (I doubt it though - maybe streams i/o is super clever somehow)
Actually you shouldn't need O_SYNC at all (unless viewing the file over NFS) - with no streams buffering your output will all go out to Linux buffers and any other app opening the same file will see it whether it's been actually written to disk or not
I'm not sure exactly what you're doing, but the fsync and the O_SYNC doesn't have anything to do with printf -- printf  is buffered I/O.   setvbuf is on the right track -- what type of system are you running on?
streams is not supper clever (its super confusing sometimes!!).
Avatar of PhilC

ASKER

would I have to change my open() to an fopen()?
setvbuf fails (dumps) when I try to change the mode
setvbuf(iStdOutAndErr, NULL,_IONBF,0);

Thank You
ASKER CERTIFIED SOLUTION
Avatar of Duncan Roe
Duncan Roe
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of PhilC

ASKER

works great, thank you