Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions allowed_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,13 @@ bind! {
zend_is_auto_global,
zend_llist_get_next_ex,
zend_llist_get_prev_ex,
php_register_url_stream_wrapper,
php_stream_locate_url_wrapper,
php_unregister_url_stream_wrapper,
php_unregister_url_stream_wrapper_volatile,
php_register_url_stream_wrapper_volatile,
php_stream_wrapper,
php_stream_stdio_ops,
zend_atomic_bool_store,
zend_interrupt_function
}
30 changes: 30 additions & 0 deletions docsrs_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1996,6 +1996,36 @@ impl _php_stream {
__bindgen_bitfield_unit
}
}
extern "C" {
pub static mut php_stream_stdio_ops: php_stream_ops;
}
extern "C" {
pub fn php_register_url_stream_wrapper(
protocol: *const ::std::os::raw::c_char,
wrapper: *const php_stream_wrapper,
) -> zend_result;
}
extern "C" {
pub fn php_unregister_url_stream_wrapper(
protocol: *const ::std::os::raw::c_char,
) -> zend_result;
}
extern "C" {
pub fn php_register_url_stream_wrapper_volatile(
protocol: *mut zend_string,
wrapper: *mut php_stream_wrapper,
) -> zend_result;
}
extern "C" {
pub fn php_unregister_url_stream_wrapper_volatile(protocol: *mut zend_string) -> zend_result;
}
extern "C" {
pub fn php_stream_locate_url_wrapper(
path: *const ::std::os::raw::c_char,
path_for_open: *mut *const ::std::os::raw::c_char,
options: ::std::os::raw::c_int,
) -> *mut php_stream_wrapper;
}
pub type php_core_globals = _php_core_globals;
#[repr(C)]
pub struct _php_core_globals {
Expand Down
2 changes: 1 addition & 1 deletion src/zend/ex.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::ffi::{zend_execute_data, ZEND_MM_ALIGNMENT, ZEND_MM_ALIGNMENT_MASK};
use crate::ffi::{_zend_function, zend_execute_data, ZEND_MM_ALIGNMENT, ZEND_MM_ALIGNMENT_MASK};

use crate::{
args::ArgParser,
Expand Down
2 changes: 2 additions & 0 deletions src/zend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod globals;
mod handlers;
mod linked_list;
mod module;
mod streams;

use crate::{error::Result, ffi::php_printf};
use std::ffi::CString;
Expand All @@ -24,6 +25,7 @@ pub use globals::SapiGlobals;
pub use handlers::ZendObjectHandlers;
pub use linked_list::ZendLinkedList;
pub use module::ModuleEntry;
pub use streams::*;

// Used as the format string for `php_printf`.
const FORMAT_STR: &[u8] = b"%s\0";
Expand Down
100 changes: 100 additions & 0 deletions src/zend/streams.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use std::ptr::{self, NonNull};

use crate::{
ffi::{
php_register_url_stream_wrapper, php_register_url_stream_wrapper_volatile, php_stream,
php_stream_context, php_stream_locate_url_wrapper, php_stream_wrapper,
php_stream_wrapper_ops, php_unregister_url_stream_wrapper,
php_unregister_url_stream_wrapper_volatile, zend_string,
},
types::ZendStr,
};

pub type StreamWrapper = php_stream_wrapper;

pub type StreamOpener = unsafe extern "C" fn(
*mut StreamWrapper,
*const std::ffi::c_char,
*const std::ffi::c_char,
i32,
*mut *mut zend_string,
*mut php_stream_context,
i32,
*const std::ffi::c_char,
u32,
*const std::ffi::c_char,
u32,
) -> *mut Stream;

impl StreamWrapper {
pub fn get(name: &str) -> Option<&Self> {
unsafe {
let result = php_stream_locate_url_wrapper(name.as_ptr().cast(), ptr::null_mut(), 0);
Some(NonNull::new(result)?.as_ref())
}
}

pub fn get_mut(name: &str) -> Option<&mut Self> {
unsafe {
let result = php_stream_locate_url_wrapper(name.as_ptr().cast(), ptr::null_mut(), 0);
Some(NonNull::new(result)?.as_mut())
}
}

pub fn register(self, name: &str) -> Result<Self, ()> {
// We have to convert it to a static so owned streamwrapper doesn't get dropped.
let copy = Box::new(self);
let copy = Box::leak(copy);
let name = std::ffi::CString::new(name).unwrap();
let result = unsafe { php_register_url_stream_wrapper(name.as_ptr(), copy) };
if result == 0 {
Ok(*copy)
} else {
Err(())
}
}

pub fn register_volatile(self, name: &str) -> Result<Self, ()> {
// We have to convert it to a static so owned streamwrapper doesn't get dropped.
let copy = Box::new(self);
let copy = Box::leak(copy);
let name = ZendStr::new(name, false);
let result =
unsafe { php_register_url_stream_wrapper_volatile((*name).as_ptr() as _, copy) };
if result == 0 {
Ok(*copy)
} else {
Err(())
}
}

pub fn unregister(name: &str) -> Result<(), ()> {
let name = std::ffi::CString::new(name).unwrap();
match unsafe { php_unregister_url_stream_wrapper(name.as_ptr()) } {
0 => Ok(()),
_ => Err(()),
}
}

pub fn unregister_volatile(name: &str) -> Result<(), ()> {
let name = ZendStr::new(name, false);
match unsafe { php_unregister_url_stream_wrapper_volatile((*name).as_ptr() as _) } {
0 => Ok(()),
_ => Err(()),
}
}

pub fn wops(&self) -> &php_stream_wrapper_ops {
unsafe { &*self.wops }
}

pub fn wops_mut(&mut self) -> &mut php_stream_wrapper_ops {
unsafe { &mut *(self.wops as *mut php_stream_wrapper_ops) }
}
}

pub type Stream = php_stream;

pub type StreamWrapperOps = php_stream_wrapper_ops;

impl StreamWrapperOps {}