Skip to content

Commit 032e40e

Browse files
authored
Merge pull request #285 from danog/php_8.3_sapi
Expose SapiModule
2 parents 2067c31 + 3081630 commit 032e40e

File tree

7 files changed

+172
-2
lines changed

7 files changed

+172
-2
lines changed

allowed_bindings.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ bind! {
2727
_emalloc,
2828
_zend_executor_globals,
2929
_sapi_globals_struct,
30+
_sapi_module_struct,
3031
_zend_expected_type,
3132
_zend_expected_type_Z_EXPECTED_ARRAY,
3233
_zend_expected_type_Z_EXPECTED_BOOL,
@@ -243,6 +244,7 @@ bind! {
243244
zend_class_unserialize_deny,
244245
zend_executor_globals,
245246
sapi_globals_struct,
247+
sapi_module_struct,
246248
zend_objects_store_del,
247249
zend_hash_move_forward_ex,
248250
zend_hash_get_current_key_type_ex,
@@ -254,6 +256,7 @@ bind! {
254256
ZEND_ACC_NOT_SERIALIZABLE,
255257
executor_globals,
256258
sapi_globals,
259+
sapi_module,
257260
php_printf,
258261
__zend_malloc,
259262
tsrm_get_ls_cache,

docsrs_bindings.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ pub type __time_t = ::std::os::raw::c_long;
201201
pub type __blksize_t = ::std::os::raw::c_long;
202202
pub type __blkcnt_t = ::std::os::raw::c_long;
203203
pub type __syscall_slong_t = ::std::os::raw::c_long;
204+
pub type gid_t = __gid_t;
205+
pub type uid_t = __uid_t;
204206
#[repr(C)]
205207
#[derive(Debug, Copy, Clone)]
206208
pub struct __sigset_t {
@@ -2265,6 +2267,12 @@ extern "C" {
22652267
}
22662268
#[repr(C)]
22672269
#[derive(Debug, Copy, Clone)]
2270+
pub struct sapi_header_struct {
2271+
pub header: *mut ::std::os::raw::c_char,
2272+
pub header_len: usize,
2273+
}
2274+
#[repr(C)]
2275+
#[derive(Debug, Copy, Clone)]
22682276
pub struct sapi_headers_struct {
22692277
pub headers: zend_llist,
22702278
pub http_response_code: ::std::os::raw::c_int,
@@ -2273,6 +2281,10 @@ pub struct sapi_headers_struct {
22732281
pub http_status_line: *mut ::std::os::raw::c_char,
22742282
}
22752283
pub type sapi_post_entry = _sapi_post_entry;
2284+
pub type sapi_module_struct = _sapi_module_struct;
2285+
extern "C" {
2286+
pub static mut sapi_module: sapi_module_struct;
2287+
}
22762288
#[repr(C)]
22772289
#[derive(Debug, Copy, Clone)]
22782290
pub struct sapi_request_info {
@@ -2323,6 +2335,111 @@ pub type sapi_globals_struct = _sapi_globals_struct;
23232335
extern "C" {
23242336
pub static mut sapi_globals: sapi_globals_struct;
23252337
}
2338+
pub const sapi_header_op_enum_SAPI_HEADER_REPLACE: sapi_header_op_enum = 0;
2339+
pub const sapi_header_op_enum_SAPI_HEADER_ADD: sapi_header_op_enum = 1;
2340+
pub const sapi_header_op_enum_SAPI_HEADER_DELETE: sapi_header_op_enum = 2;
2341+
pub const sapi_header_op_enum_SAPI_HEADER_DELETE_ALL: sapi_header_op_enum = 3;
2342+
pub const sapi_header_op_enum_SAPI_HEADER_SET_STATUS: sapi_header_op_enum = 4;
2343+
pub type sapi_header_op_enum = ::std::os::raw::c_uint;
2344+
#[repr(C)]
2345+
#[derive(Debug, Copy, Clone)]
2346+
pub struct _sapi_module_struct {
2347+
pub name: *mut ::std::os::raw::c_char,
2348+
pub pretty_name: *mut ::std::os::raw::c_char,
2349+
pub startup: ::std::option::Option<
2350+
unsafe extern "C" fn(sapi_module: *mut _sapi_module_struct) -> ::std::os::raw::c_int,
2351+
>,
2352+
pub shutdown: ::std::option::Option<
2353+
unsafe extern "C" fn(sapi_module: *mut _sapi_module_struct) -> ::std::os::raw::c_int,
2354+
>,
2355+
pub activate: ::std::option::Option<unsafe extern "C" fn() -> ::std::os::raw::c_int>,
2356+
pub deactivate: ::std::option::Option<unsafe extern "C" fn() -> ::std::os::raw::c_int>,
2357+
pub ub_write: ::std::option::Option<
2358+
unsafe extern "C" fn(str_: *const ::std::os::raw::c_char, str_length: usize) -> usize,
2359+
>,
2360+
pub flush:
2361+
::std::option::Option<unsafe extern "C" fn(server_context: *mut ::std::os::raw::c_void)>,
2362+
pub get_stat: ::std::option::Option<unsafe extern "C" fn() -> *mut zend_stat_t>,
2363+
pub getenv: ::std::option::Option<
2364+
unsafe extern "C" fn(
2365+
name: *const ::std::os::raw::c_char,
2366+
name_len: usize,
2367+
) -> *mut ::std::os::raw::c_char,
2368+
>,
2369+
pub sapi_error: ::std::option::Option<
2370+
unsafe extern "C" fn(
2371+
type_: ::std::os::raw::c_int,
2372+
error_msg: *const ::std::os::raw::c_char,
2373+
...
2374+
),
2375+
>,
2376+
pub header_handler: ::std::option::Option<
2377+
unsafe extern "C" fn(
2378+
sapi_header: *mut sapi_header_struct,
2379+
op: sapi_header_op_enum,
2380+
sapi_headers: *mut sapi_headers_struct,
2381+
) -> ::std::os::raw::c_int,
2382+
>,
2383+
pub send_headers: ::std::option::Option<
2384+
unsafe extern "C" fn(sapi_headers: *mut sapi_headers_struct) -> ::std::os::raw::c_int,
2385+
>,
2386+
pub send_header: ::std::option::Option<
2387+
unsafe extern "C" fn(
2388+
sapi_header: *mut sapi_header_struct,
2389+
server_context: *mut ::std::os::raw::c_void,
2390+
),
2391+
>,
2392+
pub read_post: ::std::option::Option<
2393+
unsafe extern "C" fn(buffer: *mut ::std::os::raw::c_char, count_bytes: usize) -> usize,
2394+
>,
2395+
pub read_cookies: ::std::option::Option<unsafe extern "C" fn() -> *mut ::std::os::raw::c_char>,
2396+
pub register_server_variables:
2397+
::std::option::Option<unsafe extern "C" fn(track_vars_array: *mut zval)>,
2398+
pub log_message: ::std::option::Option<
2399+
unsafe extern "C" fn(
2400+
message: *const ::std::os::raw::c_char,
2401+
syslog_type_int: ::std::os::raw::c_int,
2402+
),
2403+
>,
2404+
pub get_request_time:
2405+
::std::option::Option<unsafe extern "C" fn(request_time: *mut f64) -> zend_result>,
2406+
pub terminate_process: ::std::option::Option<unsafe extern "C" fn()>,
2407+
pub php_ini_path_override: *mut ::std::os::raw::c_char,
2408+
pub default_post_reader: ::std::option::Option<unsafe extern "C" fn()>,
2409+
pub treat_data: ::std::option::Option<
2410+
unsafe extern "C" fn(
2411+
arg: ::std::os::raw::c_int,
2412+
str_: *mut ::std::os::raw::c_char,
2413+
destArray: *mut zval,
2414+
),
2415+
>,
2416+
pub executable_location: *mut ::std::os::raw::c_char,
2417+
pub php_ini_ignore: ::std::os::raw::c_int,
2418+
pub php_ini_ignore_cwd: ::std::os::raw::c_int,
2419+
pub get_fd: ::std::option::Option<
2420+
unsafe extern "C" fn(fd: *mut ::std::os::raw::c_int) -> ::std::os::raw::c_int,
2421+
>,
2422+
pub force_http_10: ::std::option::Option<unsafe extern "C" fn() -> ::std::os::raw::c_int>,
2423+
pub get_target_uid:
2424+
::std::option::Option<unsafe extern "C" fn(arg1: *mut uid_t) -> ::std::os::raw::c_int>,
2425+
pub get_target_gid:
2426+
::std::option::Option<unsafe extern "C" fn(arg1: *mut gid_t) -> ::std::os::raw::c_int>,
2427+
pub input_filter: ::std::option::Option<
2428+
unsafe extern "C" fn(
2429+
arg: ::std::os::raw::c_int,
2430+
var: *const ::std::os::raw::c_char,
2431+
val: *mut *mut ::std::os::raw::c_char,
2432+
val_len: usize,
2433+
new_val_len: *mut usize,
2434+
) -> ::std::os::raw::c_uint,
2435+
>,
2436+
pub ini_defaults:
2437+
::std::option::Option<unsafe extern "C" fn(configuration_hash: *mut HashTable)>,
2438+
pub phpinfo_as_text: ::std::os::raw::c_int,
2439+
pub ini_entries: *const ::std::os::raw::c_char,
2440+
pub additional_functions: *const zend_function_entry,
2441+
pub input_filter_init: ::std::option::Option<unsafe extern "C" fn() -> ::std::os::raw::c_uint>,
2442+
}
23262443
#[repr(C)]
23272444
#[derive(Debug, Copy, Clone)]
23282445
pub struct _sapi_post_entry {

src/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ extern "C" {
2727
pub fn ext_php_rs_zend_object_release(obj: *mut zend_object);
2828
pub fn ext_php_rs_executor_globals() -> *mut zend_executor_globals;
2929
pub fn ext_php_rs_sapi_globals() -> *mut sapi_globals_struct;
30+
pub fn ext_php_rs_sapi_module() -> *mut sapi_module_struct;
3031
pub fn ext_php_rs_zend_try_catch(
3132
func: unsafe extern "C" fn(*const c_void) -> *const c_void,
3233
ctx: *const c_void,

src/wrapper.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ sapi_globals_struct *ext_php_rs_sapi_globals() {
5252
#endif
5353
}
5454

55+
sapi_module_struct *ext_php_rs_sapi_module() {
56+
return &sapi_module;
57+
}
58+
5559
bool ext_php_rs_zend_try_catch(void* (*callback)(void *), void *ctx, void **result) {
5660
zend_try {
5761
*result = callback(ctx);

src/wrapper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@ void *ext_php_rs_zend_object_alloc(size_t obj_size, zend_class_entry *ce);
3333
void ext_php_rs_zend_object_release(zend_object *obj);
3434
zend_executor_globals *ext_php_rs_executor_globals();;
3535
sapi_globals_struct *ext_php_rs_sapi_globals();
36+
sapi_module_struct *ext_php_rs_sapi_module();
3637
bool ext_php_rs_zend_try_catch(void* (*callback)(void *), void *ctx, void **result);
3738
void ext_php_rs_zend_bailout();

src/zend/globals.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use crate::boxed::ZBox;
99
#[cfg(php82)]
1010
use crate::ffi::zend_atomic_bool_store;
1111
use crate::ffi::{
12-
_sapi_globals_struct, _zend_executor_globals, ext_php_rs_executor_globals,
13-
ext_php_rs_sapi_globals, zend_ini_entry,
12+
_sapi_globals_struct, _sapi_module_struct, _zend_executor_globals, ext_php_rs_executor_globals,
13+
ext_php_rs_sapi_globals, ext_php_rs_sapi_module, zend_ini_entry,
1414
};
1515
use crate::types::{ZendHashTable, ZendObject};
1616

@@ -20,6 +20,9 @@ pub type ExecutorGlobals = _zend_executor_globals;
2020
/// Stores global SAPI variables used in the PHP executor.
2121
pub type SapiGlobals = _sapi_globals_struct;
2222

23+
/// Stores the SAPI module used in the PHP executor.
24+
pub type SapiModule = _sapi_module_struct;
25+
2326
impl ExecutorGlobals {
2427
/// Returns a reference to the PHP executor globals.
2528
///
@@ -167,6 +170,40 @@ impl SapiGlobals {
167170
}
168171
}
169172

173+
impl SapiModule {
174+
/// Returns a reference to the PHP SAPI module.
175+
///
176+
/// The executor globals are guarded by a RwLock. There can be multiple
177+
/// immutable references at one time but only ever one mutable reference.
178+
/// Attempting to retrieve the globals while already holding the global
179+
/// guard will lead to a deadlock. Dropping the globals guard will release
180+
/// the lock.
181+
pub fn get() -> GlobalReadGuard<Self> {
182+
// SAFETY: PHP executor globals are statically declared therefore should never
183+
// return an invalid pointer.
184+
let globals = unsafe { ext_php_rs_sapi_module().as_ref() }
185+
.expect("Static executor globals were invalid");
186+
let guard = SAPI_MODULE_LOCK.read();
187+
GlobalReadGuard { globals, guard }
188+
}
189+
190+
/// Returns a mutable reference to the PHP executor globals.
191+
///
192+
/// The executor globals are guarded by a RwLock. There can be multiple
193+
/// immutable references at one time but only ever one mutable reference.
194+
/// Attempting to retrieve the globals while already holding the global
195+
/// guard will lead to a deadlock. Dropping the globals guard will release
196+
/// the lock.
197+
pub fn get_mut() -> GlobalWriteGuard<Self> {
198+
// SAFETY: PHP executor globals are statically declared therefore should never
199+
// return an invalid pointer.
200+
let globals = unsafe { ext_php_rs_sapi_module().as_mut() }
201+
.expect("Static executor globals were invalid");
202+
let guard = SAPI_MODULE_LOCK.write();
203+
GlobalWriteGuard { globals, guard }
204+
}
205+
}
206+
170207
/// Executor globals rwlock.
171208
///
172209
/// PHP provides no indication if the executor globals are being accessed so
@@ -179,6 +216,12 @@ static GLOBALS_LOCK: RwLock<()> = const_rwlock(());
179216
/// this is only effective on the Rust side.
180217
static SAPI_LOCK: RwLock<()> = const_rwlock(());
181218

219+
/// SAPI globals rwlock.
220+
///
221+
/// PHP provides no indication if the executor globals are being accessed so
222+
/// this is only effective on the Rust side.
223+
static SAPI_MODULE_LOCK: RwLock<()> = const_rwlock(());
224+
182225
/// Wrapper guard that contains a reference to a given type `T`. Dropping a
183226
/// guard releases the lock on the relevant rwlock.
184227
pub struct GlobalReadGuard<T: 'static> {

src/zend/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub use function::Function;
2121
pub use function::FunctionEntry;
2222
pub use globals::ExecutorGlobals;
2323
pub use globals::SapiGlobals;
24+
pub use globals::SapiModule;
2425
pub use handlers::ZendObjectHandlers;
2526
pub use ini_entry_def::IniEntryDef;
2627
pub use module::ModuleEntry;

0 commit comments

Comments
 (0)