Ted
Ted

Reputation: 1611

C - write data to a file, either write all or write nothing

In my case, writing partial data is nonsense, so I figure out this:

ssize_t write_all(int fd, unsigned char* data, size_t size) {
    ssize_t w;
    size_t written = 0;
    unsigned char* buf = data;

    do {
        w = write(fd, buf, size-written);
        if (w > 0) {
            written += w;
            if (written == size) {
                return written;
            } else {
                buf += w;
            }
        } else {
            lseek(fd, SEEK_CUR, -written);
            return 0;
        }
    } while (1);
}

Is this correct? Or are there any better practices?

Upvotes: 2

Views: 373

Answers (1)

Z4-tier
Z4-tier

Reputation: 7978

Here is what I would do:

  1. create a temporary file somewhere convenient (like /tmp)

  2. write out that file until you reach the point where you can declare the operation a success

  3. unlink the original and move the new file to the same location/name.

Once you call write() you are at the mercy of the kernel as far as when the data will actually be flushed to the disk.

You can use O_SYNC to add a level of assurance that the data has been written - O_SYNC will cause write() to block until the data is written to disk. O_DSYNC has the same behavior, but it will block until all of the file-system metadata is written as well, giving a stronger guarantee that the data will be retrievable once write() returns.

Upvotes: 3

Related Questions