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)