(I had to think for quite a while before responding, because this might be seen as nitpicking, but I'll try to express the point clearly. It is a nuance, but an important one, because it gives a developer the basis to make an informed decision on what they consider reasonable in a given situation.)
write() may be short simply because some internal kernel buffer can't take more input at that time. As of what size the buffers are, who knows. Can you write a gigabyte to /dev/ttyUSB0? No. Can you assume you can write 100 bytes? Why?
No it won't. File descriptor writes (without O_NONBLOCK) are not limited by the size of kernel buffers. You can absolutely write a gigabyte to /dev/ttyUSB0 and the call should just block until all the data is written, the device disappears, or an asynchronous signal handler is invoked.
There are a few exceptions, but they are not about kernel buffers per se.
The kernel limits single read and write syscalls to a bit less than two gigabytes (2
31 bytes). The reason is complicated, but boils down to minimizing bugs due to unstated assumptions in old filesystem drivers. (That is, it is difficult to ensure old filesystem drivers work accurately with over 32-bit requests in all cases.)
A file descriptor refers to a file description (an entry in the open file table), which in Linux has an associated set of handlers; a
struct file_operations for a file-like object. Essentially, the write syscall implementation in the kernel (in fs/read_write.c) calls ksys_write() which calls vfs_write(), which maintains the file position associated with the file description, limits the write size to MAX_RW_COUNT (defined in include/linux/fs.h in the Linux kernel, currently exactly one page less than 2 GiB), verifies the target memory buffer (to write data from) is valid, and then calls the filesystem/device specific ->write() handler. Note that it is up to the filesystem/device specific read/write handlers to honor the O_NONBLOCK flag, too!
Now, because the Linux kernel dictators are pretty big on the principle of least surprise, filesystem drivers should fulfill the entire write (and read). But, the kernel does not verify they do. So, the expectation is that the drivers do fulfill the entire request, but there is no enforcement or guarantees. If a filesystem/device does return a short count when it technically could service the entire operation, the maintainers will accept a clean patch to fix that. However, do we
know that there
cannot be any reasonable reasons for a device or filesystem to return a short count?
(I've been considering implementing for USB Serial protocol with pipe/socket semantics, bypassing the TTY layer. The O_NONBLOCK semantics are clear and easy; it's the blocking syscall semantics that give me a pause: most userspace programmers use the simplest, least amount of code to get things done, and reality rules. I'd like to return short counts if the device NAKs an USB packet, but will that throw off the simple userspace code?)
So, it boils down to:
Should short reads/writes happen with blocking reads and writes?No, they shouldn't.Can short reads/writes happen with blocking reads and writes?Yes, they can; there is no code in the Linux kernel or the C library that verifies they do not happen; the code that implements them should not
return short counts for blocking reads and writes, but technically, they could occur, depending on the kernel driver implementing the object you are reading from/writing to.