Manik Sidana
Manik Sidana

Reputation: 2155

When does actual write() takes place in C?

What really happens when write() system call is executed?

Lets say I have a program which writes certain data into a file using write() function call. Now C library has its own internal buffer and OS too has its own buffer.

What interaction takes place between these buffers ?

Is it like when C library buffer gets filled completely, it writes to OS buffer and when OS buffer gets filled completely, then the actual write is done on the file?

I am looking for some detailed answers, useful links would also help. Consider this question for a UNIX system.

Upvotes: 2

Views: 424

Answers (6)

wildplasser
wildplasser

Reputation: 44220

The write() system call (in fact all system calls) are nothing more that a contract between the application program and the OS.

  • for "normal" files, the write() only puts the data on a buffer, and marks that buffer as "dirty"
  • at some time in the future, these dirty buffers will be collected and actually written to disk. This can be forced by fsync()
  • this is done by the .write() "method" in the mounted-filesystem-table
  • and this will invoke the hardware's .write() method. (which could involve another level of buffering, such as DMA)
  • modern hard disks have there own buffers, which may or may not have actually been written to the physical disk, even if the OS->controller told them to.

Now, some (abnormal) files don't have a write() method to support them. Imagine open()ing "/dev/null", and write()ing a buffer to it. The system could choose not to buffer it, since it will never be written anyway.

Also note that the behaviour of write() does depend on the nature of the file; for network sockets the write(fd,buff,size) can return before size bytes have been sent(write will return the number of characters sent). But it is impossible to find out where they are once they have been sent. They could still be in a network buffer (eg waiting for Nagle ...), or a buffer inside the network interface, or a buffer in a router or switch somewhere on the wire.

Upvotes: 3

sashoalm
sashoalm

Reputation: 79447

Since you're asking for UNIX, you must keep in mind that a file might actually be on an FTP server, which you have mounted, as an example. For example files /dev and /proc are not files on the HDD, as well.

Also, on Linux data is not written to the hard drive directly, instead there is a polling process, that flushes all pending writes every so often.

But again, those are implementation details, that really don't affect anything from the point of view of your program.

Upvotes: 0

Brendan
Brendan

Reputation: 37214

As far as I know...

The write() function is a lower level thing where the library doesn't buffer data (unlike fwrite() where the library does/may buffer data).

Despite that, the only guarantee is that the OS transfers the data to disk drive before the next fsync() completes. However, hard disk drives usually have their own internal buffers that are (sometimes) beyond the OS's control, so even if a subsequent fsync() has completed it's possible for a power failure or something to occur before the data is actually written from the disk drive's internal buffer to the disk's physical media.

Essentially, if you really must make sure that your data is actually written to the disk's physical media; then you need to redesign your code to avoid this requirement, or accept a (small) risk of failure, or ensure the hardware is capable of it (e.g. get a UPS).

Upvotes: 3

Aki Suihkonen
Aki Suihkonen

Reputation: 20017

Years ago operating systems were supposed to implement an 'elevator algorithm' to schedule writes to disk. The idea would be to minimize the disk writing head movement, which would allow a good throughput for several processes accessing the disk at the same time.

Upvotes: 0

cdarke
cdarke

Reputation: 44344

OS dependant, see man 2 sync and (on Linux) the discussion in man 8 sync.

Upvotes: 0

hyde
hyde

Reputation: 62777

write() writes data to operating system, making it visible for all processes (if it is something which can be read by other processes). How operating system buffers it, or when it gets written permanently to disk, that is very library, OS, system configuration and file system specific. However, sync() can be used to force buffers to be flushed.

What is quaranteed, is that POSIX requires that, on a POSIX-compliant file system, a read() which can be proved to occur after a write() has returned must return the written data.

Upvotes: 2

Related Questions