write(2)
System call
System call that hands bytes to a file descriptor (1 for stdout, 2 for stderr), with no buffering and no formatting. Returns the number of bytes written.
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);Description
write asks the kernel to write count bytes, read from buf, to the descriptor fd. A descriptor is a small integer: 0 for standard input, 1 for standard output, 2 for standard error, then the ones returned by open, pipe or socket.
It is the call that sits underneath printf(3) and puts(3), without what they add. No buffer in your process: when write returns, the bytes are in the kernel's hands. No formatting: write knows nothing about strings or numbers, only bytes. To print an integer, you first have to turn it into digits yourself.
Return value
The number of bytes actually written, or -1 on error, with the cause in errno. That number can be smaller than count, for example when the disk is full or a signal interrupts the write partway through. A program that has to send everything calls write again with the rest, in a loop.
Pitfalls
countis a size in bytes, not a string length.write(1, s, sizeof s)on achar *sends 8 bytes on a 64-bit machine, the size of the pointer. For a string, usestrlen(s).writedoes not add a\nand does not stop at the'\0':write(1, "abc", 4)sends the null byte too.Mixing
writeandprintfon the same output scrambles the display order as soon asstdoutis no longer a terminal, becauseprintfkeeps its text in a buffer. The demonstration is in printf prints nothing before a crash.An accented character takes several bytes in UTF-8:
strlencounts them correctly, a number written by hand easily gets it wrong.
Example
#include <string.h>#include <unistd.h>
int main(void){ const char *msg = "connection established\n"; ssize_t n;
n = write(1, msg, strlen(msg)); if (n == -1) return 1; write(2, "done\n", 5); return 0;}$ gcc -Wall -Wextra -g write.c -o write$ ./writeconnection establisheddone$ ./write > out.txtdone$ cat out.txtconnection establishedThe > redirection only affects descriptor 1: the message sent to descriptor 2 stays on the screen.
write_str
Write write_str, which sends a string to descriptor 1 with write, one character per call, without the terminating null byte.