1const _SC_ARG_MAX: c_int = 0;
5const _SC_CHILD_MAX: c_int = 1;
6const _SC_CLK_TCK: c_int = 2;
7const _SC_NGROUPS_MAX: c_int = 3;
8const _SC_OPEN_MAX: c_int = 4;
9const _SC_STREAM_MAX: c_int = 5;
10const _SC_TZNAME_MAX: c_int = 6;
11const _SC_PAGE_SIZE: c_int = 30;
12const _SC_NPROCESSORS_CONF: c_int = 83;
13const _SC_NPROCESSORS_ONLN: c_int = 84;
14const _SC_PHYS_PAGES: c_int = 85;
15const _SC_AVPHYS_PAGES: c_int = 86;
16const _SC_IOV_MAX: c_int = 60;
17const _SC_SEM_NSEMS_MAX: c_int = 32;
18const _SC_SEM_VALUE_MAX: c_int = 33;
19const _SC_MQ_OPEN_MAX: c_int = 27;
20const _SC_MQ_PRIO_MAX: c_int = 28;
21const _SC_DELAYTIMER_MAX: c_int = 26;
22const _SC_THREAD_DESTRUCTOR_ITERATIONS: c_int = 73;
23const _SC_THREAD_KEYS_MAX: c_int = 74;
24const _SC_THREAD_STACK_MIN: c_int = 75;
25const _SC_LOGIN_NAME_MAX: c_int = 71;
26const _SC_TTY_NAME_MAX: c_int = 72;
27const _SC_SYMLOOP_MAX: c_int = 173;
28const _SC_HOST_NAME_MAX: c_int = 180;
29const _SC_NZERO: c_int = 109;
30const _SC_VERSION: c_int = 29;
31const _SC_2_VERSION: c_int = 46;
32const _SC_XOPEN_VERSION: c_int = 89;
33
34#[no_mangle]
35pub unsafe extern "C" fn mmap(
36 addr: *mut c_void,
37 len: usize,
38 prot: c_int,
39 flags: c_int,
40 fd: c_int,
41 off: i64,
42) -> *mut c_void {
43 let r = crate::syscall(
44 SYS_MMAP,
45 addr as c_long,
46 len as c_long,
47 prot as c_long,
48 flags as c_long,
49 fd as c_long,
50 off as c_long,
51 );
52 if r == -1 {
53 return -1isize as *mut c_void;
54 }
55 r as *mut c_void
56}
57
58#[no_mangle]
59pub unsafe extern "C" fn munmap(addr: *mut c_void, len: usize) -> c_int {
60 crate::syscall(SYS_MUNMAP, addr as c_long, len as c_long, 0, 0, 0, 0) as c_int
61}
62
63#[no_mangle]
64pub unsafe extern "C" fn pread(fd: c_int, buf: *mut c_void, count: usize, offset: i64) -> isize {
65 crate::syscall(
66 SYS_PREAD64,
67 fd as c_long,
68 buf as c_long,
69 count as c_long,
70 offset as c_long,
71 0,
72 0,
73 ) as isize
74}
75
76unsafe fn rlimit_sc(resource: c_int) -> c_long {
77 let mut lim: crate::Rlimit = core::mem::zeroed();
78 if crate::getrlimit(resource, &mut lim) != 0 {
79 return -1;
80 }
81 if lim.rlim_cur == !0u64 {
82 return -1;
83 }
84 if lim.rlim_cur > c_long::MAX as u64 {
85 return c_long::MAX;
86 }
87 lim.rlim_cur as c_long
88}
89
90unsafe fn online_cpus() -> c_long {
91 let mut set = [0u8; 128];
92 let r = crate::sched_getaffinity(0, set.len(), set.as_mut_ptr());
93 if r != 0 {
94 return 1;
95 }
96 let mut count = 0u32;
97 for b in set.iter() {
98 count += b.count_ones();
99 }
100 if count == 0 { 1 } else { count as c_long }
101}
102
103unsafe fn memory_pages(free: bool) -> c_long {
104 let mut info = [0u64; 16];
106 if crate::sysinfo(info.as_mut_ptr() as *mut core::ffi::c_void) != 0 {
107 return -1;
108 }
109 let total = if free {
110 info[5].saturating_add(info[7])
111 } else {
112 info[4]
113 };
114 let unit = (info[13] & 0xffff_ffff) as u64;
115 let bytes = total.saturating_mul(if unit == 0 { 1 } else { unit });
116 (bytes / 4096) as c_long
117}
118
119#[no_mangle]
120pub unsafe extern "C" fn sysconf(name: c_int) -> c_long {
121 const POSIX_VERSION: c_long = 200809;
122 match name {
123 _SC_ARG_MAX => 131072,
124 _SC_CHILD_MAX => rlimit_sc(crate::RLIMIT_NPROC),
125 _SC_CLK_TCK => 100,
126 _SC_NGROUPS_MAX => 32,
127 _SC_OPEN_MAX => rlimit_sc(crate::RLIMIT_NOFILE),
128 _SC_STREAM_MAX => -1,
129 _SC_TZNAME_MAX => 6,
130 7 | 8 => 1, 9 | 11 | 12 => POSIX_VERSION, 10 | 13 | 14 => -1, 15..=22 => POSIX_VERSION, 23 | 24 => -1, 25 => 0, _SC_DELAYTIMER_MAX => 0x7fffffff,
137 _SC_MQ_OPEN_MAX => -1,
138 _SC_MQ_PRIO_MAX => 32768,
139 _SC_VERSION => POSIX_VERSION,
140 _SC_PAGE_SIZE => 4096,
141 31 => 30, _SC_SEM_NSEMS_MAX => 256,
143 _SC_SEM_VALUE_MAX => 0x7fffffff,
144 34 | 35 => -1, 36 => 99, 37 => 2048, 38 => 99, 39 => 1000, 40 => 2, 42 | 43 => -1, 44 => 255, _SC_2_VERSION => POSIX_VERSION,
150 47 => POSIX_VERSION, 48..=52 => -1, _SC_IOV_MAX => 1024,
153 67 | 68 => POSIX_VERSION, 69 | 70 => -1, _SC_LOGIN_NAME_MAX => 256,
156 _SC_TTY_NAME_MAX => 32,
157 _SC_THREAD_DESTRUCTOR_ITERATIONS => 4,
158 _SC_THREAD_KEYS_MAX => 128,
159 _SC_THREAD_STACK_MIN => 2048,
160 76 => -1, 77 | 78 | 79 => POSIX_VERSION, 80 | 81 => -1, 82 => POSIX_VERSION, _SC_NPROCESSORS_CONF | _SC_NPROCESSORS_ONLN => online_cpus(),
165 _SC_PHYS_PAGES => memory_pages(false),
166 _SC_AVPHYS_PAGES => memory_pages(true),
167 87 | 88 => -1, _SC_XOPEN_VERSION => 700,
169 90 => 700, 91 => 1, 92 => -1, 93 | 94 => 1, 95 => -1, 97 => -1, 98..=100 => -1, _SC_NZERO => 20,
177 125 | 126 | 128 => -1, 127 => 1, 129..=131 => -1, 132 | 133 => POSIX_VERSION, 137 | 138 | 139 => POSIX_VERSION,
182 149 => POSIX_VERSION, 153 | 154 | 155 | 157 | 159 => POSIX_VERSION,
184 160 | 161 => -1,
185 164 => POSIX_VERSION, 165 => -1, 168..=172 => -1, _SC_SYMLOOP_MAX => 40,
189 174 => 0, 175 => -1,
191 176 | 177 | 179 => -1, 178 => 1, _SC_HOST_NAME_MAX => 255,
194 181..=184 => -1, 235 | 236 => POSIX_VERSION, 237 | 238 | 240 => -1, 239 => 1, 241..=245 => -1, _ => {
200 crate::__errno_location().write(EINVAL);
201 -1
202 }
203 }
204}
205
206#[no_mangle]
207pub unsafe extern "C" fn execle(path: *const c_char, arg: *const c_char, mut args: ...) -> c_int {
208 let mut argv: [*const c_char; 128] = [core::ptr::null(); 128];
209 argv[0] = arg;
210 let mut n = 1usize;
211 loop {
212 let a: *const c_char = args.next_arg();
213 if a.is_null() {
214 break;
215 }
216 if n >= argv.len() - 1 {
217 crate::__errno_location().write(E2BIG);
218 return -1;
219 }
220 argv[n] = a;
221 n += 1;
222 }
223 argv[n] = core::ptr::null();
224 let envp: *const *const c_char = args.next_arg();
225 crate::execve(path, argv.as_ptr(), envp)
226}
227
228#[no_mangle]
229pub unsafe extern "C" fn flockfile(f: *mut crate::FILE) {
230 if (*f).lock < 0 { return; }
231 let tid = crate::sys_gettid() as i32;
232 loop {
233 let v = crate::a_load(&raw const (*f).lock);
234 if v == tid {
235 (*f).lockcount += 1;
236 return;
237 }
238 if v == 0 && crate::a_cas(&raw mut (*f).lock, 0, tid) == 0 {
239 (*f).lockcount = 1;
240 return;
241 }
242 if v != 0 {
243 crate::futex_wait(&raw mut (*f).lock, v);
244 }
245 }
246}
247
248#[no_mangle]
249pub unsafe extern "C" fn funlockfile(f: *mut crate::FILE) {
250 if (*f).lock < 0 { return; }
251 if (*f).lockcount > 1 {
252 (*f).lockcount -= 1;
253 return;
254 }
255 (*f).lockcount = 0;
256 crate::a_store(&raw mut (*f).lock, 0);
257 crate::futex_wake(&raw mut (*f).lock, 1);
258}
259
260#[no_mangle]
261pub unsafe extern "C" fn __libc_current_sigrtmin() -> c_int {
262 34
263}
264
265#[no_mangle]
266pub unsafe extern "C" fn strdup(s: *const c_char) -> *mut c_char {
267 if s.is_null() {
268 return core::ptr::null_mut();
269 }
270 let len = crate::strlen(s);
271 let p = crate::malloc(len + 1) as *mut c_char;
272 if p.is_null() {
273 return core::ptr::null_mut();
274 }
275 crate::memcpy(p as *mut c_void, s as *const c_void, len + 1);
276 p
277}
278
279static mut MKTEMP_COUNTER: c_uint = 0;
280
281unsafe fn mktemp_internal(
282 template: *mut c_char,
283 mkdir_fn: Option<unsafe extern "C" fn(*const c_char, c_uint) -> c_int>,
284) -> *mut c_char {
285 if template.is_null() {
286 crate::__errno_location().write(EINVAL);
287 return core::ptr::null_mut();
288 }
289 let len = crate::strlen(template);
290 if len < 6 {
291 crate::__errno_location().write(EINVAL);
292 return core::ptr::null_mut();
293 }
294 let mut xcount = 0usize;
295 while xcount < 6 {
296 let ch = *template.add(len - 1 - xcount) as u8;
297 if ch != b'X' {
298 break;
299 }
300 xcount += 1;
301 }
302 if xcount != 6 {
303 crate::__errno_location().write(EINVAL);
304 return core::ptr::null_mut();
305 }
306 let _pid = crate::getpid();
307 let mut c = MKTEMP_COUNTER;
308 for _ in 0..1000 {
309 let mut n = c;
310 for i in 0..6 {
311 let digit = (n % 36) as u8;
312 let ch = if digit < 10 { b'0' + digit } else { b'a' + digit - 10 };
313 *template.add(len - 6 + i) = ch as c_char;
314 n /= 36;
315 }
316 c = c.wrapping_add(1);
317 if mkdir_fn.is_some() {
318 if crate::mkdir(template, 0o700) == 0 {
319 MKTEMP_COUNTER = c;
320 return template;
321 }
322 let e = crate::__errno_location().read();
323 if e != EEXIST && e != EINTR {
324 break;
325 }
326 } else {
327 MKTEMP_COUNTER = c;
328 return template;
329 }
330 }
331 MKTEMP_COUNTER = c;
332 template
333}
334
335#[no_mangle]
336pub unsafe extern "C" fn mkdtemp(template: *mut c_char) -> *mut c_char {
337 mktemp_internal(template, Some(crate::mkdir))
338}
339
340#[no_mangle]
341pub unsafe extern "C" fn mktemp(template: *mut c_char) -> *mut c_char {
342 mktemp_internal(template, None)
343}