Skip to content

Instantly share code, notes, and snippets.

@moriyoshi
Created November 9, 2010 11:26
Show Gist options
  • Save moriyoshi/668983 to your computer and use it in GitHub Desktop.
Save moriyoshi/668983 to your computer and use it in GitHub Desktop.
import sys
from ctypes import *
c_int_p = POINTER(c_int)
c_uint_p = POINTER(c_uint)
def typeof(structure, name):
for k, v in structure._fields_:
if k == name:
return v
raise KeyError(name)
class Stat(Structure):
pass
class StringValue(Structure):
_fields_ = [
('val', c_char_p),
('len', c_int),
]
class ObjectValue(Structure):
_fields_ = [
('handle', c_uint),
('handlers', c_void_p),
]
class HashTable(Structure):
pass
class ZValueValue(Union):
_fields_ = [
('lval', c_long),
('dval', c_double),
('str', StringValue),
('ht', POINTER(HashTable)),
('obj', ObjectValue)
]
class ZValStruct(Structure):
_fields_ = [
('value', ZValueValue),
('refcount', c_uint),
('type', c_uint8),
('is_ref', c_uint8),
]
class ZendLList(Structure):
_fields_ = [
('head', c_void_p),
('tail', c_void_p),
('count', c_size_t),
('size', c_size_t),
('dtor', POINTER(CFUNCTYPE(None, c_void_p))),
('persistent', c_uint8),
('traverse_ptr', c_void_p),
]
class SAPIHeaderStruct(Structure):
_fields_ = [
('header', c_char_p),
('header_len', c_uint),
]
class SAPIHeadersStruct(Structure):
_fields_ = [
('headers', ZendLList),
('http_response_code', c_int),
('send_default_content_type', c_uint8),
('mimetype', c_char_p),
('http_status_line', c_char_p),
]
class SAPIModuleStruct(Structure):
pass
class ArgInfo(Structure):
_fields_ = [
('name', c_char_p),
('name_len', c_uint),
('class_name', c_char_p),
('class_name_len', c_uint),
('type_hint', c_uint8),
('allow_null', c_int),
('pass_by_reference', c_int),
]
class ZendFunctionEntry(Structure):
_fields_ = [
('fname', c_char_p),
('handler', CFUNCTYPE(None, c_int, POINTER(ZValStruct), POINTER(POINTER(ZValStruct)), POINTER(ZValStruct), c_int, c_void_p)),
('arg_info', POINTER(ArgInfo)),
('num_args', c_uint),
('flags', c_uint),
]
class PHPRuntimeError(Exception):
pass
SAPIModuleStruct._fields_ = [
('name', c_char_p),
('pretty_name', c_char_p),
('startup', CFUNCTYPE(c_int, POINTER(SAPIModuleStruct))),
('shutdown', CFUNCTYPE(c_int, POINTER(SAPIModuleStruct))),
('activate', CFUNCTYPE(c_int, c_void_p)),
('deactivate', CFUNCTYPE(c_int, c_void_p)),
('ub_write', CFUNCTYPE(c_int, POINTER(c_char), c_uint, c_void_p)),
('flush', CFUNCTYPE(None, c_void_p)),
('get_stat', CFUNCTYPE(c_void_p, c_void_p)),
('getenv', CFUNCTYPE(c_char_p, c_char_p, c_size_t, c_void_p)),
('sapi_error', CFUNCTYPE(None, c_int, c_char_p)),
('header_handler', CFUNCTYPE(c_int, POINTER(SAPIHeaderStruct), c_int, POINTER(SAPIHeadersStruct), c_void_p)),
('send_headers', CFUNCTYPE(c_int, POINTER(SAPIHeadersStruct), c_void_p)),
('send_header', CFUNCTYPE(None, POINTER(SAPIHeaderStruct), c_void_p, c_void_p)),
('read_post', CFUNCTYPE(c_int, c_char_p, c_uint, c_void_p)),
('read_cookies', CFUNCTYPE(c_char_p, c_void_p)),
('register_server_variables', CFUNCTYPE(None, POINTER(ZValStruct), c_void_p)),
('log_message', CFUNCTYPE(None, c_char_p, c_void_p)),
('get_request_time', CFUNCTYPE(c_uint, c_void_p)),
('terminate_process', CFUNCTYPE(None, c_void_p)),
('php_ini_path_override', c_char_p),
('block_interruptions', CFUNCTYPE(None)),
('unblock_interruptions', CFUNCTYPE(None)),
('default_post_reader', CFUNCTYPE(None, c_void_p)),
('treat_data', CFUNCTYPE(None, c_int, c_char_p, POINTER(ZValStruct), c_void_p)),
('executable_location', c_char_p),
('php_ini_ignore', c_int),
('get_fd', CFUNCTYPE(c_int, c_int_p, c_void_p)),
('force_http_10', CFUNCTYPE(c_int, c_void_p)),
('get_target_uid', CFUNCTYPE(c_int, c_int_p, c_void_p)),
('get_target_gid', CFUNCTYPE(c_int, c_int_p, c_void_p)),
('input_filter', CFUNCTYPE(c_uint, c_int, c_char_p, POINTER(c_char_p), c_uint, c_uint, c_void_p)),
('ini_defaults', CFUNCTYPE(None, POINTER(HashTable))),
('phpinfo_as_text', c_int),
('ini_entries', c_char_p),
('additional_functions', POINTER(ZendFunctionEntry)),
('input_filter_init', CFUNCTYPE(c_uint, c_void_p)),
]
php_module = CDLL('php5ts.dll')
def python_sapi_startup(module):
if php_module.php_module_startup(module, c_void_p(0), 0):
return -1
return 0
def python_sapi_shutdown(module):
pass
def python_sapi_ub_write(buf, buf_len, tsrm_ls):
sys.stdout.write(buf[0:buf_len])
return buf_len
def python_sapi_flush(context):
pass
def python_sapi_send_headers(*arg, **kwarg):
return 1 # SAPI_HEADER_SENT_SUCCESSFULLY
python_sapi_module = SAPIModuleStruct(
name='python',
pretty_name='Python SAPI module',
startup=typeof(SAPIModuleStruct, 'startup')(python_sapi_startup),
shutdown=typeof(SAPIModuleStruct, 'shutdown')(python_sapi_shutdown),
activate=typeof(SAPIModuleStruct, 'activate')(0),
deactivate=typeof(SAPIModuleStruct, 'deactivate')(0),
ub_write=typeof(SAPIModuleStruct, 'ub_write')(python_sapi_ub_write),
flush=typeof(SAPIModuleStruct, 'flush')(python_sapi_flush),
get_stat=typeof(SAPIModuleStruct, 'get_stat')(0),
getenv=typeof(SAPIModuleStruct, 'getenv')(0),
sapi_error=typeof(SAPIModuleStruct, 'sapi_error')(php_module.zend_error),
header_handler=typeof(SAPIModuleStruct, 'header_handler')(0),
send_headers=typeof(SAPIModuleStruct, 'send_headers')(python_sapi_send_headers),
send_header=typeof(SAPIModuleStruct, 'send_header')(0),
read_post=typeof(SAPIModuleStruct, 'read_post')(0),
read_cookies=typeof(SAPIModuleStruct, 'read_cookies')(0),
register_server_variables=typeof(SAPIModuleStruct, 'register_server_variables')(0),
log_message=typeof(SAPIModuleStruct, 'log_message')(0),
get_request_time=typeof(SAPIModuleStruct, 'get_request_time')(0),
terminate_process=typeof(SAPIModuleStruct, 'terminate_process')(0),
php_ini_path_override=c_char_p(0),
block_interruptions=typeof(SAPIModuleStruct, 'block_interruptions')(0),
unblock_interruptions=typeof(SAPIModuleStruct, 'unblock_interruptions')(0),
default_post_reader=typeof(SAPIModuleStruct, 'default_post_reader')(0),
treat_data=typeof(SAPIModuleStruct, 'treat_data')(0),
php_ini_ignore=0,
get_fd=typeof(SAPIModuleStruct, 'get_fd')(0),
force_http_10=typeof(SAPIModuleStruct, 'force_http_10')(0),
input_filter=typeof(SAPIModuleStruct, 'input_filter')(0),
ini_defaults=typeof(SAPIModuleStruct, 'ini_defaults')(0),
phpinfo_as_text=1,
ini_entries=c_char_p(0),
additional_functions=(ZendFunctionEntry*1)(ZendFunctionEntry(name=c_char_p(0))),
input_filter_init=typeof(SAPIModuleStruct, 'input_filter_init')(0),
)
php_module.tsrm_startup(c_int(1), c_int(1), c_int(0), c_char_p(0))
tsrm_ls = php_module.ts_resource_ex(0, None)
try:
php_module.sapi_startup(byref(python_sapi_module))
if python_sapi_module.startup(byref(python_sapi_module)):
raise PHPRuntimeError("Failed to initialize PHP runtime")
try:
if php_module.php_request_startup(tsrm_ls):
raise PHPRuntimeError("Failed to initialize PHP runtime")
if php_module.zend_eval_string_ex(c_char_p('echo "Hello world!";'), c_void_p(None), c_char_p("eval"), 1, tsrm_ls):
raise PHPRuntimeError("Failed to execute PHP script")
finally:
php_module.php_request_shutdown(c_void_p(None))
php_module.php_module_shutdown(tsrm_ls)
finally:
php_module.sapi_shutdown()
php_module.tsrm_shutdown()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment