Merge pull request #285 from danog/php_8.3_sapi

Expose SapiModule
This commit is contained in:
Daniil Gentili 2023-11-24 12:13:41 +01:00 committed by GitHub
commit 032e40ede6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 172 additions and 2 deletions

View File

@ -27,6 +27,7 @@ bind! {
_emalloc,
_zend_executor_globals,
_sapi_globals_struct,
_sapi_module_struct,
_zend_expected_type,
_zend_expected_type_Z_EXPECTED_ARRAY,
_zend_expected_type_Z_EXPECTED_BOOL,
@ -243,6 +244,7 @@ bind! {
zend_class_unserialize_deny,
zend_executor_globals,
sapi_globals_struct,
sapi_module_struct,
zend_objects_store_del,
zend_hash_move_forward_ex,
zend_hash_get_current_key_type_ex,
@ -254,6 +256,7 @@ bind! {
ZEND_ACC_NOT_SERIALIZABLE,
executor_globals,
sapi_globals,
sapi_module,
php_printf,
__zend_malloc,
tsrm_get_ls_cache,

View File

@ -201,6 +201,8 @@ pub type __time_t = ::std::os::raw::c_long;
pub type __blksize_t = ::std::os::raw::c_long;
pub type __blkcnt_t = ::std::os::raw::c_long;
pub type __syscall_slong_t = ::std::os::raw::c_long;
pub type gid_t = __gid_t;
pub type uid_t = __uid_t;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct __sigset_t {
@ -2265,6 +2267,12 @@ extern "C" {
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct sapi_header_struct {
pub header: *mut ::std::os::raw::c_char,
pub header_len: usize,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct sapi_headers_struct {
pub headers: zend_llist,
pub http_response_code: ::std::os::raw::c_int,
@ -2273,6 +2281,10 @@ pub struct sapi_headers_struct {
pub http_status_line: *mut ::std::os::raw::c_char,
}
pub type sapi_post_entry = _sapi_post_entry;
pub type sapi_module_struct = _sapi_module_struct;
extern "C" {
pub static mut sapi_module: sapi_module_struct;
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct sapi_request_info {
@ -2323,6 +2335,111 @@ pub type sapi_globals_struct = _sapi_globals_struct;
extern "C" {
pub static mut sapi_globals: sapi_globals_struct;
}
pub const sapi_header_op_enum_SAPI_HEADER_REPLACE: sapi_header_op_enum = 0;
pub const sapi_header_op_enum_SAPI_HEADER_ADD: sapi_header_op_enum = 1;
pub const sapi_header_op_enum_SAPI_HEADER_DELETE: sapi_header_op_enum = 2;
pub const sapi_header_op_enum_SAPI_HEADER_DELETE_ALL: sapi_header_op_enum = 3;
pub const sapi_header_op_enum_SAPI_HEADER_SET_STATUS: sapi_header_op_enum = 4;
pub type sapi_header_op_enum = ::std::os::raw::c_uint;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _sapi_module_struct {
pub name: *mut ::std::os::raw::c_char,
pub pretty_name: *mut ::std::os::raw::c_char,
pub startup: ::std::option::Option<
unsafe extern "C" fn(sapi_module: *mut _sapi_module_struct) -> ::std::os::raw::c_int,
>,
pub shutdown: ::std::option::Option<
unsafe extern "C" fn(sapi_module: *mut _sapi_module_struct) -> ::std::os::raw::c_int,
>,
pub activate: ::std::option::Option<unsafe extern "C" fn() -> ::std::os::raw::c_int>,
pub deactivate: ::std::option::Option<unsafe extern "C" fn() -> ::std::os::raw::c_int>,
pub ub_write: ::std::option::Option<
unsafe extern "C" fn(str_: *const ::std::os::raw::c_char, str_length: usize) -> usize,
>,
pub flush:
::std::option::Option<unsafe extern "C" fn(server_context: *mut ::std::os::raw::c_void)>,
pub get_stat: ::std::option::Option<unsafe extern "C" fn() -> *mut zend_stat_t>,
pub getenv: ::std::option::Option<
unsafe extern "C" fn(
name: *const ::std::os::raw::c_char,
name_len: usize,
) -> *mut ::std::os::raw::c_char,
>,
pub sapi_error: ::std::option::Option<
unsafe extern "C" fn(
type_: ::std::os::raw::c_int,
error_msg: *const ::std::os::raw::c_char,
...
),
>,
pub header_handler: ::std::option::Option<
unsafe extern "C" fn(
sapi_header: *mut sapi_header_struct,
op: sapi_header_op_enum,
sapi_headers: *mut sapi_headers_struct,
) -> ::std::os::raw::c_int,
>,
pub send_headers: ::std::option::Option<
unsafe extern "C" fn(sapi_headers: *mut sapi_headers_struct) -> ::std::os::raw::c_int,
>,
pub send_header: ::std::option::Option<
unsafe extern "C" fn(
sapi_header: *mut sapi_header_struct,
server_context: *mut ::std::os::raw::c_void,
),
>,
pub read_post: ::std::option::Option<
unsafe extern "C" fn(buffer: *mut ::std::os::raw::c_char, count_bytes: usize) -> usize,
>,
pub read_cookies: ::std::option::Option<unsafe extern "C" fn() -> *mut ::std::os::raw::c_char>,
pub register_server_variables:
::std::option::Option<unsafe extern "C" fn(track_vars_array: *mut zval)>,
pub log_message: ::std::option::Option<
unsafe extern "C" fn(
message: *const ::std::os::raw::c_char,
syslog_type_int: ::std::os::raw::c_int,
),
>,
pub get_request_time:
::std::option::Option<unsafe extern "C" fn(request_time: *mut f64) -> zend_result>,
pub terminate_process: ::std::option::Option<unsafe extern "C" fn()>,
pub php_ini_path_override: *mut ::std::os::raw::c_char,
pub default_post_reader: ::std::option::Option<unsafe extern "C" fn()>,
pub treat_data: ::std::option::Option<
unsafe extern "C" fn(
arg: ::std::os::raw::c_int,
str_: *mut ::std::os::raw::c_char,
destArray: *mut zval,
),
>,
pub executable_location: *mut ::std::os::raw::c_char,
pub php_ini_ignore: ::std::os::raw::c_int,
pub php_ini_ignore_cwd: ::std::os::raw::c_int,
pub get_fd: ::std::option::Option<
unsafe extern "C" fn(fd: *mut ::std::os::raw::c_int) -> ::std::os::raw::c_int,
>,
pub force_http_10: ::std::option::Option<unsafe extern "C" fn() -> ::std::os::raw::c_int>,
pub get_target_uid:
::std::option::Option<unsafe extern "C" fn(arg1: *mut uid_t) -> ::std::os::raw::c_int>,
pub get_target_gid:
::std::option::Option<unsafe extern "C" fn(arg1: *mut gid_t) -> ::std::os::raw::c_int>,
pub input_filter: ::std::option::Option<
unsafe extern "C" fn(
arg: ::std::os::raw::c_int,
var: *const ::std::os::raw::c_char,
val: *mut *mut ::std::os::raw::c_char,
val_len: usize,
new_val_len: *mut usize,
) -> ::std::os::raw::c_uint,
>,
pub ini_defaults:
::std::option::Option<unsafe extern "C" fn(configuration_hash: *mut HashTable)>,
pub phpinfo_as_text: ::std::os::raw::c_int,
pub ini_entries: *const ::std::os::raw::c_char,
pub additional_functions: *const zend_function_entry,
pub input_filter_init: ::std::option::Option<unsafe extern "C" fn() -> ::std::os::raw::c_uint>,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _sapi_post_entry {

View File

@ -27,6 +27,7 @@ extern "C" {
pub fn ext_php_rs_zend_object_release(obj: *mut zend_object);
pub fn ext_php_rs_executor_globals() -> *mut zend_executor_globals;
pub fn ext_php_rs_sapi_globals() -> *mut sapi_globals_struct;
pub fn ext_php_rs_sapi_module() -> *mut sapi_module_struct;
pub fn ext_php_rs_zend_try_catch(
func: unsafe extern "C" fn(*const c_void) -> *const c_void,
ctx: *const c_void,

View File

@ -52,6 +52,10 @@ sapi_globals_struct *ext_php_rs_sapi_globals() {
#endif
}
sapi_module_struct *ext_php_rs_sapi_module() {
return &sapi_module;
}
bool ext_php_rs_zend_try_catch(void* (*callback)(void *), void *ctx, void **result) {
zend_try {
*result = callback(ctx);

View File

@ -33,5 +33,6 @@ void *ext_php_rs_zend_object_alloc(size_t obj_size, zend_class_entry *ce);
void ext_php_rs_zend_object_release(zend_object *obj);
zend_executor_globals *ext_php_rs_executor_globals();;
sapi_globals_struct *ext_php_rs_sapi_globals();
sapi_module_struct *ext_php_rs_sapi_module();
bool ext_php_rs_zend_try_catch(void* (*callback)(void *), void *ctx, void **result);
void ext_php_rs_zend_bailout();

View File

@ -9,8 +9,8 @@ use crate::boxed::ZBox;
#[cfg(php82)]
use crate::ffi::zend_atomic_bool_store;
use crate::ffi::{
_sapi_globals_struct, _zend_executor_globals, ext_php_rs_executor_globals,
ext_php_rs_sapi_globals, zend_ini_entry,
_sapi_globals_struct, _sapi_module_struct, _zend_executor_globals, ext_php_rs_executor_globals,
ext_php_rs_sapi_globals, ext_php_rs_sapi_module, zend_ini_entry,
};
use crate::types::{ZendHashTable, ZendObject};
@ -20,6 +20,9 @@ pub type ExecutorGlobals = _zend_executor_globals;
/// Stores global SAPI variables used in the PHP executor.
pub type SapiGlobals = _sapi_globals_struct;
/// Stores the SAPI module used in the PHP executor.
pub type SapiModule = _sapi_module_struct;
impl ExecutorGlobals {
/// Returns a reference to the PHP executor globals.
///
@ -167,6 +170,40 @@ impl SapiGlobals {
}
}
impl SapiModule {
/// Returns a reference to the PHP SAPI module.
///
/// The executor globals are guarded by a RwLock. There can be multiple
/// immutable references at one time but only ever one mutable reference.
/// Attempting to retrieve the globals while already holding the global
/// guard will lead to a deadlock. Dropping the globals guard will release
/// the lock.
pub fn get() -> GlobalReadGuard<Self> {
// SAFETY: PHP executor globals are statically declared therefore should never
// return an invalid pointer.
let globals = unsafe { ext_php_rs_sapi_module().as_ref() }
.expect("Static executor globals were invalid");
let guard = SAPI_MODULE_LOCK.read();
GlobalReadGuard { globals, guard }
}
/// Returns a mutable reference to the PHP executor globals.
///
/// The executor globals are guarded by a RwLock. There can be multiple
/// immutable references at one time but only ever one mutable reference.
/// Attempting to retrieve the globals while already holding the global
/// guard will lead to a deadlock. Dropping the globals guard will release
/// the lock.
pub fn get_mut() -> GlobalWriteGuard<Self> {
// SAFETY: PHP executor globals are statically declared therefore should never
// return an invalid pointer.
let globals = unsafe { ext_php_rs_sapi_module().as_mut() }
.expect("Static executor globals were invalid");
let guard = SAPI_MODULE_LOCK.write();
GlobalWriteGuard { globals, guard }
}
}
/// Executor globals rwlock.
///
/// PHP provides no indication if the executor globals are being accessed so
@ -179,6 +216,12 @@ static GLOBALS_LOCK: RwLock<()> = const_rwlock(());
/// this is only effective on the Rust side.
static SAPI_LOCK: RwLock<()> = const_rwlock(());
/// SAPI globals rwlock.
///
/// PHP provides no indication if the executor globals are being accessed so
/// this is only effective on the Rust side.
static SAPI_MODULE_LOCK: RwLock<()> = const_rwlock(());
/// Wrapper guard that contains a reference to a given type `T`. Dropping a
/// guard releases the lock on the relevant rwlock.
pub struct GlobalReadGuard<T: 'static> {

View File

@ -21,6 +21,7 @@ pub use function::Function;
pub use function::FunctionEntry;
pub use globals::ExecutorGlobals;
pub use globals::SapiGlobals;
pub use globals::SapiModule;
pub use handlers::ZendObjectHandlers;
pub use ini_entry_def::IniEntryDef;
pub use module::ModuleEntry;