207 lines
6.7 KiB
C
207 lines
6.7 KiB
C
#ifndef VLIBC_FCNTL_H
|
|
#define VLIBC_FCNTL_H
|
|
|
|
/*
|
|
* vlibc — <fcntl.h>.
|
|
*
|
|
* 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 <unistd.h> (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 <unistd.h>; that file is todo 19's and out of scope here,
|
|
* and musl declares lockf in <fcntl.h> as well — the constants accompany the
|
|
* declaration so the header stays self-contained. A later integration pass
|
|
* may re-export the same declaration from <unistd.h> (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 <vlibc/features.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#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 <unistd.h>) */
|
|
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 */
|