Landin library reference source

hosted/libc/libc.ldn

1--  The C library beneath the hosted providers, declared as ordinary
2--  extern(c) imports on every hosted target.  hosted/io and hosted/heap
3--  reach the operating system only through these declarations; the compiler
4--  links the C library and knows none of its names.  Facts that differ
5--  between systems are selected by `compiler.os`, record layouts by the C
6--  ABI as well, and the native C headers of each system check them: the
7--  `stat` record in abi/core-io-file-identity, the rest in the hosted
8--  runtime and ABI fixtures.
9
10compiler.assert(compiler.os == linux or compiler.os == darwin
11                or compiler.os == freebsd)
12
13--- Open the file at the NUL-terminated `path` and return its descriptor, or
14--- -1 with the reason in errno.  `flags` is `o_rdonly` or `o_wronly`, or'd
15--- with `o_creat` and `o_trunc`; with `o_creat` the one variadic argument
16--- is the new file's permission bits as an `i32`, which the process umask
17--- filters.
18public extern(c) open: (path: ptr u8, flags: i32, ...) -> (descriptor: i32)
19
20--- Read at most `length` bytes from `descriptor` into `data`.  The count
21--- read, zero at end of file, or -1 with the reason in errno.  EINTR means
22--- nothing was transferred.
23public extern(c) read: (descriptor: i32, data: ptr mut u8, length: usize)
24                       -> (count: isize)
25
26--- Write at most `length` bytes from `data` to `descriptor`.  The count
27--- accepted, which may be short, or -1 with the reason in errno.  EINTR
28--- means nothing was transferred.
29public extern(c) write: (descriptor: i32, data: ptr u8, length: usize)
30                        -> (count: isize)
31
32--- Close `descriptor`: 0, or -1 with the reason in errno.  The descriptor
33--- may be released even when this fails, so a failed close is never
34--- retried.
35public extern(c) close: (descriptor: i32) -> (status: i32)
36
37--- The number of bytes before the first NUL at `text`.
38public extern(c) strlen: (text: ptr u8) -> (length: usize)
39
40--- What `malloc` returns when it cannot allocate: C's null pointer.
41public no_allocation: atom
42
43--- A `malloc` result: a block, or `no_allocation`.
44public allocation: type = no_allocation | ptr mut u8
45
46--- Allocate `size` bytes aligned for any C object, or `no_allocation`.
47--- `malloc(0)` may return either; a caller that needs a distinct block for
48--- an empty request asks for a nonzero size.
49public extern(c) malloc: (size: usize) -> (block: allocation)
50
51--- Give a block from `malloc` back to the C library.
52public extern(c) free: (block: ptr mut u8) -> none
53
54fixed if compiler.os == linux then
55    --- The calling thread's errno cell, `__errno_location` on Linux and
56    --- `__error` on Darwin and FreeBSD.  Read it immediately after the
57    --- failing call, before any other call that may set it.
58    public extern(c) link(symbol: "__errno_location") errno_cell:
59        () -> (cell: ptr mut i32)
60else
61    --- The calling thread's errno cell, `__errno_location` on Linux and
62    --- `__error` on Darwin and FreeBSD.  Read it immediately after the
63    --- failing call, before any other call that may set it.
64    public extern(c) link(symbol: "__error") errno_cell:
65        () -> (cell: ptr mut i32)
66end if
67
68--- The calling thread's errno: the reason the last failing C call gave.
69--- Read it immediately after that call, before any other call that may set
70--- it.
71public current_errno: () -> (number: i32) =
72    cell: ptr mut i32 = errno_cell()
73    number = cell.val
74end current_errno
75
76--- errno: the operation is not permitted.  The same on every hosted
77--- system.
78public eperm: i32 = 1
79--- errno: no such file or directory.
80public enoent: i32 = 2
81--- errno: interrupted by a signal before anything was transferred.
82public eintr: i32 = 4
83--- errno: permission denied.
84public eacces: i32 = 13
85--- errno: the file system is read-only.
86public erofs: i32 = 30
87
88--- `open` flag: read only.  The same on every hosted system.
89public o_rdonly: i32 = 0
90--- `open` flag: write only.  The same on every hosted system.
91public o_wronly: i32 = 1
92
93fixed if compiler.os == linux then
94    --- `open` flag: create the file if it does not exist.  Linux keeps one
95    --- value on every architecture; Darwin and FreeBSD share the BSD one.
96    public o_creat: i32 = 64
97    --- `open` flag: truncate an existing regular file to length zero.
98    public o_trunc: i32 = 512
99else
100    --- `open` flag: create the file if it does not exist.  Linux keeps one
101    --- value on every architecture; Darwin and FreeBSD share the BSD one.
102    public o_creat: i32 = 512
103    --- `open` flag: truncate an existing regular file to length zero.
104    public o_trunc: i32 = 1024
105end if
106
107--- C's `struct timespec`: whole seconds and the nanoseconds after them.
108public timespec: type = struct
109    seconds: i64
110    nanoseconds: i64
111end timespec
112
113--  Full records rather than guessed opaque storage, selected by hosted
114--  system and C ABI.  Darwin arm64 uses the ordinary stat symbol with its
115--  64-bit inode ABI.
116
117fixed if compiler.os == freebsd then
118    --- `sizeof (struct stat)` in the native C headers.
119    public file_status_size: usize = 224
120    --- C's `struct stat`, as `stat` fills it on this system.
121    public file_status: type = struct
122        device: u64
123        inode: u64
124        links: u64
125        mode: u16
126        bsdflags: i16
127        uid: u32
128        gid: u32
129        padding: i32
130        special_device: u64
131        accessed: timespec
132        modified: timespec
133        changed: timespec
134        born: timespec
135        bytes: i64
136        blocks: i64
137        block_size: i32
138        flags: u32
139        generation: u64
140        revision: u64
141        spare: [9]u64
142    end file_status
143elsif compiler.c_sysv_lp64 then
144    --- `sizeof (struct stat)` in the native C headers.
145    public file_status_size: usize = 144
146    --- C's `struct stat`, as `stat` fills it on this system.
147    public file_status: type = struct
148        device: u64
149        inode: u64
150        links: u64
151        mode: u32
152        uid: u32
153        gid: u32
154        padding: i32
155        special_device: u64
156        bytes: i64
157        block_size: i64
158        blocks: i64
159        accessed: timespec
160        modified: timespec
161        changed: timespec
162        reserved: [3]i64
163    end file_status
164elsif compiler.c_aapcs64_lp64 or compiler.c_riscv_lp64d then
165    --- `sizeof (struct stat)` in the native C headers.
166    public file_status_size: usize = 128
167    --- C's `struct stat`, as `stat` fills it on this system.
168    public file_status: type = struct
169        device: u64
170        inode: u64
171        mode: u32
172        links: u32
173        uid: u32
174        gid: u32
175        special_device: u64
176        padding1: u64
177        bytes: i64
178        block_size: i32
179        padding2: i32
180        blocks: i64
181        accessed: timespec
182        modified: timespec
183        changed: timespec
184        reserved: [2]u32
185    end file_status
186else
187    --- `sizeof (struct stat)` in the native C headers.
188    public file_status_size: usize = 144
189    --- C's `struct stat`, as `stat` fills it on this system.
190    public file_status: type = struct
191        device: i32
192        mode: u16
193        links: u16
194        inode: u64
195        uid: u32
196        gid: u32
197        special_device: i32
198        accessed: timespec
199        modified: timespec
200        changed: timespec
201        created: timespec
202        bytes: i64
203        blocks: i64
204        block_size: i32
205        flags: u32
206        generation: u32
207        spare: i32
208        reserved: [2]i64
209    end file_status
210end if
211
212--- Fill `result` with the status of the file `path` names, following
213--- symbolic links: 0, or -1 with the reason in errno.
214public extern(c) stat: (path: ptr u8, result: ptr mut file_status)
215                       -> (status: i32)