diff --git a/src/header/semaphore/cbindgen.toml b/src/header/semaphore/cbindgen.toml index a96854c7ad..2b04643716 100644 --- a/src/header/semaphore/cbindgen.toml +++ b/src/header/semaphore/cbindgen.toml @@ -5,12 +5,21 @@ after_includes = """ """ trailer = """ #define SEM_FAILED ((sem_t *) -1) + +/* POSIX variadic named semaphore opener. cbindgen cannot emit variadic + functions, so the prototype is declared manually here. */ +sem_t *sem_open(const char *name, int oflag, ...); """ language = "C" style = "Type" no_includes = true cpp_compat = true +[fn] +# cbindgen cannot emit variadic functions automatically; write the sem_open +# prototype by hand in the trailer so C callers see the POSIX signature. +exclude = ["sem_open"] + [enum] prefix_with_name = true diff --git a/src/header/semaphore/mod.rs b/src/header/semaphore/mod.rs index a334c7e074..623a4ce399 100644 --- a/src/header/semaphore/mod.rs +++ b/src/header/semaphore/mod.rs @@ -144,7 +144,8 @@ pub unsafe extern "C" fn sem_init(sem: *mut sem_t, _pshared: c_int, value: c_uin #[unsafe(no_mangle)] pub unsafe extern "C" fn sem_open( name: *const c_char, - oflag: c_int, /* (va_list) mode: mode_t, value: c_uint */ + oflag: c_int, + mut __valist: ... ) -> *mut sem_t { if name.is_null() { ERRNO.set(EINVAL); return SEM_FAILED_PTR; } let name_bytes = unsafe { CStr::from_ptr(name) }.to_bytes().to_vec(); @@ -156,11 +157,10 @@ pub unsafe extern "C" fn sem_open( with_named_sems(|map| { if let Some(e) = map.get(&name_bytes) { e.refs.fetch_add(1, Ordering::Relaxed); } }); return ptr as *mut NamedSemaphore as *mut sem_t; } - let (mode, value): (mode_t, c_uint) = { - let oflag_ptr: *const c_int = &oflag; - let mode_ptr = unsafe { oflag_ptr.add(1) as *const mode_t }; - let value_ptr = unsafe { oflag_ptr.add(2) as *const c_uint }; - (unsafe { *mode_ptr }, if create { unsafe { *value_ptr } } else { 0 }) + let (mode, value): (mode_t, c_uint) = if create { + (unsafe { __valist.arg::() }, unsafe { __valist.arg::() }) + } else { + (0, 0) }; let ptr = unsafe { map_named_semaphore(name, oflag, mode, value) }; if ptr == SEM_FAILED_PTR { return SEM_FAILED_PTR; }