Skip to main content

c/
regression_stubs.rs

1// Stubs and minimal implementations for symbols required by libc-test
2// regression cases that currently fail to link.
3
4const _SC_PAGE_SIZE: c_int = 30;
5
6#[no_mangle]
7pub unsafe extern "C" fn mmap(
8    addr: *mut c_void,
9    len: usize,
10    prot: c_int,
11    flags: c_int,
12    fd: c_int,
13    off: i64,
14) -> *mut c_void {
15    crate::syscall(
16        SYS_MMAP,
17        addr as c_long,
18        len as c_long,
19        prot as c_long,
20        flags as c_long,
21        fd as c_long,
22        off as c_long,
23    ) as *mut c_void
24}
25
26#[no_mangle]
27pub unsafe extern "C" fn munmap(addr: *mut c_void, len: usize) -> c_int {
28    crate::syscall(SYS_MUNMAP, addr as c_long, len as c_long, 0, 0, 0, 0) as c_int
29}
30
31#[no_mangle]
32pub unsafe extern "C" fn pread(fd: c_int, buf: *mut c_void, count: usize, offset: i64) -> isize {
33    crate::syscall(
34        SYS_PREAD64,
35        fd as c_long,
36        buf as c_long,
37        count as c_long,
38        offset as c_long,
39        0,
40        0,
41    ) as isize
42}
43
44#[no_mangle]
45pub unsafe extern "C" fn sysconf(name: c_int) -> c_long {
46    match name {
47        _SC_PAGE_SIZE => 4096,
48        _ => {
49            crate::__errno_location().write(EINVAL);
50            -1
51        }
52    }
53}
54
55#[no_mangle]
56pub unsafe extern "C" fn execle(path: *const c_char, arg: *const c_char, mut args: ...) -> c_int {
57    let mut argv: [*const c_char; 128] = [core::ptr::null(); 128];
58    argv[0] = arg;
59    let mut n = 1usize;
60    loop {
61        let a: *const c_char = args.next_arg();
62        if a.is_null() {
63            break;
64        }
65        if n >= argv.len() - 1 {
66            crate::__errno_location().write(E2BIG);
67            return -1;
68        }
69        argv[n] = a;
70        n += 1;
71    }
72    argv[n] = core::ptr::null();
73    let envp: *const *const c_char = args.next_arg();
74    crate::syscall(
75        SYS_EXECVE,
76        path as c_long,
77        argv.as_ptr() as c_long,
78        envp as c_long,
79        0,
80        0,
81        0,
82    ) as c_int
83}
84
85#[no_mangle]
86pub unsafe extern "C" fn flockfile(f: *mut crate::FILE) {
87    if (*f).lock < 0 { return; }
88    let tid = crate::sys_gettid() as i32;
89    loop {
90        let v = crate::a_load(&raw const (*f).lock);
91        if v == tid {
92            (*f).lockcount += 1;
93            return;
94        }
95        if v == 0 && crate::a_cas(&raw mut (*f).lock, 0, tid) == 0 {
96            (*f).lockcount = 1;
97            return;
98        }
99        if v != 0 {
100            crate::futex_wait(&raw mut (*f).lock, v);
101        }
102    }
103}
104
105#[no_mangle]
106pub unsafe extern "C" fn funlockfile(f: *mut crate::FILE) {
107    if (*f).lock < 0 { return; }
108    if (*f).lockcount > 1 {
109        (*f).lockcount -= 1;
110        return;
111    }
112    (*f).lockcount = 0;
113    crate::a_store(&raw mut (*f).lock, 0);
114    crate::futex_wake(&raw mut (*f).lock, 1);
115}
116
117#[no_mangle]
118pub unsafe extern "C" fn __libc_current_sigrtmin() -> c_int {
119    34
120}
121
122#[no_mangle]
123pub unsafe extern "C" fn strdup(s: *const c_char) -> *mut c_char {
124    if s.is_null() {
125        return core::ptr::null_mut();
126    }
127    let len = crate::strlen(s);
128    let p = crate::malloc(len + 1) as *mut c_char;
129    if p.is_null() {
130        return core::ptr::null_mut();
131    }
132    crate::memcpy(p as *mut c_void, s as *const c_void, len + 1);
133    p
134}
135
136static mut MKTEMP_COUNTER: c_uint = 0;
137
138unsafe fn mktemp_internal(
139    template: *mut c_char,
140    mkdir_fn: Option<unsafe extern "C" fn(*const c_char, c_uint) -> c_int>,
141) -> *mut c_char {
142    if template.is_null() {
143        crate::__errno_location().write(EINVAL);
144        return core::ptr::null_mut();
145    }
146    let len = crate::strlen(template);
147    if len < 6 {
148        crate::__errno_location().write(EINVAL);
149        return core::ptr::null_mut();
150    }
151    let mut xcount = 0usize;
152    while xcount < 6 {
153        let ch = *template.add(len - 1 - xcount) as u8;
154        if ch != b'X' {
155            break;
156        }
157        xcount += 1;
158    }
159    if xcount != 6 {
160        crate::__errno_location().write(EINVAL);
161        return core::ptr::null_mut();
162    }
163    let _pid = crate::getpid();
164    let mut c = MKTEMP_COUNTER;
165    for _ in 0..1000 {
166        let mut n = c;
167        for i in 0..6 {
168            let digit = (n % 36) as u8;
169            let ch = if digit < 10 { b'0' + digit } else { b'a' + digit - 10 };
170            *template.add(len - 6 + i) = ch as c_char;
171            n /= 36;
172        }
173        c = c.wrapping_add(1);
174        if mkdir_fn.is_some() {
175            if crate::mkdir(template, 0o700) == 0 {
176                MKTEMP_COUNTER = c;
177                return template;
178            }
179            let e = crate::__errno_location().read();
180            if e != EEXIST && e != EINTR {
181                break;
182            }
183        } else {
184            MKTEMP_COUNTER = c;
185            return template;
186        }
187    }
188    MKTEMP_COUNTER = c;
189    template
190}
191
192#[no_mangle]
193pub unsafe extern "C" fn mkdtemp(template: *mut c_char) -> *mut c_char {
194    mktemp_internal(template, Some(crate::mkdir))
195}
196
197#[no_mangle]
198pub unsafe extern "C" fn mktemp(template: *mut c_char) -> *mut c_char {
199    mktemp_internal(template, None)
200}