open / close - glibc
Split from the chapter glibc: stdio and Formatted I/O into the per-function layout; see the method page and the glibc ledger for coverage status.
Family B – Low-Level Input/Output (libc wrappers)
These unistd.h functions are one-to-one wrappers over the syscalls
fully documented in
Descriptors and File I/O; entries here
cover only the libc-side deltas. Three facts recur:
- Return translation. Syscall success is a nonnegative value;
failures surface as
-1witherrnoset – the wrapper is where the kernel’s negative-error convention becomes the C convention. No mapping or masking happens beyond that. - EINTR is not retried. glibc returns
EINTRto the caller; the manual (Interrupted Primitives) documents that interrupted primitives fail withEINTRunless the handler was installed withSA_RESTART, and offers theTEMP_FAILURE_RETRYmacro inunistd.has the caller side retry loop. Nothing in the wrapper layer retries for you. - Close-on-exec plumbing. Flagless wrappers (
pipe,dup2) cannot setFD_CLOEXEC; glibc’s answer is the GNU flag-taking variantspipe2/dup3(unistd.hgates them on_GNU_SOURCE), whileopen-style calls takeO_CLOEXECdirectly andfopen/popenexpose theemode character.
Signature – int open(const char *path, int flags, ... /* mode_t */);
int close(int fd); – unistd.h/fcntl.h.
Libc side – variadic third argument for O_CREAT/O_TMPFILE;
open64/openat/openat64 in the same ledger section. On arm64 glibc’s
open() issues openat(AT_FDCWD, ...) because no open slot exists
(see the open entry in
Descriptors and File I/O). close
returns 0/-1+errno; the kernel releases the descriptor even on
EINTR-in-doubt paths, so retrying close is wrong (syscall chapter,
close entry). Both are raw translation wrappers; no retries, no
fallbacks.