-3

I have a cpp program that constantly prints out readings from a gyro. I want to write these values to a file but the problem is that the cpp program can be exited anytime (either power down of system or user press ctrl + c etc). What is a good way to safely write these values to a files as they are being read without having to safely close the file after. I am thinking of somehow using the bash >> operator.

.
.
.
while(1)
{

   printf("acc: %+5.3f", ax);
   //write the printed line to file...

}
.
.
.
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Lightsout
  • 3,454
  • 2
  • 36
  • 65
  • What do you think happens if `bash` is halfway through writing a file and the power gets cut? You can't protect against that kind of thing. – Silvio Mayolo Jan 18 '18 at 00:28
  • 1
    You can solve the ctrl-c issue pretty easily by capturing the interrupt event. For more info, see: https://stackoverflow.com/questions/17766550/ctrl-c-interrupt-event-handling-in-linux – scohe001 Jan 18 '18 at 00:31
  • You can detect ctrl+c signal but there's a little you can do. You can ignore it and continue the work optionally flush the data into output with fflush(stdout). For power downs there's no protection. You can only watch the program die. – Piotr Styczyński Jan 18 '18 at 00:33
  • @SilvioMayolo I dont care if the text gets cut off I just dont wanta corrupted file etc – Lightsout Jan 18 '18 at 00:37
  • 1
    Flush the file buffer after each write. – Barmar Jan 18 '18 at 00:39

2 Answers2

0

To protect against the program being terminated with Ctl-c, flush the buffer after each write:

fstream << "acc: " << ax << std::flush;

Note that if you end the output with std::endl, this writes a newline and also flushes the buffer.

Protecting against the system losing power is harder. There are OS-specific functions like fsync() on Unix, which force any kernel file buffers to be written to disk. But to use this you need the underlying Unix file descriptor, and there's no standard way to get that from a C++ fstream. See Retrieving file descriptor from a std::fstream

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • What would be the consequence of cutting power during write?? I don't care at all about losing text values and I'M only writing text. – Lightsout Jan 18 '18 at 03:24
  • Anything in kernel buffers that hasn't been sent to disk will be lost. – Barmar Jan 18 '18 at 03:26
  • Ok well I guess Ill just forget about it then and just cut the power without protection if the worst thing is losing a few letters. – Lightsout Jan 18 '18 at 03:27
  • If you lose power, lots of stuff on disk can be messed up. `fsck` tries to clean it up as best it can, but things can be lost irreparably. There's very little you can do in software to protect against this completely, the best you can do is try to shrink the windows of vulnerability. – Barmar Jan 18 '18 at 03:28
  • Even if you could call `fsync()`, the power could fail while the OS is in the middle of writing to disk. – Barmar Jan 18 '18 at 03:29
0

In this case you have 2 points of possible synchronization issues:

  1. printf buffers
  2. bash buffers and file open/close operations.

You can improve the 'printf' part by using the 'fflush(stdout)' call, but you have no control over the bash process.

The best solution would be to use your own file output with fprintf, followed with fflush and sync or similar. The latter would guarantee that system buffers would be flushed as well.

In c++ world you can use output streams to a file with 'endl' or 'flush' at the end. They would flush output buffere, though you might still need 'sync'.

Serge
  • 11,616
  • 3
  • 18
  • 28