[prev in list] [next in list] [prev in thread] [next in thread] 

List:       hpux-cxx-dev
Subject:    Re: AW: CXX-DEV: Fsync on std::ofstream
From:       Martin Sebor <sebor () roguewave ! com>
Date:       2004-10-28 16:32:15
Message-ID: 41811F0F.6060707 () roguewave ! com
[Download RAW message or body]

Mario Paumann wrote:
>>>So I assume that std::ofstream::~ofstream doesnt call 
>>
>>fsync(2) or sync(2).
>>
>>>Is that right ?
>>
>>No, but unless the program terminates before the call to the dtor
>>it shouldn't make a difference (as long as fstream is implemented
>>in terms of the POSIX I/O library as opposed to libc as, IIRC, it
> 
> 
> My program is a daemon and doesn't terminate.

Unless it crashes ;-) I meant terminate in the general sense,
including by a signal.

> 
> 
>>is). The dtor will flush the contents of the buffer to the file
>>(by calling write(2)) which is all you need to guarantee that the
>>data won't get lost.
> 
> 
> Is it that way ?

I believe that's the behavior required by POSIX. From
http://www.opengroup.org/onlinepubs/007908799/xsh/write.html:

After a write() to a regular file has successfully returned:

   *  Any successful read() from each byte position in the file
      that was modified by that write will return the data specified
      by the write() for that position until such byte positions are
      again modified.

This is roughly what happens:

$ cat t.cpp && aCC t.cpp && rm -f foo.text \
   && ./a.out || cat foo.text

#include <fcntl.h>
#include <signal.h>
#include <unistd.h>

int main ()
{
     int fd = open ("foo.text", O_WRONLY | O_CREAT, 0666);

     if (fd < 0)
         return 1;

     write (fd, "Hello, World!\n", 14);

     raise (SIGBUS);
}

Bus error (core dumped)
Hello, World!

> Because why should there be sync(1) and fsync(1) or
> syncer(1M). They would be useless if write would write it directly to disk.

True, but I didn't say that write() writes directly to the disk.
write just moves the data from the user space of the process to
a buffer in the kernel. The OS then schedules the disk update
with the data stored in the kernel buffer. The purpose of sync()
is to give programs some degree of control over this scheduling.
If the OS crashes before it updates the file on the disk (i.e.,
before the sync), the data might be lost. But not if just the
process crashes.

> I think HP-UX uses cache buffers and write doesn't guarantee that it is
> written to disk unless std::fstream uses O_SYNC on open(2). Does it use
> O_SYNC ?

No, it certainly doesn't. That would make it very inefficient.

> 
> 
>>If you're worried about termination before the dtor is invoked
>>(or if your filebuf uses libc stdio underneath), you might want
>>to consider using unbuffered I/O.
> 
> 
> Are you talking about the filebuf buffer or der hpux cache buffers.  There
> are two of them.

I was referring to the user space buffers, not those maintained by
the OS. As I explained above, the latter should not be a concern
unless it's the OS that crashes.

> And I'm worried about the hpux cache buffers which aren't
> written to disk. I want to make sure that it is really on disk.

In that case fsync() or sync() would be appropriate.

Martin
 _________________________________________________________________
 To leave this mailing list, send mail to majordomo@cxx.cup.hp.com
    with the message UNSUBSCRIBE cxx-dev
 _________________________________________________________________
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic