#ifndef VLIBC_FCNTL_H #define VLIBC_FCNTL_H /* * vlibc — . * * File control, record locks, and the open-flag constants (POSIX.1-2008 plus * the Linux x86_64 additions). Every O_*, F_*, AT_* and POSIX_FADV_* value * below is a Linux kernel UAPI fact for x86_64 (asm-generic/fcntl.h), transcribed in * hex with the kernel's octal form in a comment — not an invented number. * O_TMPFILE and O_SYNC are defined as flag combinations exactly as the * kernel defines them. * * Note on the *at constants: on x86_64 AT_EACCESS == AT_REMOVEDIR == 0x200; * the kernel disambiguates by syscall (faccessat vs unlinkat), so both names * carry the same value here. * * open/openat are deliberately NOT declared here: POSIX places them in this * header, but this project's single declaration site is (todo 19; * see its header comment). creat() lives here — its canonical POSIX home. * * Level 2 (muslmimic/XSI): lockf plus F_LOCK/F_TLOCK/F_ULOCK/F_TEST. POSIX * puts lockf in ; that file is todo 19's and out of scope here, * and musl declares lockf in as well — the constants accompany the * declaration so the header stays self-contained. A later integration pass * may re-export the same declaration from (identical, harmless). * * None of these declarations carry an intent attribute: every function * performs I/O with side effects and reports failures through errno (or, * for posix_fadvise/posix_fallocate, an error-number return), so const/pure * would be unsound — the same rationale unistd.h documents for its I/O * family. */ #include #include #include #ifdef __cplusplus extern "C" { #endif /* ---- open(2) flag bits ---- */ /* Mask for the O_RDONLY/O_WRONLY/O_RDWR access mode. */ #define O_ACCMODE 0x3 #define O_RDONLY 0x0 /* 00000000 */ #define O_WRONLY 0x1 /* 00000001 */ #define O_RDWR 0x2 /* 00000002 */ #define O_CREAT 0x40 /* 00000100 */ #define O_EXCL 0x80 /* 00000200 */ #define O_NOCTTY 0x100 /* 00000400 */ #define O_TRUNC 0x200 /* 00001000 */ #define O_APPEND 0x400 /* 00002000 */ #define O_NONBLOCK 0x800 /* 00004000 */ #define O_DSYNC 0x1000 /* 00010000 */ #define O_ASYNC 0x2000 /* 00020000 */ #define O_DIRECT 0x4000 /* 00040000 */ #define O_LARGEFILE 0x8000 /* 00100000 */ #define O_DIRECTORY 0x10000 /* 00200000 */ #define O_NOFOLLOW 0x20000 /* 00400000 */ #define O_NOATIME 0x40000 /* 01000000 */ #define O_CLOEXEC 0x80000 /* 02000000 */ /* * __O_SYNC/__O_TMPFILE are Linux-kernel names in the implementation-reserved * namespace (this libc IS "the implementation", and the kernel UAPI mandates * the exact spellings) — the NOLINT below is the house waiver for that. */ #define __O_SYNC 0x100000 /* NOLINT(bugprone-reserved-identifier) 04000000 */ #define O_SYNC (__O_SYNC | O_DSYNC) #define O_PATH 0x200000 /* 010000000 */ #define __O_TMPFILE 0x400000 /* NOLINT(bugprone-reserved-identifier) 020000000 */ #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) /* ---- fcntl(2) commands ---- */ #define F_DUPFD 0 #define F_GETFD 1 #define F_SETFD 2 #define F_GETFL 3 #define F_SETFL 4 #define F_GETLK 5 #define F_SETLK 6 #define F_SETLKW 7 #define F_SETOWN 8 #define F_GETOWN 9 #define F_SETSIG 10 #define F_GETSIG 11 /* Linux-specific owner-identity commands (constants only; struct f_owner_ex * is out of POSIX scope and not provided). */ #define F_SETOWN_EX 15 #define F_GETOWN_EX 16 #define F_GETOWNER_UIDS 17 /* Open-file-description (OFD) locks, Linux 3.15+. */ #define F_OFD_GETLK 36 #define F_OFD_SETLK 37 #define F_OFD_SETLKW 38 #define F_DUPFD_CLOEXEC 1030 /* F_LINUX_SPECIFIC_BASE (1024) + 6 */ /* Close the descriptor on exec — the F_SETFD/F_GETFD flag. */ #define FD_CLOEXEC 1 /* Record-lock types (struct flock l_type). */ #define F_RDLCK 0 #define F_WRLCK 1 #define F_UNLCK 2 /* ---- *at(2) base-directory and behavior flags ---- */ #define AT_FDCWD (-100) #define AT_SYMLINK_NOFOLLOW 0x100 #define AT_REMOVEDIR 0x200 #define AT_SYMLINK_FOLLOW 0x400 #define AT_EACCESS 0x200 /* ---- posix_fadvise(2) advice values ---- */ #define POSIX_FADV_NORMAL 0 #define POSIX_FADV_RANDOM 1 #define POSIX_FADV_SEQUENTIAL 2 #define POSIX_FADV_WILLNEED 3 #define POSIX_FADV_DONTNEED 4 #define POSIX_FADV_NOREUSE 5 /* * Record-lock descriptor, ABI-identical to the x86_64 kernel layout * (asm-generic/fcntl.h: short, short, long, long, int — 32 bytes with * natural padding). On x86_64 the LFS and non-LFS layouts are one struct, * so there is no separate flock64 here. */ struct flock { short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */ short l_whence; /* SEEK_SET, SEEK_CUR, or SEEK_END (from ) */ off_t l_start; /* relative offset of the locked region */ off_t l_len; /* region length; 0 means through EOF */ pid_t l_pid; /* PID of the process holding the lock (F_GETLK) */ }; /* * Perform one of the F_* control operations on fildes. Only the commands * that take a third argument read it from the varargs; all others pass 0, * which the kernel ignores. Return the command-specific result, or -1 with * errno set. */ int fcntl(int fildes, int cmd, ...); /* * Equivalent to open(path, O_WRONLY | O_CREAT | O_TRUNC, mode): create * path for writing, truncating any existing file, with mode masked by the * process umask. Return a file descriptor, or -1 with errno set. */ int creat(const char *path, mode_t mode); /* * Announce an expected access pattern for the range [offset, offset+len) of * fd (len 0 means through EOF). Unlike the rest of the family this returns * an error NUMBER directly — 0 on success, else the positive errno value * (e.g. EBADF, ESPIPE) — and errno is untouched (POSIX). */ int posix_fadvise(int fd, off_t offset, off_t len, int advice); /* * Ensure storage is allocated for the range [offset, offset+len) of fd, * growing the file as needed. Returns an error number directly (0 on * success) and leaves errno untouched, like posix_fadvise (POSIX). */ int posix_fallocate(int fd, off_t offset, off_t len); #if VLIBC_LEVEL_GE(2) /* lockf() commands (POSIX XSI; the kernel has no lockf syscall — these are * userspace cmd values). */ #define F_ULOCK 0 /* unlock a previously locked region */ #define F_LOCK 1 /* lock a region, blocking until available */ #define F_TLOCK 2 /* try to lock; -1 with EACCES/EAGAIN if held */ #define F_TEST 3 /* test a region for another process's lock */ /* * Apply or remove an exclusive POSIX record lock on [current offset, * current offset + len) of fd (len 0 means through EOF). XSI. Return 0, or * -1 with errno set. */ int lockf(int fd, int cmd, off_t len); #endif /* VLIBC_LEVEL_GE(2) */ #ifdef __cplusplus } #endif #endif /* VLIBC_FCNTL_H */