Search code examples
linuxioctlfcntl

Uninterruptible read/write calls


At some point during my C programming adventures on Linux, I encountered flags (possibly ioctl/fcntl?), that make reads and writes on a file descriptor uninterruptible.

Unfortunately I cannot recall how to do this, or where I read it. Can anyone shed some light?

Update0

To refine my query, I'm after the same blocking and guarantees that fwrite() and fread() provide, sans userspace buffering.


Solution

  • You can avoid EINTR from read() and write() by ensuring all your signal handlers are installed with the SA_RESTART flag of sigaction().

    However this does not protect you from short reads / writes. This is only possible by putting the read() / write() into a loop (it does not require an additional buffer beyond the one that must already be supplied to the read() / write() call.)

    Such a loop would look like:

    /* If return value is less than `count', then errno == 0 indicates end of file,
     * otherwise errno indicates the error that occurred. */
    ssize_t hard_read(int fd, void *buf, size_t count)
    {
        ssize_t rv;
        ssize_t total_read = 0;
    
        while (total_read < count)
        {
            rv = read(fd, (char *)buf + total_read, count - total_read);
    
            if (rv == 0)
                errno = 0;
    
            if (rv < 1)
                if (errno == EINTR)
                    continue;
                else
                    break;
    
            total_read += rv;
        }
    
        return rv;
    }