123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477 |
- #+build linux, darwin, openbsd, freebsd, netbsd
- package posix
- import "core:c"
- when ODIN_OS == .Darwin {
- foreign import lib "system:System.framework"
- } else {
- foreign import lib "system:c"
- }
- // fcntl.h - file control options
- foreign lib {
- /*
- Implemented as `return open(path, O_WRONLY|O_CREAT|O_TRUNC, mode);`
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/creat.html ]]
- */
- creat :: proc(path: cstring, mode: mode_t) -> FD ---
- /*
- Perform the operations on open files.
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html ]]
- */
- fcntl :: proc(fd: FD, cmd: FCNTL_Cmd, #c_vararg args: ..any) -> c.int ---
- /*
- Establish the connection between a file and a file descriptor.
- It shall create an open file description that refers to a file and a file descriptor that
- refers to that open file description. The file descriptor is used by other I/O functions to
- refer to that file.
- The path argument points to a pathname naming the file
- Returns: -1 on failure (setting errno), a file descriptor on success.
- Example:
- // The following example opens the file /tmp/file, either by creating it (if it does not already exist),
- // or by truncating its length to 0 (if it does exist). In the former case, if the call creates a new file,
- // the access permission bits in the file mode of the file are set to permit reading and writing by the owner,
- // and to permit reading only by group members and others.
- fd := posix.open("/tmp/file", { .WRONLY, .CREAT, .TRUNC }, { .IRUSR, .IWUSR, .IRGRP, .IROTH })
- // The following example uses the open() function to try to create the LOCKFILE file and open it for writing.
- // Since the open() function specifies the O_EXCL flag, the call fails if the file already exists.
- // In that case, the program assumes that someone else is updating the password file and exits.
- fd := posix.open("/etc/ptmp", { .WRONLY, .CREAT, .EXCL }, { .IRUSR, .IWUSR, .IRGRP, .IROTH })
- if fd == -1 {
- fmt.println("cannot open /etc/ptmp")
- }
- // The following example opens a file for writing, creating the file if it does not already exist.
- // If the file does exist, the system truncates the file to zero bytes.
- fd := posix.open("/etc/ptmp", { .WRONLY, .CREAT, .TRUNC }, { .IRUSR, .IWUSR, .IRGRP, .IROTH })
- if fd == -1 {
- fmt.println("cannot open output file")
- }
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html ]]
- */
- open :: proc(path: cstring, flags: O_Flags, #c_vararg mode: ..mode_t) -> FD ---
- /*
- Equivalent to the open() function except in the case where path specifies a relative path.
- In this case the file to be opened is determined relative to the directory associated with the
- file descriptor fd instead of the current working directory.
- Returns: -1 on failure (setting errno), a file descriptor on success.
- [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html ]]
- */
- openat :: proc(fd: FD, path: cstring, flags: O_Flags, mode: mode_t = {}) -> FD ---
- }
- FCNTL_Cmd :: enum c.int {
- DUPFD = F_DUPFD,
- DUPFD_CLOEXEC = F_DUPFD_CLOEXEC,
- GETFD = F_GETFD,
- SETFD = F_SETFD,
- GETFL = F_GETFL,
- SETFL = F_SETFL,
- GETLK = F_GETLK,
- SETLK = F_SETLK,
- SETLKW = F_SETLKW,
- GETOWN = F_GETOWN,
- SETOWN = F_SETOWN,
- }
- Lock_Type :: enum c.short {
- RDLCK = F_RDLCK,
- UNLCK = F_UNLCK,
- WRLCK = F_WRLCK,
- }
- O_Flag_Bits :: enum c.int {
- // Sets FD_CLOEXEC on the file descriptor.
- CLOEXEC = log2(O_CLOEXEC),
- // If not exists, combined with DIRECTORY will cause creation of a directory, otherwise a regular file.
- CREAT = log2(O_CREAT),
- // Fails if the opened descriptor would not be a directory.
- DIRECTORY = log2(O_DIRECTORY),
- // If combined with CREAT, causes a failure if the file already exists.
- EXCL = log2(O_EXCL),
- // If terminal device, do not make it the controlling terminal for the process.
- NOCTTY = log2(O_NOCTTY),
- // Don't follow symbolic links, fail with errno ELOOP.
- NOFOLLOW = log2(O_NOFOLLOW),
- // If exists and regular, truncate the length to 0.
- TRUNC = log2(O_TRUNC),
- // NOTE: use with `posix.O_TTY_INIT + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in
- // this bit set enum because it is 0 on some platforms and a value on others.
- // TTY_INIT = O_TTY_INIT,
- // Set file offset to end of file prior to each write.
- APPEND = log2(O_APPEND),
- // Write I/O shall complete as defined by synchronized I/O data integrity completion.
- DSYNC = log2(O_DSYNC),
- // Causes nonblocking behaviour in various situations.
- NONBLOCK = log2(O_NONBLOCK),
- // Write I/O shall complete as defined by synchronized I/O file integrity completion.
- SYNC = log2(O_SYNC),
- // NOTE: use with `posix.O_RSYNC + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in
- // this bit set enum because it is 0 on some platforms and a value on others.
- // RSYNC = O_RSYNC,
- // Execute only.
- EXEC = log2(O_EXEC),
- // Reading and writing.
- RDWR = log2(O_RDWR),
- // Writing only.
- WRONLY = log2(O_WRONLY),
- // Reading only.
- // RDONLY = 0, // Default
- }
- O_Flags :: bit_set[O_Flag_Bits; c.int]
- O_ACCMODE :: O_Flags{ .EXEC, .RDWR, .WRONLY }
- AT_Flag_Bits :: enum c.int {
- EACCESS = log2(AT_EACCESS),
- SYMLINK_NOFOLLOW = log2(AT_SYMLINK_NOFOLLOW),
- SYMLINK_FOLLOW = log2(AT_SYMLINK_FOLLOW),
- REMOVEDIR = log2(AT_REMOVEDIR),
- }
- AT_Flags :: bit_set[AT_Flag_Bits; c.int]
- when ODIN_OS == .Darwin {
- off_t :: distinct c.int64_t
- pid_t :: distinct c.int32_t
- F_DUPFD :: 0
- F_DUPFD_CLOEXEC :: 67
- F_GETFD :: 1
- F_SETFD :: 2
- F_GETFL :: 3
- F_SETFL :: 4
- F_GETLK :: 7
- F_SETLK :: 8
- F_SETLKW :: 9
- F_GETOWN :: 5
- F_SETOWN :: 6
- FD_CLOEXEC :: 1
- F_RDLCK :: 1
- F_UNLCK :: 2
- F_WRLCK :: 3
- O_CLOEXEC :: 0x01000000
- O_CREAT :: 0x00000200
- O_DIRECTORY :: 0x00100000
- O_EXCL :: 0x00000800
- O_NOCTTY :: 0x00020000
- O_NOFOLLOW :: 0x00000100
- O_TRUNC :: 0x00000400
- _O_TTY_INIT :: 0
- O_TTY_INIT :: O_Flags{}
- O_APPEND :: 0x00000008
- O_DSYNC :: 0x00400000
- O_NONBLOCK :: 0x00000004
- O_SYNC :: 0x0080
- _O_RSYNC :: 0
- O_RSYNC :: O_Flags{}
- O_EXEC :: 0x40000000
- O_RDONLY :: 0
- O_RDWR :: 0x0002
- O_WRONLY :: 0x0001
- _O_SEARCH :: O_EXEC | O_DIRECTORY
- O_SEARCH :: O_Flags{.EXEC, .DIRECTORY}
- AT_FDCWD: FD: -2
- AT_EACCESS :: 0x0010
- AT_SYMLINK_NOFOLLOW :: 0x0020
- AT_SYMLINK_FOLLOW :: 0x0040
- AT_REMOVEDIR :: 0x0080
- flock :: struct {
- l_start: off_t, /* [PSX] relative offset in bytes */
- l_len: off_t, /* [PSX] size; if 0 then until EOF */
- l_pid: pid_t, /* [PSX] process ID of the process holding the lock */
- l_type: Lock_Type, /* [PSX] type of lock */
- l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
- }
- } else when ODIN_OS == .FreeBSD {
- off_t :: distinct c.int64_t
- pid_t :: distinct c.int32_t
- F_DUPFD :: 0
- F_DUPFD_CLOEXEC :: 17
- F_GETFD :: 1
- F_SETFD :: 2
- F_GETFL :: 3
- F_SETFL :: 4
- F_GETLK :: 7
- F_SETLK :: 8
- F_SETLKW :: 9
- F_GETOWN :: 5
- F_SETOWN :: 6
- FD_CLOEXEC :: 1
- F_RDLCK :: 1
- F_UNLCK :: 2
- F_WRLCK :: 3
- O_CLOEXEC :: 0x00100000
- O_CREAT :: 0x0200
- O_DIRECTORY :: 0x00020000
- O_EXCL :: 0x0800
- O_NOCTTY :: 0x8000
- O_NOFOLLOW :: 0x0100
- O_TRUNC :: 0x0400
- _O_TTY_INIT :: 0x00080000
- O_TTY_INIT :: O_Flags{O_Flag_Bits(log2(_O_TTY_INIT))}
- O_APPEND :: 0x0008
- O_DSYNC :: 0x01000000
- O_NONBLOCK :: 0x0004
- O_SYNC :: 0x0080
- _O_RSYNC :: 0
- O_RSYNC :: O_Flags{} // NOTE: not defined in headers
- O_EXEC :: 0x00040000
- O_RDONLY :: 0
- O_RDWR :: 0x0002
- O_WRONLY :: 0x0001
- _O_SEARCH :: O_EXEC
- O_SEARCH :: O_Flags{ .EXEC }
- AT_FDCWD: FD: -100
- AT_EACCESS :: 0x0100
- AT_SYMLINK_NOFOLLOW :: 0x0200
- AT_SYMLINK_FOLLOW :: 0x0400
- AT_REMOVEDIR :: 0x0800
- flock :: struct {
- l_start: off_t, /* [PSX] relative offset in bytes */
- l_len: off_t, /* [PSX] size; if 0 then until EOF */
- l_pid: pid_t, /* [PSX] process ID of the process holding the lock */
- l_type: Lock_Type, /* [PSX] type of lock */
- l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
- l_sysid: c.int,
- }
- } else when ODIN_OS == .NetBSD {
- off_t :: distinct c.int64_t
- pid_t :: distinct c.int32_t
- F_DUPFD :: 0
- F_DUPFD_CLOEXEC :: 12
- F_GETFD :: 1
- F_SETFD :: 2
- F_GETFL :: 3
- F_SETFL :: 4
- F_GETLK :: 7
- F_SETLK :: 8
- F_SETLKW :: 9
- F_GETOWN :: 5
- F_SETOWN :: 6
- FD_CLOEXEC :: 1
- F_RDLCK :: 1
- F_UNLCK :: 2
- F_WRLCK :: 3
- O_CLOEXEC :: 0x00400000
- O_CREAT :: 0x0200
- O_DIRECTORY :: 0x0020000
- O_EXCL :: 0x0800
- O_NOCTTY :: 0x8000
- O_NOFOLLOW :: 0x0100
- O_TRUNC :: 0x0400
- _O_TTY_INIT :: 0
- O_TTY_INIT :: O_Flags{} // NOTE: not defined in the headers
- O_APPEND :: 0x0008
- O_DSYNC :: 0x010000
- O_NONBLOCK :: 0x0004
- O_SYNC :: 0x0080
- _O_RSYNC :: 0x0002
- O_RSYNC :: O_Flags{O_Flag_Bits(log2(_O_RSYNC))}
- O_EXEC :: 0x04000000
- O_RDONLY :: 0
- O_RDWR :: 0x0002
- O_WRONLY :: 0x0001
- _O_SEARCH :: 0x00800000
- O_SEARCH :: O_Flags{O_Flag_Bits(log2(_O_SEARCH))}
- AT_FDCWD: FD: -100
- AT_EACCESS :: 0x100
- AT_SYMLINK_NOFOLLOW :: 0x200
- AT_SYMLINK_FOLLOW :: 0x400
- AT_REMOVEDIR :: 0x800
- flock :: struct {
- l_start: off_t, /* [PSX] relative offset in bytes */
- l_len: off_t, /* [PSX] size; if 0 then until EOF */
- l_pid: pid_t, /* [PSX] process ID of the process holding the lock */
- l_type: Lock_Type, /* [PSX] type of lock */
- l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
- }
- } else when ODIN_OS == .OpenBSD {
- off_t :: distinct c.int64_t
- pid_t :: distinct c.int32_t
- F_DUPFD :: 0
- F_DUPFD_CLOEXEC :: 10
- F_GETFD :: 1
- F_SETFD :: 2
- F_GETFL :: 3
- F_SETFL :: 4
- F_GETLK :: 7
- F_SETLK :: 8
- F_SETLKW :: 9
- F_GETOWN :: 5
- F_SETOWN :: 6
- FD_CLOEXEC :: 1
- F_RDLCK :: 1
- F_UNLCK :: 2
- F_WRLCK :: 3
- O_CLOEXEC :: 0x10000
- O_CREAT :: 0x0200
- O_DIRECTORY :: 0x20000
- O_EXCL :: 0x0800
- O_NOCTTY :: 0x8000
- O_NOFOLLOW :: 0x0100
- O_TRUNC :: 0x0400
- _O_TTY_INIT :: 0
- O_TTY_INIT :: O_Flags{} // NOTE: not defined in the headers
- O_APPEND :: 0x0008
- O_DSYNC :: 0x010000
- O_NONBLOCK :: 0x0004
- O_SYNC :: 0x0080
- _O_RSYNC :: O_SYNC
- O_RSYNC :: O_Flags{.SYNC}
- O_EXEC :: 0x04000000 // NOTE: not defined in the headers
- O_RDONLY :: 0
- O_RDWR :: 0x0002
- O_WRONLY :: 0x0001
- _O_SEARCH :: 0
- O_SEARCH :: O_Flags{} // NOTE: not defined in the headers
- AT_FDCWD: FD: -100
- AT_EACCESS :: 0x01
- AT_SYMLINK_NOFOLLOW :: 0x02
- AT_SYMLINK_FOLLOW :: 0x04
- AT_REMOVEDIR :: 0x08
- flock :: struct {
- l_start: off_t, /* [PSX] relative offset in bytes */
- l_len: off_t, /* [PSX] size; if 0 then until EOF */
- l_pid: pid_t, /* [PSX] process ID of the process holding the lock */
- l_type: Lock_Type, /* [PSX] type of lock */
- l_whence: c.short, /* [PSX] flag (Whence) of starting offset */
- }
- } else when ODIN_OS == .Linux {
- off_t :: distinct c.int64_t
- pid_t :: distinct c.int
- F_DUPFD :: 0
- F_GETFD :: 1
- F_SETFD :: 2
- F_GETFL :: 3
- F_SETFL :: 4
- F_GETLK :: 5
- F_SETLK :: 6
- F_SETLKW :: 7
- F_SETOWN :: 8
- F_GETOWN :: 9
- F_RDLCK :: 0
- F_UNLCK :: 2
- F_WRLCK :: 1
- F_DUPFD_CLOEXEC :: 1030
- FD_CLOEXEC :: 1
- O_CREAT :: 0o0_000_100
- O_EXCL :: 0o0_000_200
- O_NOCTTY :: 0o0_000_400
- O_TRUNC :: 0o0_001_000
- O_DIRECTORY :: 0o0_200_000
- O_NOFOLLOW :: 0o0_400_000
- O_CLOEXEC :: 0o2_000_000
- _O_TTY_INIT :: 0
- O_TTY_INIT :: O_Flags{}
- O_APPEND :: 0o0_002_000
- O_NONBLOCK :: 0o0_004_000
- O_DSYNC :: 0o0_010_000
- O_SYNC :: 0o4_010_000
- _O_RSYNC :: 0
- O_RSYNC :: O_Flags{}
- O_EXEC :: 0x04000000 // NOTE: not defined in the headers
- O_RDONLY :: 0
- O_WRONLY :: 0o1
- O_RDWR :: 0o2
- _O_SEARCH :: 0
- O_SEARCH :: O_Flags{}
- AT_FDCWD: FD: -100
- AT_EACCESS :: 0x200
- AT_SYMLINK_NOFOLLOW :: 0x100
- AT_SYMLINK_FOLLOW :: 0x400
- AT_REMOVEDIR :: 0x200
- flock :: struct {
- l_type: Lock_Type, /* [PSX] type of lock. */
- l_whence: c.short, /* [PSX] flag (Whence) of starting offset. */
- l_start: off_t, /* [PSX] relative offset in bytes. */
- l_len: off_t, /* [PSX] size; if 0 then until EOF. */
- l_pid: pid_t, /* [PSX] process ID of the process holding the lock. */
- }
- }
|