mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-12 11:40:50 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f3b0e4721 |
No files matched your search
@@ -1,669 +0,0 @@
|
||||
define set_ts
|
||||
set $tsrm_ls = $arg0
|
||||
end
|
||||
|
||||
document set_ts
|
||||
set the ts resource, it is impossible for gdb to
|
||||
call ts_resource_ex while no process is running,
|
||||
but we could get the resource from the argument
|
||||
of frame info.
|
||||
end
|
||||
|
||||
define ____executor_globals
|
||||
if basic_functions_module.zts
|
||||
if !$tsrm_ls
|
||||
set $tsrm_ls = ts_resource_ex(0, 0)
|
||||
end
|
||||
set $eg = ((zend_executor_globals*) (*((void ***) $tsrm_ls))[executor_globals_id-1])
|
||||
set $cg = ((zend_compiler_globals*) (*((void ***) $tsrm_ls))[compiler_globals_id-1])
|
||||
else
|
||||
set $eg = executor_globals
|
||||
set $cg = compiler_globals
|
||||
end
|
||||
end
|
||||
|
||||
document ____executor_globals
|
||||
portable way of accessing executor_globals, set $eg
|
||||
this also sets compiler_globals to $cg
|
||||
ZTS detection is automatically based on ext/standard module struct
|
||||
end
|
||||
|
||||
define print_cvs
|
||||
____executor_globals
|
||||
set $p = $eg.current_execute_data.CVs
|
||||
set $c = $eg.current_execute_data.op_array.last_var
|
||||
set $v = $eg.current_execute_data.op_array.vars
|
||||
set $i = 0
|
||||
|
||||
printf "Compiled variables count: %d\n", $c
|
||||
while $i < $c
|
||||
printf "%d = %s\n", $i, $v[$i].name
|
||||
if $p[$i] != 0
|
||||
printzv *$p[$i]
|
||||
else
|
||||
printf "*uninitialized*\n"
|
||||
end
|
||||
set $i = $i + 1
|
||||
end
|
||||
end
|
||||
|
||||
define dump_bt
|
||||
set $t = $arg0
|
||||
while $t
|
||||
printf "[%p] ", $t
|
||||
set $fst = $t->function_state
|
||||
if $fst.function->common.function_name
|
||||
if $fst.arguments
|
||||
set $count = (int)*($fst.arguments)
|
||||
|
||||
if $t->object
|
||||
if $fst.function.common.scope
|
||||
printf "%s->", $fst.function.common.scope->name
|
||||
else
|
||||
if !$eg
|
||||
____executor_globals
|
||||
end
|
||||
|
||||
set $known_class = 0
|
||||
if $eg
|
||||
set $handle = $t->object.value.obj.handle
|
||||
set $handlers = $t->object.value.obj.handlers
|
||||
set $zobj = (zend_object *)$eg.objects_store.object_buckets[$handle].bucket.obj.object
|
||||
|
||||
if $handlers->get_class_entry == &zend_std_object_get_class
|
||||
set $known_class = 1
|
||||
|
||||
if $handlers.get_class_name
|
||||
if $handlers.get_class_name != &zend_std_object_get_class_name
|
||||
set $known_class = 0
|
||||
end
|
||||
end
|
||||
|
||||
if $known_class
|
||||
printf "%s->", $zobj->ce.name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if !$known_class
|
||||
printf "(Unknown)->"
|
||||
end
|
||||
end
|
||||
else
|
||||
if $fst.function.common.scope
|
||||
printf "%s::", $fst.function.common.scope->name
|
||||
end
|
||||
end
|
||||
|
||||
printf "%s(", $fst.function->common.function_name
|
||||
while $count > 0
|
||||
set $zvalue = *(zval **)($fst.arguments - $count)
|
||||
set $type = $zvalue->type
|
||||
if $type == 0
|
||||
printf "NULL"
|
||||
end
|
||||
if $type == 1
|
||||
printf "%ld", $zvalue->value.lval
|
||||
end
|
||||
if $type == 2
|
||||
printf "%lf", $zvalue->value.dval
|
||||
end
|
||||
if $type == 3
|
||||
if $zvalue->value.lval
|
||||
printf "true"
|
||||
else
|
||||
printf "false"
|
||||
end
|
||||
end
|
||||
if $type == 4
|
||||
printf "array(%d)[%p]", $zvalue->value.ht->nNumOfElements, $zvalue
|
||||
end
|
||||
if $type == 5
|
||||
printf "object[%p]", $zvalue
|
||||
end
|
||||
if $type == 6
|
||||
____print_str $zvalue->value.str.val $zvalue->value.str.len
|
||||
end
|
||||
if $type == 7
|
||||
printf "resource(#%d)", $zvalue->value.lval
|
||||
end
|
||||
if $type == 8
|
||||
printf "constant"
|
||||
end
|
||||
if $type == 9
|
||||
printf "const_array"
|
||||
end
|
||||
if $type > 9
|
||||
printf "unknown type %d", $type
|
||||
end
|
||||
set $count = $count -1
|
||||
if $count > 0
|
||||
printf ", "
|
||||
end
|
||||
end
|
||||
printf ") "
|
||||
else
|
||||
printf "%s() ", $fst.function->common.function_name
|
||||
end
|
||||
else
|
||||
printf "??? "
|
||||
end
|
||||
if $t->op_array != 0
|
||||
printf "%s:%d ", $t->op_array->filename, $t->opline->lineno
|
||||
end
|
||||
set $t = $t->prev_execute_data
|
||||
printf "\n"
|
||||
end
|
||||
end
|
||||
|
||||
document dump_bt
|
||||
dumps the current execution stack. usage: dump_bt executor_globals.current_execute_data
|
||||
end
|
||||
|
||||
define printzv
|
||||
set $ind = 1
|
||||
____printzv $arg0 0
|
||||
end
|
||||
|
||||
document printzv
|
||||
prints zval contents
|
||||
end
|
||||
|
||||
define ____printzv_contents
|
||||
set $zvalue = $arg0
|
||||
set $type = $zvalue->type
|
||||
|
||||
printf "(refcount=%d", $zvalue->refcount__gc
|
||||
if $zvalue->is_ref__gc
|
||||
printf ",is_ref"
|
||||
end
|
||||
printf ") "
|
||||
if $type == 0
|
||||
printf "NULL"
|
||||
end
|
||||
if $type == 1
|
||||
printf "long: %ld", $zvalue->value.lval
|
||||
end
|
||||
if $type == 2
|
||||
printf "double: %lf", $zvalue->value.dval
|
||||
end
|
||||
if $type == 3
|
||||
printf "bool: "
|
||||
if $zvalue->value.lval
|
||||
printf "true"
|
||||
else
|
||||
printf "false"
|
||||
end
|
||||
end
|
||||
if $type == 4
|
||||
printf "array(%d): ", $zvalue->value.ht->nNumOfElements
|
||||
if ! $arg1
|
||||
printf "{\n"
|
||||
set $ind = $ind + 1
|
||||
____print_ht $zvalue->value.ht 1
|
||||
set $ind = $ind - 1
|
||||
set $i = $ind
|
||||
while $i > 0
|
||||
printf " "
|
||||
set $i = $i - 1
|
||||
end
|
||||
printf "}"
|
||||
end
|
||||
set $type = 0
|
||||
end
|
||||
if $type == 5
|
||||
printf "object"
|
||||
____executor_globals
|
||||
set $handle = $zvalue->value.obj.handle
|
||||
set $handlers = $zvalue->value.obj.handlers
|
||||
if basic_functions_module.zts
|
||||
set $zobj = zend_objects_get_address($zvalue, $tsrm_ls)
|
||||
else
|
||||
set $zobj = zend_objects_get_address($zvalue)
|
||||
end
|
||||
if $handlers->get_class_entry == &zend_std_object_get_class
|
||||
set $cname = $zobj->ce.name
|
||||
else
|
||||
set $cname = "Unknown"
|
||||
end
|
||||
printf "(%s) #%d", $cname, $handle
|
||||
if ! $arg1
|
||||
if $handlers->get_properties == &zend_std_get_properties
|
||||
set $ht = $zobj->properties
|
||||
if $ht
|
||||
printf "(%d): ", $ht->nNumOfElements
|
||||
printf "{\n"
|
||||
set $ind = $ind + 1
|
||||
____print_ht $ht 1
|
||||
set $ind = $ind - 1
|
||||
set $i = $ind
|
||||
while $i > 0
|
||||
printf " "
|
||||
set $i = $i - 1
|
||||
end
|
||||
printf "}"
|
||||
else
|
||||
echo "no properties found"
|
||||
end
|
||||
end
|
||||
end
|
||||
set $type = 0
|
||||
end
|
||||
if $type == 6
|
||||
printf "string(%d): ", $zvalue->value.str.len
|
||||
____print_str $zvalue->value.str.val $zvalue->value.str.len
|
||||
end
|
||||
if $type == 7
|
||||
printf "resource: #%d", $zvalue->value.lval
|
||||
end
|
||||
if $type == 8
|
||||
printf "constant"
|
||||
end
|
||||
if $type == 9
|
||||
printf "const_array"
|
||||
end
|
||||
if $type > 9
|
||||
printf "unknown type %d", $type
|
||||
end
|
||||
printf "\n"
|
||||
end
|
||||
|
||||
define ____printzv
|
||||
____executor_globals
|
||||
set $zvalue = $arg0
|
||||
|
||||
printf "[%p] ", $zvalue
|
||||
|
||||
if $zvalue == $eg.uninitialized_zval_ptr
|
||||
printf "*uninitialized* "
|
||||
end
|
||||
|
||||
set $zcontents = (zval*) $zvalue
|
||||
if $arg1
|
||||
____printzv_contents $zcontents $arg1
|
||||
else
|
||||
____printzv_contents $zcontents 0
|
||||
end
|
||||
end
|
||||
|
||||
define ____print_const_table
|
||||
set $ht = $arg0
|
||||
set $p = $ht->pListHead
|
||||
|
||||
while $p != 0
|
||||
set $const = (zend_constant *) $p->pData
|
||||
|
||||
set $i = $ind
|
||||
while $i > 0
|
||||
printf " "
|
||||
set $i = $i - 1
|
||||
end
|
||||
|
||||
if $p->nKeyLength > 0
|
||||
____print_str $p->arKey $p->nKeyLength
|
||||
printf " => "
|
||||
else
|
||||
printf "%d => ", $p->h
|
||||
end
|
||||
|
||||
____printzv_contents &$const->value 0
|
||||
set $p = $p->pListNext
|
||||
end
|
||||
end
|
||||
|
||||
define print_const_table
|
||||
set $ind = 1
|
||||
printf "[%p] {\n", $arg0
|
||||
____print_const_table $arg0
|
||||
printf "}\n"
|
||||
end
|
||||
|
||||
define ____print_ht
|
||||
set $ht = (HashTable*)$arg0
|
||||
set $p = $ht->pListHead
|
||||
|
||||
while $p != 0
|
||||
set $i = $ind
|
||||
while $i > 0
|
||||
printf " "
|
||||
set $i = $i - 1
|
||||
end
|
||||
|
||||
if $p->nKeyLength > 0
|
||||
____print_str $p->arKey $p->nKeyLength
|
||||
printf " => "
|
||||
else
|
||||
printf "%d => ", $p->h
|
||||
end
|
||||
|
||||
if $arg1 == 0
|
||||
printf "%p\n", (void*)$p->pData
|
||||
end
|
||||
if $arg1 == 1
|
||||
set $zval = *(zval **)$p->pData
|
||||
____printzv $zval 1
|
||||
end
|
||||
if $arg1 == 2
|
||||
printf "%s\n", (char*)$p->pData
|
||||
end
|
||||
|
||||
set $p = $p->pListNext
|
||||
end
|
||||
end
|
||||
|
||||
define print_ht
|
||||
set $ind = 1
|
||||
printf "[%p] {\n", $arg0
|
||||
____print_ht $arg0 1
|
||||
printf "}\n"
|
||||
end
|
||||
|
||||
document print_ht
|
||||
dumps elements of HashTable made of zval
|
||||
end
|
||||
|
||||
define print_htptr
|
||||
set $ind = 1
|
||||
printf "[%p] {\n", $arg0
|
||||
____print_ht $arg0 0
|
||||
printf "}\n"
|
||||
end
|
||||
|
||||
document print_htptr
|
||||
dumps elements of HashTable made of pointers
|
||||
end
|
||||
|
||||
define print_htstr
|
||||
set $ind = 1
|
||||
printf "[%p] {\n", $arg0
|
||||
____print_ht $arg0 2
|
||||
printf "}\n"
|
||||
end
|
||||
|
||||
document print_htstr
|
||||
dumps elements of HashTable made of strings
|
||||
end
|
||||
|
||||
define ____print_ft
|
||||
set $ht = $arg0
|
||||
set $p = $ht->pListHead
|
||||
|
||||
while $p != 0
|
||||
set $func = (zend_function*)$p->pData
|
||||
|
||||
set $i = $ind
|
||||
while $i > 0
|
||||
printf " "
|
||||
set $i = $i - 1
|
||||
end
|
||||
|
||||
if $p->nKeyLength > 0
|
||||
____print_str $p->arKey $p->nKeyLength
|
||||
printf " => "
|
||||
else
|
||||
printf "%d => ", $p->h
|
||||
end
|
||||
|
||||
printf "\"%s\"\n", $func->common.function_name
|
||||
set $p = $p->pListNext
|
||||
end
|
||||
end
|
||||
|
||||
define print_ft
|
||||
set $ind = 1
|
||||
printf "[%p] {\n", $arg0
|
||||
____print_ft $arg0
|
||||
printf "}\n"
|
||||
end
|
||||
|
||||
document print_ft
|
||||
dumps a function table (HashTable)
|
||||
end
|
||||
|
||||
define ____print_inh_class
|
||||
set $ce = $arg0
|
||||
if $ce->ce_flags & 0x10 || $ce->ce_flags & 0x20
|
||||
printf "abstract "
|
||||
else
|
||||
if $ce->ce_flags & 0x40
|
||||
printf "final "
|
||||
end
|
||||
end
|
||||
printf "class %s", $ce->name
|
||||
if $ce->parent != 0
|
||||
printf " extends %s", $ce->parent->name
|
||||
end
|
||||
if $ce->num_interfaces != 0
|
||||
printf " implements"
|
||||
set $tmp = 0
|
||||
while $tmp < $ce->num_interfaces
|
||||
printf " %s", $ce->interfaces[$tmp]->name
|
||||
set $tmp = $tmp + 1
|
||||
if $tmp < $ce->num_interfaces
|
||||
printf ","
|
||||
end
|
||||
end
|
||||
end
|
||||
set $ce = $ce->parent
|
||||
end
|
||||
|
||||
define ____print_inh_iface
|
||||
set $ce = $arg0
|
||||
printf "interface %s", $ce->name
|
||||
if $ce->num_interfaces != 0
|
||||
set $ce = $ce->interfaces[0]
|
||||
printf " extends %s", $ce->name
|
||||
else
|
||||
set $ce = 0
|
||||
end
|
||||
end
|
||||
|
||||
define print_inh
|
||||
set $ce = $arg0
|
||||
set $depth = 0
|
||||
while $ce != 0
|
||||
set $tmp = $depth
|
||||
while $tmp != 0
|
||||
printf " "
|
||||
set $tmp = $tmp - 1
|
||||
end
|
||||
set $depth = $depth + 1
|
||||
if $ce->ce_flags & 0x80
|
||||
____print_inh_iface $ce
|
||||
else
|
||||
____print_inh_class $ce
|
||||
end
|
||||
printf " {\n"
|
||||
end
|
||||
while $depth != 0
|
||||
set $tmp = $depth
|
||||
while $tmp != 1
|
||||
printf " "
|
||||
set $tmp = $tmp - 1
|
||||
end
|
||||
printf "}\n"
|
||||
set $depth = $depth - 1
|
||||
end
|
||||
end
|
||||
|
||||
define print_pi
|
||||
set $pi = $arg0
|
||||
printf "[%p] {\n", $pi
|
||||
printf " h = %lu\n", $pi->h
|
||||
printf " flags = %d (", $pi->flags
|
||||
if $pi->flags & 0x100
|
||||
printf "ZEND_ACC_PUBLIC"
|
||||
else
|
||||
if $pi->flags & 0x200
|
||||
printf "ZEND_ACC_PROTECTED"
|
||||
else
|
||||
if $pi->flags & 0x400
|
||||
printf "ZEND_ACC_PRIVATE"
|
||||
else
|
||||
if $pi->flags & 0x800
|
||||
printf "ZEND_ACC_CHANGED"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
printf ")\n"
|
||||
printf " name = "
|
||||
____print_str $pi->name $pi->name_length
|
||||
printf "\n}\n"
|
||||
end
|
||||
|
||||
define ____print_str
|
||||
set $tmp = 0
|
||||
set $str = $arg0
|
||||
printf "\""
|
||||
while $tmp < $arg1
|
||||
if $str[$tmp] > 32 && $str[$tmp] < 127
|
||||
printf "%c", $str[$tmp]
|
||||
else
|
||||
printf "\\%o", $str[$tmp]
|
||||
end
|
||||
set $tmp = $tmp + 1
|
||||
end
|
||||
printf "\""
|
||||
end
|
||||
|
||||
define printzn
|
||||
____executor_globals
|
||||
set $ind = 0
|
||||
set $znode = $arg0
|
||||
if $znode->op_type == 1
|
||||
set $optype = "IS_CONST"
|
||||
end
|
||||
if $znode->op_type == 2
|
||||
set $optype = "IS_TMP_VAR"
|
||||
end
|
||||
if $znode->op_type == 4
|
||||
set $optype = "IS_VAR"
|
||||
end
|
||||
if $znode->op_type == 8
|
||||
set $optype = "IS_UNUSED"
|
||||
end
|
||||
|
||||
printf "[%p] %s", $znode, $optype
|
||||
|
||||
if $znode->op_type == 1
|
||||
printf ": "
|
||||
____printzv &$znode->u.constant 0
|
||||
end
|
||||
if $znode->op_type == 2
|
||||
printf ": "
|
||||
set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var)
|
||||
____printzv ((union _temp_variable *)$tvar)->tmp_var 0
|
||||
end
|
||||
if $znode->op_type == 4
|
||||
printf ": "
|
||||
set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var)
|
||||
____printzv *$tvar->var.ptr_ptr 0
|
||||
end
|
||||
if $znode->op_type == 8
|
||||
printf "\n"
|
||||
end
|
||||
end
|
||||
|
||||
document printzn
|
||||
print type and content of znode.
|
||||
usage: printzn &opline->op1
|
||||
end
|
||||
|
||||
define printzops
|
||||
printf "op1 => "
|
||||
printzn &execute_data->opline.op1
|
||||
printf "op2 => "
|
||||
printzn &execute_data->opline.op2
|
||||
printf "result => "
|
||||
printzn &execute_data->opline.result
|
||||
end
|
||||
|
||||
document printzops
|
||||
dump operands of the current opline
|
||||
end
|
||||
|
||||
define zbacktrace
|
||||
____executor_globals
|
||||
dump_bt $eg.current_execute_data
|
||||
end
|
||||
|
||||
document zbacktrace
|
||||
prints backtrace.
|
||||
This command is almost a short cut for
|
||||
> (gdb) ____executor_globals
|
||||
> (gdb) dump_bt $eg.current_execute_data
|
||||
end
|
||||
|
||||
define zmemcheck
|
||||
set $p = alloc_globals.head
|
||||
set $stat = "?"
|
||||
set $total_size = 0
|
||||
if $arg0 != 0
|
||||
set $not_found = 1
|
||||
else
|
||||
set $not_found = 0
|
||||
end
|
||||
printf " block size status file:line\n"
|
||||
printf "-------------------------------------------------------------------------------\n"
|
||||
while $p
|
||||
set $aptr = $p + sizeof(struct _zend_mem_header) + sizeof(align_test)
|
||||
if $arg0 == 0 || (void *)$aptr == (void *)$arg0
|
||||
if $p->magic == 0x7312f8dc
|
||||
set $stat = "OK"
|
||||
end
|
||||
if $p->magic == 0x99954317
|
||||
set $stat = "FREED"
|
||||
end
|
||||
if $p->magic == 0xfb8277dc
|
||||
set $stat = "CACHED"
|
||||
end
|
||||
set $filename = strrchr($p->filename, '/')
|
||||
if !$filename
|
||||
set $filename = $p->filename
|
||||
else
|
||||
set $filename = $filename + 1
|
||||
end
|
||||
printf " %p ", $aptr
|
||||
if $p->size == sizeof(struct _zval_struct) && ((struct _zval_struct *)$aptr)->type >= 0 && ((struct _zval_struct *)$aptr)->type < 10
|
||||
printf "ZVAL?(%-2d) ", $p->size
|
||||
else
|
||||
printf "%-9d ", $p->size
|
||||
end
|
||||
set $total_size = $total_size + $p->size
|
||||
printf "%-06s %s:%d", $stat, $filename, $p->lineno
|
||||
if $p->orig_filename
|
||||
set $orig_filename = strrchr($p->orig_filename, '/')
|
||||
if !$orig_filename
|
||||
set $orig_filename = $p->orig_filename
|
||||
else
|
||||
set $orig_filename = $orig_filename + 1
|
||||
end
|
||||
printf " <= %s:%d\n", $orig_filename, $p->orig_lineno
|
||||
else
|
||||
printf "\n"
|
||||
end
|
||||
if $arg0 != 0
|
||||
set $p = 0
|
||||
set $not_found = 0
|
||||
else
|
||||
set $p = $p->pNext
|
||||
end
|
||||
else
|
||||
set $p = $p->pNext
|
||||
end
|
||||
end
|
||||
if $not_found
|
||||
printf "no such block that begins at %p.\n", $aptr
|
||||
end
|
||||
if $arg0 == 0
|
||||
printf "-------------------------------------------------------------------------------\n"
|
||||
printf " total: %d bytes\n", $total_size
|
||||
end
|
||||
end
|
||||
|
||||
document zmemcheck
|
||||
show status of a memory block.
|
||||
usage: zmemcheck [ptr].
|
||||
if ptr is 0, all blocks will be listed.
|
||||
end
|
||||
-175
@@ -1,175 +0,0 @@
|
||||
ext/mysqlnd/mysqlnd.h ident
|
||||
ext/simplexml/simplexml.c ident
|
||||
ext/iconv/php_iconv.h ident
|
||||
ext/posix/posix.c ident
|
||||
ext/recode/recode.c ident
|
||||
ext/skeleton/create_stubs ident
|
||||
ext/phar/phar/pharcommand.inc ident
|
||||
ext/phar/phar.c ident
|
||||
ext/sysvmsg/sysvmsg.c ident
|
||||
ext/enchant/enchant.c ident
|
||||
ext/reflection/php_reflection.c ident
|
||||
ext/oci8/oci8.c ident
|
||||
ext/dba/libinifile/inifile.c ident
|
||||
ext/dba/libflatfile/flatfile.c ident
|
||||
ext/dba/libcdb/cdb_make.c ident
|
||||
ext/dba/libcdb/cdb.c ident
|
||||
ext/filter/filter.c ident
|
||||
ext/zip/php_zip.c ident
|
||||
README.input_filter ident
|
||||
run-tests.php ident
|
||||
sapi/nsapi/nsapi.c ident
|
||||
sapi/continuity/capi.c ident
|
||||
Zend/RFCs/002.txt ident
|
||||
Zend/RFCs/003.txt ident
|
||||
NEWS merge=NEWS
|
||||
/ext/bz2/tests/with_strings.phpt -crlf
|
||||
/ext/dom/tests/bug40836.phpt -crlf
|
||||
/ext/dom/tests/domelement.phpt -crlf
|
||||
/ext/ereg/tests/eregi_basic_002.phpt -crlf
|
||||
/ext/iconv/tests/iconv004.phpt -crlf
|
||||
/ext/iconv/tests/iconv_basic.phpt -crlf
|
||||
/ext/iconv/tests/iconv_strpos.phpt -crlf
|
||||
/ext/iconv/tests/iconv_strpos_variation2.phpt -crlf
|
||||
/ext/mbstring/tests/mb_strtoupper_error2.phpt -crlf
|
||||
/ext/phar/tests/delete_in_phar_confirm.phpt -crlf
|
||||
/ext/phar/tests/frontcontroller12.phpt -crlf
|
||||
/ext/phar/tests/security.phpt -crlf
|
||||
/ext/phar/tests/test_signaturealgos.phpt -crlf
|
||||
/ext/reflection/tests/ReflectionMethod_invokeArgs_basic.phpt -crlf
|
||||
/ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt -crlf
|
||||
/ext/spl/tests/dllist_007.phpt -crlf
|
||||
/ext/spl/tests/iterator_012.phpt -crlf
|
||||
/ext/spl/tests/SplArray_fromArray.phpt -crlf
|
||||
/ext/standard/tests/dir/scandir_variation3.phpt -crlf
|
||||
/ext/standard/tests/general_functions/escapeshellcmd-win32.phpt -crlf
|
||||
/ext/standard/tests/general_functions/set_magic_quotes_runtime_error.phpt -crlf
|
||||
/ext/standard/tests/strings/bug26817.phpt -crlf
|
||||
/ext/standard/tests/strings/bug26973.phpt -crlf
|
||||
/ext/standard/tests/strings/bug27457.phpt -crlf
|
||||
/ext/standard/tests/strings/bug28386.phpt -crlf
|
||||
/ext/standard/tests/strings/bug37262.phpt -crlf
|
||||
/ext/standard/tests/strings/bug40637.phpt -crlf
|
||||
/ext/standard/tests/strings/bug40915.phpt -crlf
|
||||
/ext/standard/tests/strings/bug61374.phpt -crlf
|
||||
/ext/standard/tests/strings/chop_error.phpt -crlf
|
||||
/ext/standard/tests/strings/chop_variation2.phpt -crlf
|
||||
/ext/standard/tests/strings/chunk_split_variation10.phpt -crlf
|
||||
/ext/standard/tests/strings/chunk_split_variation8.phpt -crlf
|
||||
/ext/standard/tests/strings/count_chars_variation2.phpt -crlf
|
||||
/ext/standard/tests/strings/dirname_error.phpt -crlf
|
||||
/ext/standard/tests/strings/fprintf_variation_007_64bit.phpt -crlf
|
||||
/ext/standard/tests/strings/highlight_file.phpt -crlf
|
||||
/ext/standard/tests/strings/htmlentities03.phpt -crlf
|
||||
/ext/standard/tests/strings/htmlentities04.phpt -crlf
|
||||
/ext/standard/tests/strings/htmlentities08.phpt -crlf
|
||||
/ext/standard/tests/strings/htmlentities15.phpt -crlf
|
||||
/ext/standard/tests/strings/http_build_query.phpt -crlf
|
||||
/ext/standard/tests/strings/metaphone.phpt -crlf
|
||||
/ext/standard/tests/strings/ord_error.phpt -crlf
|
||||
/ext/standard/tests/strings/printf_basic2.phpt -crlf
|
||||
/ext/standard/tests/strings/printf_variation2.phpt -crlf
|
||||
/ext/standard/tests/strings/quoted_printable_decode_basic.phpt -crlf
|
||||
/ext/standard/tests/strings/rtrim.phpt -crlf
|
||||
/ext/standard/tests/strings/setlocale_variation1.phpt -crlf
|
||||
/ext/standard/tests/strings/sha1_basic.phpt -crlf
|
||||
/ext/standard/tests/strings/similar_text_basic.phpt -crlf
|
||||
/ext/standard/tests/strings/soundex.phpt -crlf
|
||||
/ext/standard/tests/strings/sprintf_basic1.phpt -crlf
|
||||
/ext/standard/tests/strings/sprintf_basic4.phpt -crlf
|
||||
/ext/standard/tests/strings/sprintf_basic7.phpt -crlf
|
||||
/ext/standard/tests/strings/sprintf_variation12.phpt -crlf
|
||||
/ext/standard/tests/strings/sprintf_variation28.phpt -crlf
|
||||
/ext/standard/tests/strings/sprintf_variation29.phpt -crlf
|
||||
/ext/standard/tests/strings/sprintf_variation30.phpt -crlf
|
||||
/ext/standard/tests/strings/sprintf_variation31.phpt -crlf
|
||||
/ext/standard/tests/strings/sprintf_variation38.phpt -crlf
|
||||
/ext/standard/tests/strings/sprintf_variation42.phpt -crlf
|
||||
/ext/standard/tests/strings/sprintf_variation6.phpt -crlf
|
||||
/ext/standard/tests/strings/sscanf_basic2.phpt -crlf
|
||||
/ext/standard/tests/strings/sscanf_basic3.phpt -crlf
|
||||
/ext/standard/tests/strings/str_getcsv_001.phpt -crlf
|
||||
/ext/standard/tests/strings/stripcslashes_basic.phpt -crlf
|
||||
/ext/standard/tests/strings/stripos_variation11.phpt -crlf
|
||||
/ext/standard/tests/strings/stripos_variation13.phpt -crlf
|
||||
/ext/standard/tests/strings/stripslashes_variation1.phpt -crlf
|
||||
/ext/standard/tests/strings/stripslashes_variation2.phpt -crlf
|
||||
/ext/standard/tests/strings/stristr_error.phpt -crlf
|
||||
/ext/standard/tests/strings/strnatcasecmp_basic.phpt -crlf
|
||||
/ext/standard/tests/strings/strncasecmp_variation6.phpt -crlf
|
||||
/ext/standard/tests/strings/strncasecmp_variation7.phpt -crlf
|
||||
/ext/standard/tests/strings/strncasecmp_variation8.phpt -crlf
|
||||
/ext/standard/tests/strings/strrchr_error.phpt -crlf
|
||||
/ext/standard/tests/strings/strrchr.phpt -crlf
|
||||
/ext/standard/tests/strings/strrchr_variation11.phpt -crlf
|
||||
/ext/standard/tests/strings/strrpos_error.phpt -crlf
|
||||
/ext/standard/tests/strings/strrpos_variation4.phpt -crlf
|
||||
/ext/standard/tests/strings/strrpos_variation8.phpt -crlf
|
||||
/ext/standard/tests/strings/strstr2.phpt -crlf
|
||||
/ext/standard/tests/strings/strtok_error.phpt -crlf
|
||||
/ext/standard/tests/strings/strtok_variation2.phpt -crlf
|
||||
/ext/standard/tests/strings/strtolower-win32.phpt -crlf
|
||||
/ext/standard/tests/strings/substr_compare.phpt -crlf
|
||||
/ext/standard/tests/strings/ucwords_variation1.phpt -crlf
|
||||
/ext/standard/tests/strings/unpack.phpt -crlf
|
||||
/ext/standard/tests/strings/vfprintf_basic7_64bit.phpt -crlf
|
||||
/ext/standard/tests/strings/vfprintf_variation11_64bit.phpt -crlf
|
||||
/ext/standard/tests/strings/vfprintf_variation12_64bit.phpt -crlf
|
||||
/ext/standard/tests/strings/vfprintf_variation12.phpt -crlf
|
||||
/ext/standard/tests/strings/vfprintf_variation13_64bit.phpt -crlf
|
||||
/ext/standard/tests/strings/vfprintf_variation7.phpt -crlf
|
||||
/ext/standard/tests/strings/vprintf_basic2.phpt -crlf
|
||||
/ext/standard/tests/strings/vprintf_basic7_64bit.phpt -crlf
|
||||
/ext/standard/tests/strings/vprintf_variation10.phpt -crlf
|
||||
/ext/standard/tests/strings/vprintf_variation14_64bit.phpt -crlf
|
||||
/ext/standard/tests/strings/vprintf_variation17.phpt -crlf
|
||||
/ext/standard/tests/strings/vprintf_variation4.phpt -crlf
|
||||
/ext/standard/tests/strings/vsprintf_basic4.phpt -crlf
|
||||
/ext/standard/tests/strings/vsprintf_basic8.phpt -crlf
|
||||
/ext/standard/tests/strings/vsprintf_variation12_64bit.phpt -crlf
|
||||
/ext/standard/tests/strings/vsprintf_variation13_64bit.phpt -crlf
|
||||
/ext/standard/tests/strings/vsprintf_variation15_64bit.phpt -crlf
|
||||
/ext/standard/tests/strings/vsprintf_variation17.phpt -crlf
|
||||
/ext/standard/tests/strings/vsprintf_variation4_64bit.phpt -crlf
|
||||
/ext/standard/tests/strings/vsprintf_variation7.phpt -crlf
|
||||
/ext/standard/tests/strings/wordwrap.phpt -crlf
|
||||
/ext/standard/tests/strings/wordwrap_variation5.phpt -crlf
|
||||
/ext/standard/tests/url/rawurldecode_variation_001.phpt -crlf
|
||||
/ext/tidy/tests/009.phpt -crlf
|
||||
/ext/tidy/tests/013.phpt -crlf
|
||||
/ext/tidy/tests/021.phpt -crlf
|
||||
/ext/tidy/tests/tidy_error.phpt -crlf
|
||||
/ext/tokenizer/tests/002.phpt -crlf
|
||||
/ext/tokenizer/tests/bug26463.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_error.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_variation11.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_variation12.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_variation13.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_variation14.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_variation15.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_variation18.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_variation19.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_variation1.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_variation2.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_variation3.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_variation5.phpt -crlf
|
||||
/ext/tokenizer/tests/token_get_all_variation8.phpt -crlf
|
||||
/ext/xml/tests/bug32001b.phpt -crlf
|
||||
/ext/xmlwriter/tests/OO_003.phpt -crlf
|
||||
/ext/xmlwriter/tests/xmlwriter_write_attribute_ns_error_001.phpt -crlf
|
||||
/ext/zlib/tests/008.phpt -crlf
|
||||
/ext/zlib/tests/gzopen_variation4.phpt -crlf
|
||||
/ext/zlib/tests/gzrewind_error.phpt -crlf
|
||||
/ext/zlib/tests/readgzfile_variation7.phpt -crlf
|
||||
/ext/zlib/tests/readgzfile_variation8.phpt -crlf
|
||||
/ext/zlib/tests/zlib_scheme_stat_basic.phpt -crlf
|
||||
/sapi/cli/tests/006.phpt -crlf
|
||||
/tests/run-test/test009.phpt -crlf
|
||||
/Zend/tests/012.phpt -crlf
|
||||
/Zend/tests/bug28072.phpt -crlf
|
||||
/Zend/tests/bug38624.phpt -crlf
|
||||
/Zend/tests/bug40784.phpt -crlf
|
||||
/Zend/tests/bug43053.phpt -crlf
|
||||
/Zend/tests/bug51176.phpt -crlf
|
||||
/Zend/tests/each_003.phpt -crlf
|
||||
/Zend/tests/errmsg_006.phpt -crlf
|
||||
-254
@@ -1,254 +0,0 @@
|
||||
# General Ignores
|
||||
*~
|
||||
.#*
|
||||
*.
|
||||
*.slo
|
||||
*.mk
|
||||
*.mem
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
*.a
|
||||
*.ncb
|
||||
*.opt
|
||||
*.plg
|
||||
*swp
|
||||
*.patch
|
||||
*.tgz
|
||||
*.tar.gz
|
||||
*.tar.bz2
|
||||
.FBCIndex
|
||||
.FBCLockFolder
|
||||
.deps
|
||||
.libs
|
||||
phpt.*
|
||||
core
|
||||
dynlib.m4
|
||||
Debug
|
||||
Debug_TS
|
||||
Makefile
|
||||
Makefile.fragments
|
||||
Makefile.objects
|
||||
Release
|
||||
Release_TS
|
||||
Release_TSDbg
|
||||
Release_TS_inline
|
||||
Release_inline
|
||||
ZendEngine1
|
||||
_libs
|
||||
acconfig.h
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
bsd_converted
|
||||
buildconf.stamp
|
||||
buildmk.stamp
|
||||
confdefs.h
|
||||
config.h
|
||||
config.guess
|
||||
config.cache
|
||||
config.h.in
|
||||
config.log
|
||||
config.nice
|
||||
config.nice.bat
|
||||
config.status
|
||||
config.sub
|
||||
config_vars.mk
|
||||
configuration-parser.c
|
||||
configuration-parser.h
|
||||
configuration-parser.output
|
||||
configuration-scanner.c
|
||||
configure
|
||||
configure.bat
|
||||
configure.js
|
||||
conftest
|
||||
conftest.c
|
||||
debug.log
|
||||
diff
|
||||
generated_lists
|
||||
include
|
||||
install-sh
|
||||
internal_functions.c
|
||||
lcov_data
|
||||
lcov_html
|
||||
libs
|
||||
libtool
|
||||
meta_cc
|
||||
meta_ccld
|
||||
missing
|
||||
mkinstalldirs
|
||||
modules
|
||||
php
|
||||
php-*.tar.gz
|
||||
php5.spec
|
||||
php_lcov.info
|
||||
php_test_results_*.txt
|
||||
php_version.h
|
||||
results.txt
|
||||
shlibtool
|
||||
stamp-h
|
||||
test.php3
|
||||
tmp-php.ini
|
||||
want_dependencies
|
||||
x64
|
||||
stamp-h.in
|
||||
scan_makefile_in.awk
|
||||
TSRM/tsrm_config.h
|
||||
Zend/zend_config.h
|
||||
Zend/zend_ini_parser.c
|
||||
Zend/zend_ini_parser.h
|
||||
Zend/zend_ini_parser.output
|
||||
Zend/zend_language_parser.c
|
||||
Zend/zend_language_parser.h
|
||||
Zend/zend_language_parser.output
|
||||
ext/date/lib/timelib_config.h
|
||||
ext/iconv/php_iconv_aliased_libiconv.h
|
||||
ext/phar/phar.php
|
||||
main/php_config.h
|
||||
main/php_config.h.in
|
||||
|
||||
# Test specific Ignores
|
||||
tests/*/*.diff
|
||||
tests/*/*.out
|
||||
tests/*/*.php
|
||||
tests/*/*.exp
|
||||
tests/*/*.log
|
||||
tests/*/*.sh
|
||||
*/tests/*.diff
|
||||
*/tests/*.out
|
||||
*/tests/*.php
|
||||
*/tests/*.exp
|
||||
*/tests/*.log
|
||||
*/tests/*.sh
|
||||
*/tests/*/*.diff
|
||||
*/tests/*/*.out
|
||||
*/tests/*/*.php
|
||||
*/tests/*/*.exp
|
||||
*/tests/*/*.log
|
||||
*/tests/*/*.sh
|
||||
*/*/tests/*.diff
|
||||
*/*/tests/*.out
|
||||
*/*/tests/*.php
|
||||
*/*/tests/*.exp
|
||||
*/*/tests/*.log
|
||||
*/*/tests/*.sh
|
||||
*/*/tests/*/*.diff
|
||||
*/*/tests/*/*.out
|
||||
*/*/tests/*/*.php
|
||||
*/*/tests/*/*.exp
|
||||
*/*/tests/*/*.log
|
||||
*/*/tests/*/*.sh
|
||||
|
||||
# Extension specifc ignores
|
||||
ext/*/configure.in
|
||||
ext/*/ltmain.sh
|
||||
ext/*/libs.mk
|
||||
ext/*/build
|
||||
ext/*/scan_makefile_in.awk
|
||||
ext/*/Makefile.global
|
||||
ext/*/acinclude.m4
|
||||
ext/*/config.sub
|
||||
|
||||
# Extension specific
|
||||
ext/iconv/scan_makefile_in.awk
|
||||
ext/iconv/php_have_bsd_iconv.h
|
||||
ext/iconv/php_have_ibm_iconv.h
|
||||
ext/iconv/php_have_libiconv.h
|
||||
ext/iconv/php_php_iconv_h_path.h
|
||||
ext/iconv/php_have_glibc_iconv.h
|
||||
ext/iconv/php_php_iconv_impl.h
|
||||
ext/iconv/php_have_iconv.h
|
||||
ext/iconv/php_iconv_supports_errno.h
|
||||
ext/mbstring/libmbfl/Makefile.in
|
||||
ext/mbstring/libmbfl/autoscan.log
|
||||
ext/mbstring/libmbfl/config.sub
|
||||
ext/mbstring/libmbfl/depcomp
|
||||
ext/mbstring/libmbfl/ltmain.sh
|
||||
ext/mbstring/libmbfl/stamp-h1
|
||||
ext/mbstring/libmbfl/*.dll
|
||||
ext/mbstring/libmbfl/*.lib
|
||||
ext/mbstring/libmbfl/*.RES
|
||||
ext/mbstring/libmbfl/*.res
|
||||
ext/mbstring/libmbfl/*.obj
|
||||
ext/mbstring/libmbfl/*.tds
|
||||
ext/mbstring/libmbfl/filters/Makefile.in
|
||||
ext/mbstring/libmbfl/mbfl/Makefile.in
|
||||
ext/mbstring/libmbfl/mbfl/EastAsianWidth.txt
|
||||
ext/mbstring/libmbfl/nls/Makefile.in
|
||||
ext/mssql/#*#
|
||||
ext/mssql/Makefile.global
|
||||
ext/mssql/acinclude.m4
|
||||
ext/mssql/config.sub
|
||||
ext/mssql/configure.in
|
||||
ext/mssql/ltmain.sh
|
||||
ext/mysql/weztest.sqlite
|
||||
ext/oci8/tests/*.tmp
|
||||
ext/oci8/tests/*.vglog
|
||||
ext/pdo/conftest*
|
||||
ext/pdo/tests/*.db
|
||||
ext/pdo/tests/*.tmp
|
||||
ext/pdo_firebird/conftest*
|
||||
ext/pdo_mysql/conftest*
|
||||
ext/pdo_mysql/tests/*.db
|
||||
ext/pdo_mysql/tests/*.tmp
|
||||
ext/pdo_oci/conftest*
|
||||
ext/pdo_odbc/tests/*.db
|
||||
ext/pdo_odbc/tests/*.tmp
|
||||
ext/pdo_odbc/tests/*.mdb
|
||||
ext/pdo_pgsql/conftest*
|
||||
ext/pdo_pgsql/tests/*.db
|
||||
ext/pdo_pgsql/tests/*.tmp
|
||||
ext/pdo_sqlite/conftest*
|
||||
ext/pdo_sqlite/sqlite3.h
|
||||
ext/pdo_sqlite/tests/*.db
|
||||
ext/pdo_sqlite/tests/*.tmp
|
||||
ext/phar/phar.phar
|
||||
ext/pspell/tests/*.tmp
|
||||
ext/reflection/xml
|
||||
ext/reflection/html
|
||||
ext/reflection/spl.chm
|
||||
ext/simplexml/examples/security.new.xml
|
||||
ext/spl/examples/.htaccess
|
||||
ext/spl/examples/*.phps
|
||||
ext/sqlite/weztest.sqlite
|
||||
ext/sqlite/libsqlite/src/sqlite.h
|
||||
ext/sqlite/libsqlite/src/parse.out
|
||||
ext/sqlite/libsqlite/src/libsqlite.dsw
|
||||
ext/sqlite3/tests/phpsql*
|
||||
ext/sqlite3/tests/*.db
|
||||
ext/sqlite3/tests/*.tmp
|
||||
ext/standard/tests/misc/*.txt
|
||||
ext/standard/tests/strings/*.txt
|
||||
main/build-defs.h
|
||||
main/internal_functions_cli.c
|
||||
main/config.w32.h
|
||||
main/stamp-h1
|
||||
main/streams/build-defs.h
|
||||
main/streams/stamp-h1
|
||||
pear/install-pear-nozlib.phar
|
||||
pear/phpize
|
||||
pear/run-tests
|
||||
pear/php-config
|
||||
pear/scripts
|
||||
sapi/apache/libphp5.module
|
||||
sapi/apache2handler/libphp5.module
|
||||
sapi/apache_hooks/libphp5.module
|
||||
sapi/cgi/php-cgi
|
||||
sapi/cli/php.1
|
||||
sapi/fpm/php-fpm
|
||||
sapi/fpm/php-fpm.1
|
||||
sapi/fpm/init.d.php-fpm
|
||||
sapi/fpm/php-fpm.conf
|
||||
sapi/fpm/fpm/php-cgi
|
||||
scripts/php-config
|
||||
scripts/phpize
|
||||
scripts/man1/*.1
|
||||
win32/*.suo
|
||||
win32/*.aps
|
||||
win32/*.positions
|
||||
win32/ext
|
||||
win32/phpts.def
|
||||
win32/wsyslog.h
|
||||
win32/win32.dsp
|
||||
win32/php.dsw
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
# We only specify one version so we only get one worker
|
||||
- 5.4
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
script: exit 0
|
||||
@@ -1,277 +0,0 @@
|
||||
========================
|
||||
PHP Coding Standards
|
||||
========================
|
||||
|
||||
This file lists several standards that any programmer adding or changing
|
||||
code in PHP should follow. Since this file was added at a very late
|
||||
stage of the development of PHP v3.0, the code base does not (yet) fully
|
||||
follow it, but it's going in that general direction. Since we are now
|
||||
well into version 5 releases, many sections have been recoded to use
|
||||
these rules.
|
||||
|
||||
Code Implementation
|
||||
-------------------
|
||||
|
||||
0. Document your code in source files and the manual. [tm]
|
||||
|
||||
1. Functions that are given pointers to resources should not free them
|
||||
|
||||
For instance, ``function int mail(char *to, char *from)`` should NOT free
|
||||
to and/or from.
|
||||
Exceptions:
|
||||
|
||||
- The function's designated behavior is freeing that resource. E.g. efree()
|
||||
|
||||
- The function is given a boolean argument, that controls whether or not
|
||||
the function may free its arguments (if true - the function must free its
|
||||
arguments, if false - it must not)
|
||||
|
||||
- Low-level parser routines, that are tightly integrated with the token
|
||||
cache and the bison code for minimum memory copying overhead.
|
||||
|
||||
2. Functions that are tightly integrated with other functions within the
|
||||
same module, and rely on each other non-trivial behavior, should be
|
||||
documented as such and declared 'static'. They should be avoided if
|
||||
possible.
|
||||
|
||||
3. Use definitions and macros whenever possible, so that constants have
|
||||
meaningful names and can be easily manipulated. The only exceptions
|
||||
to this rule are 0 and 1, when used as false and true (respectively).
|
||||
Any other use of a numeric constant to specify different behavior
|
||||
or actions should be done through a #define.
|
||||
|
||||
4. When writing functions that deal with strings, be sure to remember
|
||||
that PHP holds the length property of each string, and that it
|
||||
shouldn't be calculated with strlen(). Write your functions in a such
|
||||
a way so that they'll take advantage of the length property, both
|
||||
for efficiency and in order for them to be binary-safe.
|
||||
Functions that change strings and obtain their new lengths while
|
||||
doing so, should return that new length, so it doesn't have to be
|
||||
recalculated with strlen() (e.g. php_addslashes())
|
||||
|
||||
5. NEVER USE strncat(). If you're absolutely sure you know what you're doing,
|
||||
check its man page again, and only then, consider using it, and even then,
|
||||
try avoiding it.
|
||||
|
||||
6. Use ``PHP_*`` macros in the PHP source, and ``ZEND_*`` macros in the Zend
|
||||
part of the source. Although the ``PHP_*`` macro's are mostly aliased to the
|
||||
``ZEND_*`` macros it gives a better understanding on what kind of macro
|
||||
you're calling.
|
||||
|
||||
7. When commenting out code using a #if statement, do NOT use 0 only. Instead
|
||||
use "<svn username here>_0". For example, #if FOO_0, where FOO is your
|
||||
svn user foo. This allows easier tracking of why code was commented out,
|
||||
especially in bundled libraries.
|
||||
|
||||
8. Do not define functions that are not available. For instance, if a
|
||||
library is missing a function, do not define the PHP version of the
|
||||
function, and do not raise a run-time error about the function not
|
||||
existing. End users should use function_exists() to test for the
|
||||
existence of a function
|
||||
|
||||
9. Prefer emalloc(), efree(), estrdup(), etc. to their standard C library
|
||||
counterparts. These functions implement an internal "safety-net"
|
||||
mechanism that ensures the deallocation of any unfreed memory at the
|
||||
end of a request. They also provide useful allocation and overflow
|
||||
information while running in debug mode.
|
||||
|
||||
In almost all cases, memory returned to the engine must be allocated
|
||||
using emalloc().
|
||||
|
||||
The use of malloc() should be limited to cases where a third-party
|
||||
library may need to control or free the memory, or when the memory in
|
||||
question needs to survive between multiple requests.
|
||||
|
||||
Naming Conventions
|
||||
------------------
|
||||
|
||||
1. Function names for user-level functions should be enclosed with in
|
||||
the PHP_FUNCTION() macro. They should be in lowercase, with words
|
||||
underscore delimited, with care taken to minimize the letter count.
|
||||
Abbreviations should not be used when they greatly decrease the
|
||||
readability of the function name itself::
|
||||
|
||||
Good:
|
||||
'mcrypt_enc_self_test'
|
||||
'mysql_list_fields'
|
||||
|
||||
Ok:
|
||||
'mcrypt_module_get_algo_supported_key_sizes'
|
||||
(could be 'mcrypt_mod_get_algo_sup_key_sizes'?)
|
||||
'get_html_translation_table'
|
||||
(could be 'html_get_trans_table'?)
|
||||
|
||||
Bad:
|
||||
'hw_GetObjectByQueryCollObj'
|
||||
'pg_setclientencoding'
|
||||
'jf_n_s_i'
|
||||
|
||||
2. If they are part of a "parent set" of functions, that parent should
|
||||
be included in the user function name, and should be clearly related
|
||||
to the parent program or function family. This should be in the form
|
||||
of ``parent_*``::
|
||||
|
||||
A family of 'foo' functions, for example:
|
||||
Good:
|
||||
'foo_select_bar'
|
||||
'foo_insert_baz'
|
||||
'foo_delete_baz'
|
||||
|
||||
Bad:
|
||||
'fooselect_bar'
|
||||
'fooinsertbaz'
|
||||
'delete_foo_baz'
|
||||
|
||||
3. Function names used by user functions should be prefixed
|
||||
with ``_php_``, and followed by a word or an underscore-delimited list of
|
||||
words, in lowercase letters, that describes the function. If applicable,
|
||||
they should be declared 'static'.
|
||||
|
||||
4. Variable names must be meaningful. One letter variable names must be
|
||||
avoided, except for places where the variable has no real meaning or
|
||||
a trivial meaning (e.g. for (i=0; i<100; i++) ...).
|
||||
|
||||
5. Variable names should be in lowercase. Use underscores to separate
|
||||
between words.
|
||||
|
||||
6. Method names follow the 'studlyCaps' (also referred to as 'bumpy case'
|
||||
or 'camel caps') naming convention, with care taken to minimize the
|
||||
letter count. The initial letter of the name is lowercase, and each
|
||||
letter that starts a new 'word' is capitalized::
|
||||
|
||||
Good:
|
||||
'connect()'
|
||||
'getData()'
|
||||
'buildSomeWidget()'
|
||||
|
||||
Bad:
|
||||
'get_Data()'
|
||||
'buildsomewidget'
|
||||
'getI()'
|
||||
|
||||
7. Classes should be given descriptive names. Avoid using abbreviations where
|
||||
possible. Each word in the class name should start with a capital letter,
|
||||
without underscore delimiters (CampelCaps starting with a capital letter).
|
||||
The class name should be prefixed with the name of the 'parent set' (e.g.
|
||||
the name of the extension)::
|
||||
|
||||
Good:
|
||||
'Curl'
|
||||
'FooBar'
|
||||
|
||||
Bad:
|
||||
'foobar'
|
||||
'foo_bar'
|
||||
|
||||
Syntax and indentation
|
||||
----------------------
|
||||
|
||||
1. Never use C++ style comments (i.e. // comment). Always use C-style
|
||||
comments instead. PHP is written in C, and is aimed at compiling
|
||||
under any ANSI-C compliant compiler. Even though many compilers
|
||||
accept C++-style comments in C code, you have to ensure that your
|
||||
code would compile with other compilers as well.
|
||||
The only exception to this rule is code that is Win32-specific,
|
||||
because the Win32 port is MS-Visual C++ specific, and this compiler
|
||||
is known to accept C++-style comments in C code.
|
||||
|
||||
2. Use K&R-style. Of course, we can't and don't want to
|
||||
force anybody to use a style he or she is not used to, but,
|
||||
at the very least, when you write code that goes into the core
|
||||
of PHP or one of its standard modules, please maintain the K&R
|
||||
style. This applies to just about everything, starting with
|
||||
indentation and comment styles and up to function declaration
|
||||
syntax. Also see Indentstyle_.
|
||||
|
||||
.. _Indentstyle: http://www.catb.org/~esr/jargon/html/I/indent-style.html
|
||||
|
||||
3. Be generous with whitespace and braces. Keep one empty line between the
|
||||
variable declaration section and the statements in a block, as well as
|
||||
between logical statement groups in a block. Maintain at least one empty
|
||||
line between two functions, preferably two. Always prefer::
|
||||
|
||||
if (foo) {
|
||||
bar;
|
||||
}
|
||||
|
||||
to:
|
||||
|
||||
if(foo)bar;
|
||||
|
||||
4. When indenting, use the tab character. A tab is expected to represent
|
||||
four spaces. It is important to maintain consistency in indenture so
|
||||
that definitions, comments, and control structures line up correctly.
|
||||
|
||||
5. Preprocessor statements (#if and such) MUST start at column one. To
|
||||
indent preprocessor directives you should put the # at the beginning
|
||||
of a line, followed by any number of whitespace.
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
1. Extensions should be well tested using *.phpt tests. Read about that
|
||||
in README.TESTING.
|
||||
|
||||
Documentation and Folding Hooks
|
||||
-------------------------------
|
||||
|
||||
In order to make sure that the online documentation stays in line with
|
||||
the code, each user-level function should have its user-level function
|
||||
prototype before it along with a brief one-line description of what the
|
||||
function does. It would look like this::
|
||||
|
||||
/* {{{ proto int abs(int number)
|
||||
Returns the absolute value of the number */
|
||||
PHP_FUNCTION(abs)
|
||||
{
|
||||
...
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
The {{{ symbols are the default folding symbols for the folding mode in
|
||||
Emacs and vim (set fdm=marker). Folding is very useful when dealing with
|
||||
large files because you can scroll through the file quickly and just unfold
|
||||
the function you wish to work on. The }}} at the end of each function marks
|
||||
the end of the fold, and should be on a separate line.
|
||||
|
||||
The "proto" keyword there is just a helper for the doc/genfuncsummary script
|
||||
which generates a full function summary. Having this keyword in front of the
|
||||
function prototypes allows us to put folds elsewhere in the code without
|
||||
messing up the function summary.
|
||||
|
||||
Optional arguments are written like this::
|
||||
|
||||
/* {{{ proto object imap_header(int stream_id, int msg_no [, int from_length [, int subject_length [, string default_host]]])
|
||||
Returns a header object with the defined parameters */
|
||||
|
||||
And yes, please keep the prototype on a single line, even if that line
|
||||
is massive.
|
||||
|
||||
New and Experimental Functions
|
||||
-----------------------------------
|
||||
To reduce the problems normally associated with the first public
|
||||
implementation of a new set of functions, it has been suggested
|
||||
that the first implementation include a file labeled 'EXPERIMENTAL'
|
||||
in the function directory, and that the functions follow the
|
||||
standard prefixing conventions during their initial implementation.
|
||||
|
||||
The file labelled 'EXPERIMENTAL' should include the following
|
||||
information::
|
||||
|
||||
Any authoring information (known bugs, future directions of the module).
|
||||
Ongoing status notes which may not be appropriate for SVN comments.
|
||||
|
||||
Aliases & Legacy Documentation
|
||||
-----------------------------------
|
||||
You may also have some deprecated aliases with close to duplicate
|
||||
names, for example, somedb_select_result and somedb_selectresult. For
|
||||
documentation purposes, these will only be documented by the most
|
||||
current name, with the aliases listed in the documentation for
|
||||
the parent function. For ease of reference, user-functions with
|
||||
completely different names, that alias to the same function (such as
|
||||
highlight_file and show_source), will be separately documented. The
|
||||
proto should still be included, describing which function is aliased.
|
||||
|
||||
Backwards compatible functions and names should be maintained as long
|
||||
as the code can be reasonably be kept as part of the codebase. See
|
||||
/phpdoc/README for more information on documentation.
|
||||
@@ -1,2 +0,0 @@
|
||||
For the list of people who've put work into PHP, please see
|
||||
http://www.php.net/credits.php
|
||||
-547
@@ -1,547 +0,0 @@
|
||||
List of PHP maintainers
|
||||
=======================
|
||||
|
||||
Maintenance legend
|
||||
------------------
|
||||
Supported: Someone is actually paid to look after this.
|
||||
Maintained: Someone actually looks after it.
|
||||
Odd Fixes: It has a maintainer but they don't have time to do
|
||||
much other than throw the odd patch in. See below.
|
||||
Orphan: No current maintainer [but maybe you could take the
|
||||
role as you write your new code].
|
||||
Obsolete: Old code. Something tagged obsolete generally means
|
||||
it has been replaced by a better system and you
|
||||
should be using that.
|
||||
Unknown: Not known at this time.
|
||||
|
||||
Status legend
|
||||
-------------
|
||||
Working: Working under both Windows and Unix.
|
||||
Windows: Working only under Windows.
|
||||
Unix: Working only under Unix.
|
||||
Experimental: Under development or initial release.
|
||||
Not Working: Not working.
|
||||
Unknown: Status unknown.
|
||||
|
||||
|
||||
== Server APIs ==
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: aolserver
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache
|
||||
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache_hooks
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache2filter
|
||||
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache2handler
|
||||
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>, Ilia Alshanetsky <iliaa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: caudium
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: cgi
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: cli
|
||||
MAINTENANCE: Marcus Boerger <helly@php.net>, Edin Kadribasic <edink@php.net>
|
||||
STATUS: Working
|
||||
SINCE: 4.3.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: continuity
|
||||
PRIMARY MAINTAINER: Alex Leigh <aleigh@php.net>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: embed
|
||||
PRIMARY MAINTAINER: Edin Kadribasic <edink@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: fpm
|
||||
PRIMARY MAINTAINER: Antony Dovgal <tony2001@php.net>, Jerome Loyet <fat@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.3.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: isapi
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: litespeed
|
||||
PRIMARY MAINTAINER: George Wang <gwang@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: milter
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: nsapi
|
||||
PRIMARY MAINTAINER: Uwe Schindler <thetaphi@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: phttpd
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pi3web
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: roxen
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: thttpd
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: tux
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: webjames
|
||||
PRIMARY MAINTAINER: Alex Waugh <alex@alexwaugh.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
== Database extensions ==
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dba
|
||||
PRIMARY MAINTAINER: Marcus Börger <helly@php.net>,Christopher Jones <sixd@php.net>, Pierre-Alain Joye <pajoye@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: DBM abstraction for db2, db3, db4, dbm, ndbm, gdbm, ini
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: interbase
|
||||
PRIMARY MAINTAINER: Ard Biesheuvel <ard@ard.nu>, Jouni Ahto <jouni.ahto@exdec.fi>
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mssql
|
||||
PRIMARY MAINTAINER: Frank M. Kromann <fmk@swwwing.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Tested on phpts and isapi versions
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mysql
|
||||
PRIMARY MAINTAINER: Zak Greant <zak@mysql.com>, Georg Richter <georg@php.net>, Johannes Schlüter <johannes@php.net>, Ulf Wendel <uw@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mysqli
|
||||
PRIMARY MAINTAINER: Georg Richter <georg@php.net>, Andrey Hristov <andrey@php.net>, Johannes Schlüter <johannes@php.net>, Ulf Wendel <uw@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mysqlnd
|
||||
PRIMARY MAINTAINER: Georg Richter <georg@php.net>, Andrey Hristov <andrey@php.net>, Johannes Schlüter <johannes@php.net>, Ulf Wendel <uw@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: oci8
|
||||
PRIMARY MAINTAINER: Christopher Jones <sixd@php.net>, Antony Dovgal <tony2001@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: odbc
|
||||
PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdo
|
||||
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>, Wez Furlong <wez@php.net>
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdo_dblib
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdo_firebird
|
||||
PRIMARY MAINTAINER: Lars Westermann <lwe@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdo_mysql
|
||||
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>, Johannes Schlüter <johannes@php.net>, Andrey Hristov <andrey@php.net>, Ulf Wendel <uw@php.net>
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdo_odbc
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdo_oci
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdo_pgsql
|
||||
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdo_sqlite
|
||||
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pgsql
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>, Yasuo Ohgaki <yohgaki@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Use PostgreSQL 7.0.x or later. PostgreSQL 6.5.3 or less have fatal bug.
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sqlite
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>, Wez Furlong <wez@php.net>, Ilia Alshanetsky <iliaa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0 (Since 4.3.2 in PECL)
|
||||
COMMENT: Integrates SQLite 2 embeddable SQL database engine.
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sqlite3
|
||||
PRIMARY MAINTAINER: Scott MacVicar <scottmac@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.3
|
||||
COMMENT: Integrates SQLite 3 embeddable SQL database engine.
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sybase_ct
|
||||
PRIMARY MAINTAINER: Timm Friebe <thekid@thekid.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
== XML extensions ==
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dom
|
||||
PRIMARY MAINTAINER: Christian Stocker <chregu@php.net>, Rob Richards <rrichards@php.net>, Marcus Boerger <helly@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: simplexml
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: soap
|
||||
PRIMARY MAINTAINER: Dmitry Stogov <dmitry@zend.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: wddx
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
|
||||
MAINTENANCE: Orphaned
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: xml
|
||||
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net>, Rob Richards <rrichards@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: libxml
|
||||
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net>, Christian Stocker <chregu@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: xmlreader
|
||||
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net>, Christian Stocker <chregu@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: xmlrpc
|
||||
PRIMARY MAINTAINER: Dan Libby
|
||||
MAINTENANCE: Orphaned
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: xmlwriter
|
||||
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net>, Pierre-Alain Joye <pajoye@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: xsl
|
||||
PRIMARY MAINTAINER: Christian Stocker <chregu@php.net>, Rob Richards <rrichards@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
== Other extensions ==
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: bcmath
|
||||
MAINTENANCE: Andi Gutmans <andi@zend.com>
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: bz2
|
||||
PRIMARY MAINTAINER: Hartmut Holzgraefe <hholzgra@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
SINCE: 4.0.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: calendar
|
||||
PRIMARY MAINTAINER: Hartmut Holzgraefe <hholzgra@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: com_dotnet
|
||||
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Windows
|
||||
SINCE: 5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ctype
|
||||
PRIMARY MAINTAINER: Hartmut Holzgraefe <hholzgra@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: curl
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>, Ilia Alshanetsky <iliaa@php.net>, Pierrick Charron <pierrick@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: date
|
||||
PRIMARY MAINTAINER: Derick Rethans <derick@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: exif
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: fileinfo
|
||||
PRIMARY MAINTAINER: Derick Rethans <derick@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: filter
|
||||
PRIMARY MAINTAINER: Derick Rethans <derick@php.net>, Pierre-Alain Joye <pajoye@php.net>, Ilia Alshanetsky <iliaa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ftp
|
||||
PRIMARY MAINTAINER: Stefan Esser <sesser@php.net>
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: gd
|
||||
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: gettext
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: gmp
|
||||
PRIMARY MAINTAINER: Stanislav Malyshev <stas@php.net>, Antony Dovgal <tony2001@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.4
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: iconv
|
||||
PRIMARY MAINTAINER: Moriyoshi Koizumi <moriyoshi@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: intl
|
||||
PRIMARY MAINTAINER: Stanislav Malyshev <stas@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: imap
|
||||
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org>, Ilia Alshanetsky <iliaa@php.net>, Pierre-Alain Joye <pajoye@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: json
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
SINCE: 5.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ldap
|
||||
PRIMARY MAINTAINER: Stig Venaas <venaas@php.net>, Douglas Goldstein <cardoe@php.net>, Pierre-Alain Joye <pajoye@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mbstring
|
||||
PRIMARY MAINTAINER: Rui Hirokawa <hirokawa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mcrypt
|
||||
PRIMARY MAINTAINER: Derick Rethans <derick@derickrethans.nl>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mhash
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>, Scott MacVicar <scottmac@php.net>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mime_magic
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
MAINTENANCE: Deprecated
|
||||
STATUS: Experimental
|
||||
COMMENT: Use the fileinfo extension instead
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ming
|
||||
PRIMARY MAINTAINER: Frank M. Kromann
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: openssl
|
||||
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>, Pierre-Alain Joye <pajoye@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.4
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pcntl
|
||||
PRIMARY MAINTAINER: Arnaud Le Blanc <lbarnaud@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pcre
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>, Nuno Lopes <nlopess@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: phar
|
||||
PRIMARY MAINTAINER: Greg Beaver <cellog@php.net>, Marcus Börger <helly@php.net>, Steph Fox <sfox@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: posix
|
||||
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pspell
|
||||
PRIMARY MAINTAINER: Vlad Krupin <phpdevel@echospace.com>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: readline
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: recode
|
||||
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: reflection
|
||||
PRIMARY MAINTAINER: Marcus Börger <helly@php.net>, Johannes Schlüter <johannes@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: session
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>, Ilia Alshanetsky <iliaa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: shmop
|
||||
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: snmp
|
||||
PRIMARY MAINTAINER: Boris Lytochkin <lytboris@php.net>, Rasmus Lerdorf <rasmus@php.net>, Pierre-Alain Joye <pajoye@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sockets
|
||||
PRIMARY MAINTAINER: Chris Vandomelen <chrisv@b0rked.dhs.org>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: spl
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>, Etienne Kneuss <colder@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sysvmsg
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sysvsem
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sysvshm
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: tidy
|
||||
PRIMARY MAINTAINER: John Coggeshall <john@php.net>, Ilia Alshanetsky <iliaa@php.net>, Nuno Lopes <nlopess@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: tokenizer
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: zip
|
||||
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: zlib
|
||||
PRIMARY MAINTAINER: Stefan Roehrich <sr@linux.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -1,68 +0,0 @@
|
||||
--------------------------------------------------------------------
|
||||
The PHP License, version 3.01
|
||||
Copyright (c) 1999 - 2010 The PHP Group. All rights reserved.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, is permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. The name "PHP" must not be used to endorse or promote products
|
||||
derived from this software without prior written permission. For
|
||||
written permission, please contact group@php.net.
|
||||
|
||||
4. Products derived from this software may not be called "PHP", nor
|
||||
may "PHP" appear in their name, without prior written permission
|
||||
from group@php.net. You may indicate that your software works in
|
||||
conjunction with PHP by saying "Foo for PHP" instead of calling
|
||||
it "PHP Foo" or "phpfoo"
|
||||
|
||||
5. The PHP Group may publish revised and/or new versions of the
|
||||
license from time to time. Each version will be given a
|
||||
distinguishing version number.
|
||||
Once covered code has been published under a particular version
|
||||
of the license, you may always continue to use it under the terms
|
||||
of that version. You may also choose to use such covered code
|
||||
under the terms of any subsequent version of the license
|
||||
published by the PHP Group. No one other than the PHP Group has
|
||||
the right to modify the terms applicable to covered code created
|
||||
under this License.
|
||||
|
||||
6. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes PHP software, freely available from
|
||||
<http://www.php.net/software/>".
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
|
||||
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
|
||||
DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
This software consists of voluntary contributions made by many
|
||||
individuals on behalf of the PHP Group.
|
||||
|
||||
The PHP Group can be contacted via Email at group@php.net.
|
||||
|
||||
For more information on the PHP Group and the PHP project,
|
||||
please see <http://www.php.net>.
|
||||
|
||||
PHP includes the Zend Engine, freely available at
|
||||
<http://www.zend.com>.
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
#
|
||||
# Zend
|
||||
#
|
||||
|
||||
$(builddir)/zend_language_scanner.lo: $(srcdir)/zend_language_parser.h
|
||||
$(builddir)/zend_ini_scanner.lo: $(srcdir)/zend_ini_parser.h
|
||||
|
||||
$(srcdir)/zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
|
||||
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l)
|
||||
|
||||
$(srcdir)/zend_language_parser.h: $(srcdir)/zend_language_parser.c
|
||||
$(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
|
||||
@$(YACC) -p zend -v -d $(srcdir)/zend_language_parser.y -o $@
|
||||
|
||||
$(srcdir)/zend_ini_parser.h: $(srcdir)/zend_ini_parser.c
|
||||
$(srcdir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
|
||||
@$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o $@
|
||||
|
||||
$(srcdir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
|
||||
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l)
|
||||
|
||||
$(builddir)/zend_indent.lo $(builddir)/zend_highlight.lo $(builddir)/zend_compile.lo: $(srcdir)/zend_language_parser.h
|
||||
@@ -1,65 +0,0 @@
|
||||
|
||||
#
|
||||
# LCOV
|
||||
#
|
||||
|
||||
lcov: lcov-html
|
||||
|
||||
lcov-test: lcov-clean-data test
|
||||
|
||||
php_lcov.info: lcov-test
|
||||
@echo "Generating data for $@"
|
||||
@rm -rf lcov_data/
|
||||
@$(mkinstalldirs) lcov_data/
|
||||
@echo
|
||||
-@files=`find . -name \*.gcda -o -name \*.gcno -o -name \*.da -o -name \*.h | sed -e 's/^\.\///' | sed -e 's/\.gcda//g' -e 's/\.gcno//g' -e 's/\.da//g' | uniq` ;\
|
||||
for x in $$files; do \
|
||||
echo -n . ;\
|
||||
y=`echo $$x | sed -e 's!\.libs/!!'`; \
|
||||
dir=lcov_data/`dirname $$x`; \
|
||||
test -d "$$dir" || $(mkinstalldirs) "$$dir"; \
|
||||
if test -f "$(top_srcdir)/$$y.c"; then \
|
||||
ln -f -s $(top_srcdir)/$$y.c lcov_data/$$y.c; \
|
||||
fi; \
|
||||
if test -f "$(top_srcdir)/$$y.h"; then \
|
||||
ln -f -s $(top_srcdir)/$$y.h lcov_data/$$y.h; \
|
||||
fi; \
|
||||
if test -f "$(top_srcdir)/$$y.re"; then \
|
||||
ln -f -s $(top_srcdir)/$$y.re lcov_data/$$y.re; \
|
||||
fi; \
|
||||
if test -f "$(top_srcdir)/$$y.y"; then \
|
||||
ln -f -s $(top_srcdir)/$$y.y lcov_data/$$y.y; \
|
||||
fi; \
|
||||
if test -f "$(top_srcdir)/$$y.l"; then \
|
||||
ln -f -s $(top_srcdir)/$$y.l lcov_data/$$y.l; \
|
||||
fi; \
|
||||
if test -f "$(top_srcdir)/$$y"; then \
|
||||
ln -f -s $(top_srcdir)/$$y lcov_data/$$y; \
|
||||
fi; \
|
||||
if test -f "$(top_builddir)/$$y.c"; then \
|
||||
ln -f -s $(top_builddir)/$$y.c lcov_data/$$y.c; \
|
||||
fi; \
|
||||
test -f "$$x.gcno" && cp $$x.gcno lcov_data/$$y.gcno ; \
|
||||
test -f "$$x.gcda" && cp $$x.gcda lcov_data/$$y.gcda ; \
|
||||
test -f "$$x.da" && cp $$x.da lcov_data/$$y.da ; \
|
||||
test -f "$$x.bb" && cp $$x.bb lcov_data/$$y.bb ; \
|
||||
test -f "$$x.bbg" && cp $$x.bbg lcov_data/$$y.bbg ; \
|
||||
done
|
||||
for dir in ext/bcmath/libbcmath ext/fileinfo/libmagic ext/gd/libgd ext/mbstring/libmbfl ext/mbstring/oniguruma ext/pcre/pcrelib ext/pdo_sqlite/libsqlite ext/sqlite/libsqlite ext/sqlite3/libsqlite ext/xmlrpc/libxmlrpc ext/zip/lib; do \
|
||||
test -d lcov_data/$$dir && rm -rf lcov_data/$$dir ; \
|
||||
done
|
||||
@echo
|
||||
@echo "Generating $@"
|
||||
@$(LTP) --directory lcov_data/ --capture --base-directory=lcov_data --output-file $@
|
||||
|
||||
lcov-html: php_lcov.info
|
||||
@echo "Generating lcov HTML"
|
||||
@$(LTP_GENHTML) --legend --output-directory lcov_html/ --title "PHP Code Coverage" php_lcov.info
|
||||
|
||||
lcov-clean:
|
||||
rm -f php_lcov.info
|
||||
rm -rf lcov_data/
|
||||
rm -rf lcov_html/
|
||||
|
||||
lcov-clean-data:
|
||||
@find . -name \*.gcda -o -name \*.da -o -name \*.bbg? | xargs rm -f
|
||||
-123
@@ -1,123 +0,0 @@
|
||||
mkinstalldirs = $(top_srcdir)/build/shtool mkdir -p
|
||||
INSTALL = $(top_srcdir)/build/shtool install -c
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
|
||||
DEFS = -DPHP_ATOM_INC -I$(top_builddir)/include -I$(top_builddir)/main -I$(top_srcdir)
|
||||
COMMON_FLAGS = $(DEFS) $(INCLUDES) $(EXTRA_INCLUDES) $(CPPFLAGS) $(PHP_FRAMEWORKPATH)
|
||||
|
||||
all: $(all_targets)
|
||||
@echo
|
||||
@echo "Build complete."
|
||||
@echo "Don't forget to run 'make test'."
|
||||
@echo
|
||||
|
||||
build-modules: $(PHP_MODULES) $(PHP_ZEND_EX)
|
||||
|
||||
build-binaries: $(PHP_BINARIES)
|
||||
|
||||
libphp$(PHP_MAJOR_VERSION).la: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
|
||||
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
|
||||
-@$(LIBTOOL) --silent --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1
|
||||
|
||||
libs/libphp$(PHP_MAJOR_VERSION).bundle: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
|
||||
$(CC) $(MH_BUNDLE_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_SAPI_OBJS:.lo=.o) $(PHP_FRAMEWORKS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ && cp $@ libs/libphp$(PHP_MAJOR_VERSION).so
|
||||
|
||||
install: $(all_targets) $(install_targets)
|
||||
|
||||
install-sapi: $(OVERALL_TARGET)
|
||||
@echo "Installing PHP SAPI module: $(PHP_SAPI)"
|
||||
-@$(mkinstalldirs) $(INSTALL_ROOT)$(bindir)
|
||||
-@if test ! -r $(phptempdir)/libphp$(PHP_MAJOR_VERSION).$(SHLIB_DL_SUFFIX_NAME); then \
|
||||
for i in 0.0.0 0.0 0; do \
|
||||
if test -r $(phptempdir)/libphp$(PHP_MAJOR_VERSION).$(SHLIB_DL_SUFFIX_NAME).$$i; then \
|
||||
$(LN_S) $(phptempdir)/libphp$(PHP_MAJOR_VERSION).$(SHLIB_DL_SUFFIX_NAME).$$i $(phptempdir)/libphp$(PHP_MAJOR_VERSION).$(SHLIB_DL_SUFFIX_NAME); \
|
||||
break; \
|
||||
fi; \
|
||||
done; \
|
||||
fi
|
||||
@$(INSTALL_IT)
|
||||
|
||||
install-binaries: build-binaries $(install_binary_targets)
|
||||
|
||||
install-modules: build-modules
|
||||
@test -d modules && \
|
||||
$(mkinstalldirs) $(INSTALL_ROOT)$(EXTENSION_DIR)
|
||||
@echo "Installing shared extensions: $(INSTALL_ROOT)$(EXTENSION_DIR)/"
|
||||
@rm -f modules/*.la >/dev/null 2>&1
|
||||
@$(INSTALL) modules/* $(INSTALL_ROOT)$(EXTENSION_DIR)
|
||||
|
||||
install-headers:
|
||||
-@if test "$(INSTALL_HEADERS)"; then \
|
||||
for i in `echo $(INSTALL_HEADERS)`; do \
|
||||
i=`$(top_srcdir)/build/shtool path -d $$i`; \
|
||||
paths="$$paths $(INSTALL_ROOT)$(phpincludedir)/$$i"; \
|
||||
done; \
|
||||
$(mkinstalldirs) $$paths && \
|
||||
echo "Installing header files: $(INSTALL_ROOT)$(phpincludedir)/" && \
|
||||
for i in `echo $(INSTALL_HEADERS)`; do \
|
||||
if test "$(PHP_PECL_EXTENSION)"; then \
|
||||
src=`echo $$i | $(SED) -e "s#ext/$(PHP_PECL_EXTENSION)/##g"`; \
|
||||
else \
|
||||
src=$$i; \
|
||||
fi; \
|
||||
if test -f "$(top_srcdir)/$$src"; then \
|
||||
$(INSTALL_DATA) $(top_srcdir)/$$src $(INSTALL_ROOT)$(phpincludedir)/$$i; \
|
||||
elif test -f "$(top_builddir)/$$src"; then \
|
||||
$(INSTALL_DATA) $(top_builddir)/$$src $(INSTALL_ROOT)$(phpincludedir)/$$i; \
|
||||
else \
|
||||
(cd $(top_srcdir)/$$src && $(INSTALL_DATA) *.h $(INSTALL_ROOT)$(phpincludedir)/$$i; \
|
||||
cd $(top_builddir)/$$src && $(INSTALL_DATA) *.h $(INSTALL_ROOT)$(phpincludedir)/$$i) 2>/dev/null || true; \
|
||||
fi \
|
||||
done; \
|
||||
fi
|
||||
|
||||
PHP_TEST_SETTINGS = -d 'open_basedir=' -d 'output_buffering=0' -d 'memory_limit=-1'
|
||||
PHP_TEST_SHARED_EXTENSIONS = ` \
|
||||
if test "x$(PHP_MODULES)" != "x"; then \
|
||||
for i in $(PHP_MODULES)""; do \
|
||||
. $$i; $(top_srcdir)/build/shtool echo -n -- " -d extension=$$dlname"; \
|
||||
done; \
|
||||
fi; \
|
||||
if test "x$(PHP_ZEND_EX)" != "x"; then \
|
||||
for i in $(PHP_ZEND_EX)""; do \
|
||||
. $$i; $(top_srcdir)/build/shtool echo -n -- " -d $(ZEND_EXT_TYPE)=$(top_builddir)/modules/$$dlname"; \
|
||||
done; \
|
||||
fi`
|
||||
PHP_DEPRECATED_DIRECTIVES_REGEX = '^(magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?)[\t\ ]*='
|
||||
|
||||
test: all
|
||||
-@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
|
||||
INI_FILE=`$(PHP_EXECUTABLE) -d 'display_errors=stderr' -r 'echo php_ini_loaded_file();' 2> /dev/null`; \
|
||||
if test "$$INI_FILE"; then \
|
||||
$(EGREP) -h -v $(PHP_DEPRECATED_DIRECTIVES_REGEX) "$$INI_FILE" > $(top_builddir)/tmp-php.ini; \
|
||||
else \
|
||||
echo > $(top_builddir)/tmp-php.ini; \
|
||||
fi; \
|
||||
INI_SCANNED_PATH=`$(PHP_EXECUTABLE) -d 'display_errors=stderr' -r '$$a = explode(",\n", trim(php_ini_scanned_files())); echo $$a[0];' 2> /dev/null`; \
|
||||
if test "$$INI_SCANNED_PATH"; then \
|
||||
INI_SCANNED_PATH=`$(top_srcdir)/build/shtool path -d $$INI_SCANNED_PATH`; \
|
||||
$(EGREP) -h -v $(PHP_DEPRECATED_DIRECTIVES_REGEX) "$$INI_SCANNED_PATH"/*.ini >> $(top_builddir)/tmp-php.ini; \
|
||||
fi; \
|
||||
TEST_PHP_EXECUTABLE=$(PHP_EXECUTABLE) \
|
||||
TEST_PHP_SRCDIR=$(top_srcdir) \
|
||||
CC="$(CC)" \
|
||||
$(PHP_EXECUTABLE) -n -c $(top_builddir)/tmp-php.ini $(PHP_TEST_SETTINGS) $(top_srcdir)/run-tests.php -n -c $(top_builddir)/tmp-php.ini -d extension_dir=$(top_builddir)/modules/ $(PHP_TEST_SHARED_EXTENSIONS) $(TESTS); \
|
||||
rm $(top_builddir)/tmp-php.ini; \
|
||||
else \
|
||||
echo "ERROR: Cannot run tests without CLI sapi."; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
find . -name \*.gcno -o -name \*.gcda | xargs rm -f
|
||||
find . -name \*.lo -o -name \*.o | xargs rm -f
|
||||
find . -name \*.la -o -name \*.a | xargs rm -f
|
||||
find . -name \*.so | xargs rm -f
|
||||
find . -name .libs -a -type d|xargs rm -rf
|
||||
rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(OVERALL_TARGET) modules/* libs/*
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h stamp-h sapi/apache/libphp$(PHP_MAJOR_VERSION).module buildmk.stamp
|
||||
$(EGREP) define'.*include/php' $(top_srcdir)/configure | $(SED) 's/.*>//'|xargs rm -f
|
||||
|
||||
.PHONY: all clean install distclean test
|
||||
.NOEXPORT:
|
||||
@@ -1,39 +0,0 @@
|
||||
Between PHP 4.0.6 and 4.1.0, the Zend module struct changed in a way
|
||||
that broke both source and binary compatibility. If you are
|
||||
maintaining a third party extension, here's how to update it:
|
||||
|
||||
If this was your old module entry:
|
||||
|
||||
zend_module_entry foo_module_entry = {
|
||||
"foo", /* extension name */
|
||||
foo_functions, /* extension function list */
|
||||
NULL, /* extension-wide startup function */
|
||||
NULL, /* extension-wide shutdown function */
|
||||
PHP_RINIT(foo), /* per-request startup function */
|
||||
PHP_RSHUTDOWN(foo), /* per-request shutdown function */
|
||||
PHP_MINFO(foo), /* information function */
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
|
||||
Here's how it should look if you want your code to build with PHP
|
||||
4.1.0 and up:
|
||||
|
||||
zend_module_entry foo_module_entry = {
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
STANDARD_MODULE_HEADER,
|
||||
#endif
|
||||
"foo", /* extension name */
|
||||
foo_functions, /* extension function list */
|
||||
NULL, /* extension-wide startup function */
|
||||
NULL, /* extension-wide shutdown function */
|
||||
PHP_RINIT(foo), /* per-request startup function */
|
||||
PHP_RSHUTDOWN(foo), /* per-request shutdown function */
|
||||
PHP_MINFO(foo), /* information function */
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
FOO_VERSION, /* extension version number (string) */
|
||||
#endif
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
|
||||
If you don't care about source compatibility with earlier PHP releases
|
||||
than 4.1.0, you can drop the #if/#endif lines.
|
||||
-165
@@ -1,165 +0,0 @@
|
||||
(NOTE: you may also want to take a look at the pear package
|
||||
PECL_Gen, a PHP-only alternative for this script that
|
||||
supports way more extension writing tasks and is
|
||||
supposed to replace ext_skel completely in the long run ...)
|
||||
|
||||
WHAT IT IS
|
||||
|
||||
It's a tool for automatically creating the basic framework for a PHP module
|
||||
and writing C code handling arguments passed to your functions from a simple
|
||||
configuration file. See an example at the end of this file.
|
||||
|
||||
HOW TO USE IT
|
||||
|
||||
Very simple. First, change to the ext/ directory of the PHP 4 sources. If
|
||||
you just need the basic framework and will be writing all the code in your
|
||||
functions yourself, you can now do
|
||||
|
||||
./ext_skel --extname=module_name
|
||||
|
||||
and everything you need is placed in directory module_name.
|
||||
|
||||
[ Note that GNU awk is likely required for this script to work. Debian
|
||||
systems seem to default to using mawk, so you may need to change the
|
||||
#! line in skeleton/create_stubs and the cat $proto | awk line in
|
||||
ext_skel to use gawk explicitly. ]
|
||||
|
||||
If you don't need to test the existence of any external header files,
|
||||
libraries or functions in them, the module is already almost ready to be
|
||||
compiled in PHP. Just remove 3 comments in your_module_name/config.m4,
|
||||
change back up to PHP sources top directory, and do
|
||||
|
||||
./buildconf; ./configure --enable-module_name; make
|
||||
|
||||
But if you already have planned the overall scheme of your module, what
|
||||
functions it will contain, their return types and the arguments they take
|
||||
(a very good idea) and don't want to bother yourself with creating function
|
||||
definitions and handling arguments passed yourself, it's time to create a
|
||||
function definitions file, which you will give as an argument to ext_skel
|
||||
with option
|
||||
|
||||
--proto=filename.
|
||||
|
||||
FORMAT OF FUNCTION DEFINITIONS FILE
|
||||
|
||||
All the definitions must be on one line. In it's simplest form, it's just
|
||||
the function name, e.g.
|
||||
|
||||
my_function
|
||||
|
||||
but then you'll be left with an almost empty function body without any
|
||||
argument handling.
|
||||
|
||||
Arguments are given in parenthesis after the function name, and are of
|
||||
the form 'argument_type argument_name'. Arguments are separated from each
|
||||
other with a comma and optional space. Argument_type can be one of int,
|
||||
bool, double, float, string, array, object or mixed.
|
||||
|
||||
An optional argument is separated from the previous by an optional space,
|
||||
then '[' and of course comma and optional space, like all the other
|
||||
arguments. You should close a row of optional arguments with same amount of
|
||||
']'s as there where '['s. Currently, it does not harm if you forget to do it
|
||||
or there is a wrong amount of ']'s, but this may change in the future.
|
||||
|
||||
An additional short description may be added after the parameters.
|
||||
If present it will be filled into the 'proto' header comments in the stubs
|
||||
code and the <refpurpose> tag in the XML documentation.
|
||||
|
||||
An example:
|
||||
|
||||
my_function(int arg1, int arg2 [, int arg3 [, int arg4]]) this is my 1st
|
||||
|
||||
Arguments arg3 and arg4 are optional.
|
||||
|
||||
If possible, the function definition should also contain it's return type
|
||||
in front of the definition. It's not actually used for any C code generating
|
||||
purposes but PHP in-source documentation instead, and as such, very useful.
|
||||
It can be any of int, double, string, bool, array, object, resource, mixed
|
||||
or void.
|
||||
|
||||
The file must contain nothing else but function definitions, no comments or
|
||||
empty lines.
|
||||
|
||||
OTHER OPTIONS
|
||||
|
||||
--no-help
|
||||
|
||||
By default, ext_skel creates both comments in the source code and a test
|
||||
function to help first time module writers to get started and testing
|
||||
configuring and compiling their module. This option turns off all such things
|
||||
which may just annoy experienced PHP module coders. Especially useful with
|
||||
|
||||
--stubs=file
|
||||
|
||||
which will leave out also all module specific stuff and write just function
|
||||
stubs with function value declarations and passed argument handling, and
|
||||
function entries and definitions at the end of the file, for copying and
|
||||
pasting into an already existing module.
|
||||
|
||||
--xml[=file]
|
||||
|
||||
Creates the basics for phpdoc .xml file.
|
||||
|
||||
--full-xml
|
||||
|
||||
Not implemented yet. When or if there will ever be created a framework for
|
||||
self-contained extensions to use phpdoc system for their documentation, this
|
||||
option enables it on the created xml file.
|
||||
|
||||
CURRENT LIMITATIONS, BUGS AND OTHER ODDITIES
|
||||
|
||||
Only arguments of types int, bool, double, float, string and array are
|
||||
handled. For other types you must write the code yourself. And for type
|
||||
mixed, it wouldn't even be possible to write anything, because only you
|
||||
know what to expect.
|
||||
|
||||
It can't handle correctly, and probably never will, variable list of
|
||||
of arguments. (void foo(int bar [, ...])
|
||||
|
||||
Don't trust the generated code too much. It tries to be useful in most of
|
||||
the situations you might encounter, but automatic code generation will never
|
||||
beat a programmer who knows the real situation at hand. ext_skel is generally
|
||||
best suited for quickly generating a wrapper for c-library functions you
|
||||
might want to have available in PHP too.
|
||||
|
||||
This program doesn't have a --help option. It has --no-help instead.
|
||||
|
||||
EXAMPLE
|
||||
|
||||
The following _one_ line
|
||||
|
||||
bool my_drawtext(resource image, string text, resource font, int x, int y [, int color])
|
||||
|
||||
will create this function definition for you (note that there are a few
|
||||
question marks to be replaced by you, and you must of course add your own
|
||||
value definitions too):
|
||||
|
||||
/* {{{ proto bool my_drawtext(resource image, string text, resource font, int x, int y [, int color])
|
||||
*/
|
||||
PHP_FUNCTION(my_drawtext)
|
||||
{
|
||||
char *text = NULL;
|
||||
int argc = ZEND_NUM_ARGS();
|
||||
int image_id = -1;
|
||||
int text_len;
|
||||
int font_id = -1;
|
||||
long x;
|
||||
long y;
|
||||
long color;
|
||||
zval *image = NULL;
|
||||
zval *font = NULL;
|
||||
|
||||
if (zend_parse_parameters(argc TSRMLS_CC, "rsrll|l", &image, &text, &text_len, &font, &x, &y, &color) == FAILURE)
|
||||
return;
|
||||
|
||||
if (image) {
|
||||
ZEND_FETCH_RESOURCE(???, ???, image, image_id, "???", ???_rsrc_id);
|
||||
}
|
||||
if (font) {
|
||||
ZEND_FETCH_RESOURCE(???, ???, font, font_id, "???", ???_rsrc_id);
|
||||
}
|
||||
|
||||
php_error(E_WARNING, "my_drawtext: not yet implemented");
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
====================
|
||||
Git Commit Rules
|
||||
====================
|
||||
|
||||
This is the first file you should be reading when contributing code via Git.
|
||||
We'll assume you're basically familiar with Git, but feel free to post
|
||||
your questions on the mailing list. Please have a look at
|
||||
http://git-scm.com/ for more detailed information on Git.
|
||||
|
||||
PHP is developed through the efforts of a large number of people.
|
||||
Collaboration is a Good Thing(tm), and Git lets us do this. Thus, following
|
||||
some basic rules with regards to Git usage will::
|
||||
|
||||
a. Make everybody happier, especially those responsible for maintaining
|
||||
Git itself.
|
||||
|
||||
b. Keep the changes consistently well documented and easily trackable.
|
||||
|
||||
c. Prevent some of those 'Oops' moments.
|
||||
|
||||
d. Increase the general level of good will on planet Earth.
|
||||
|
||||
Having said that, here are the organizational rules::
|
||||
|
||||
1. Respect other people working on the project.
|
||||
|
||||
2. Discuss any significant changes on the list before committing and get
|
||||
confirmation from the release manager for the given branch.
|
||||
|
||||
3. Look at EXTENSIONS file to see who is the primary maintainer of
|
||||
the code you want to contribute to.
|
||||
|
||||
4. If you "strongly disagree" about something another person did, don't
|
||||
start fighting publicly - take it up in private email.
|
||||
|
||||
5. If you don't know how to do something, ask first!
|
||||
|
||||
6. Test your changes before committing them. We mean it. Really.
|
||||
To do so use "make test".
|
||||
|
||||
7. For development use the --enable-maintainer-zts switch to ensure your
|
||||
code handles TSRM correctly and doesn't break for those who need that.
|
||||
|
||||
Currently we have the following branches in use::
|
||||
|
||||
master The active development branch.
|
||||
|
||||
PHP-5.4 Is used to release the PHP 5.4.x series. It still allows for
|
||||
larger enhancements.
|
||||
|
||||
PHP-5.3 Is used to release the PHP 5.3.x series. This is current
|
||||
stable version and is open for bugfixes only.
|
||||
|
||||
PHP-5.2 Is used to release the PHP 5.2.x series. It is closed for
|
||||
changes now.
|
||||
|
||||
PHP-5.1 This branch is closed.
|
||||
|
||||
PHP-4.4 This branch is closed.
|
||||
|
||||
The next few rules are more of a technical nature::
|
||||
|
||||
1. All changes should first go to the lowest branch (i.e. 5.3) and then
|
||||
get merged up to all other branches. If a change is not needed for
|
||||
later branches (i.e. fixes for features which where dropped from later
|
||||
branches) an empty merge should be done.
|
||||
|
||||
2. All news updates intended for public viewing, such as new features,
|
||||
bug fixes, improvements, etc., should go into the NEWS file of the
|
||||
*first* to be released version with the given change. In other words
|
||||
any NEWS file change only needs to done in one branch.
|
||||
|
||||
3. Do not commit multiple file and dump all messages in one commit. If you
|
||||
modified several unrelated files, commit each group separately and
|
||||
provide a nice commit message for each one. See example below.
|
||||
|
||||
4. Do write your commit message in such a way that it makes sense even
|
||||
without the corresponding diff. One should be able to look at it, and
|
||||
immediately know what was modified. Definitely include the function name
|
||||
in the message as shown below.
|
||||
|
||||
5. In your commit messages, keep each line shorter than 80 characters. And
|
||||
try to align your lines vertically, if they wrap. It looks bad otherwise.
|
||||
|
||||
6. If you modified a function that is callable from PHP, prepend PHP to
|
||||
the function name as shown below.
|
||||
|
||||
|
||||
The format of the commit messages is pretty simple.
|
||||
|
||||
<max 79 characters short description>\n
|
||||
\n
|
||||
<long description, 79 chars per line>
|
||||
\n
|
||||
|
||||
An Example from the git project (commit 2b34e486bc):
|
||||
|
||||
pack-objects: Fix compilation with NO_PTHREDS
|
||||
|
||||
It looks like commit 99fb6e04 (pack-objects: convert to use
|
||||
parse_options(), 2012-02-01) moved the #ifdef NO_PTHREDS around but
|
||||
hasn't noticed that the 'arg' variable no longer is available.
|
||||
|
||||
If you fix some bugs, you should note the bug ID numbers in your
|
||||
commit message. Bug ID should be prefixed by "#" for easier access to
|
||||
bug report when developers are browsing CVS via LXR or Bonsai.
|
||||
|
||||
Example::
|
||||
|
||||
Fixed bug #14016 (pgsql notice handler double free crash bug.)
|
||||
|
||||
When you change the NEWS file for a bug fix, then please keep the bugs
|
||||
sorted in decreasing order under the fixed version.
|
||||
|
||||
You can use OpenGrok (http://lxr.php.net/) and gitweb (http://git.php.net/)
|
||||
to look at PHP Git repository in various ways.
|
||||
|
||||
|
||||
For further information on the process and further details please refer to
|
||||
https://wiki.php.net/vcs/gitworkflow and https://wiki.php.net/vcs/gitfaq
|
||||
|
||||
Happy hacking,
|
||||
|
||||
PHP Team
|
||||
@@ -1,79 +0,0 @@
|
||||
====================
|
||||
Mailinglist Rules
|
||||
====================
|
||||
|
||||
This is the first file you should be reading before doing any posts on PHP
|
||||
mailinglists. Following these rules is considered imperative to the success of
|
||||
the PHP project. Therefore expect your contributions to be of much less positive
|
||||
impact if you do not follow these rules. More importantly you can actually
|
||||
assume that not following these rules will hurt the PHP project.
|
||||
|
||||
PHP is developed through the efforts of a large number of people.
|
||||
Collaboration is a Good Thing(tm), and mailinglists lets us do this. Thus,
|
||||
following some basic rules with regards to mailinglist usage will:
|
||||
|
||||
a. Make everybody happier, especially those responsible for developing PHP
|
||||
itself.
|
||||
|
||||
b. Help in making sure we all use our time more efficiently.
|
||||
|
||||
c. Prevent you from making a fool of yourself in public.
|
||||
|
||||
d. Increase the general level of good will on planet Earth.
|
||||
|
||||
|
||||
Having said that, here are the organizational rules:
|
||||
|
||||
1. Respect other people working on the project.
|
||||
|
||||
2. Do not post when you are angry. Any post can wait a few hours. Review
|
||||
your post after a good breather or a good nights sleep.
|
||||
|
||||
3. Make sure you pick the right mailinglist for your posting. Please review
|
||||
the descriptions on the mailinglist overview page
|
||||
(http://www.php.net/mailing-lists.php). When in doubt ask a friend or
|
||||
someone you trust on IRC.
|
||||
|
||||
4. Make sure you know what you are talking about. PHP is a very large project
|
||||
that strives to be very open. The flip side is that the core developers
|
||||
are faced with a lot of requests. Make sure that you have done your
|
||||
research before posting to the entire developer community.
|
||||
|
||||
5. Patches have a much greater chance of acceptance than just asking the
|
||||
PHP developers to implement a feature for you. For one it makes the
|
||||
discussion more concrete and it shows that the poster put thought and time
|
||||
into the request.
|
||||
|
||||
6. If you are posting to an existing thread, make sure that you know what
|
||||
previous posters have said. This is even more important the longer the
|
||||
thread is already.
|
||||
|
||||
7. Please configure your email client to use a real name and keep message
|
||||
signatures to a maximum of 2 lines if at all necessary.
|
||||
|
||||
The next few rules are more some general hints:
|
||||
|
||||
1. If you notice that your posting ratio is much higher than that of other
|
||||
people, double check the above rules. Try to wait a bit longer before
|
||||
sending your replies to give other people more time to digest your answers
|
||||
and more importantly give you the opportunity to make sure that you
|
||||
aggregate your current position into a single mail instead of multiple
|
||||
ones.
|
||||
|
||||
2. Consider taking a step back from a very active thread now and then. Maybe
|
||||
talking to some friends and fellow developers will help in understanding
|
||||
the other opinions better.
|
||||
|
||||
3. Do not top post. Place your answer underneath anyone you wish to quote
|
||||
and remove any previous comment that is not relevant to your post.
|
||||
|
||||
4. Do not high-jack threads, by bringing up entirely new topics. Please
|
||||
create an entirely new thread copying anything you wish to quote into the
|
||||
new thread.
|
||||
|
||||
Finally, additional hints on how to behave inside the virtual community can be
|
||||
found in RFC 1855 (http://www.faqs.org/rfcs/rfc1855.html).
|
||||
|
||||
Happy hacking,
|
||||
|
||||
PHP Team
|
||||
@@ -1,142 +0,0 @@
|
||||
$Id: README.NEW-OUTPUT-API 219039 2006-08-30 07:39:09Z mike $
|
||||
|
||||
|
||||
API adjustment to the old output control code:
|
||||
|
||||
Everything now resides beneath the php_output namespace,
|
||||
and there's an API call for every output handler op.
|
||||
|
||||
Checking output control layers status:
|
||||
// Using OG()
|
||||
php_output_get_status(TSRMLS_C);
|
||||
|
||||
Starting the default output handler:
|
||||
// php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
|
||||
php_output_start_default(TSRMLS_C);
|
||||
|
||||
Starting an user handler by zval:
|
||||
// php_start_ob_buffer(zhandler, chunk_size, erase TSRMLS_CC);
|
||||
php_output_start_user(zhandler, chunk_size, flags TSRMLS_CC);
|
||||
|
||||
Starting an internal handler whithout context:
|
||||
// php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase TSRMLS_CC);
|
||||
php_output_start_internal(handler_name, handler_name_len, my_php_output_handler_func_t, chunk_size, flags TSRMLS_CC);
|
||||
|
||||
Starting an internal handler with context:
|
||||
// not possible with old API
|
||||
php_output_handler *h;
|
||||
h = php_output_handler_create_internal(handler_name, handler_name_len, my_php_output_handler_context_func_t, chunk_size, flags TSRMLS_CC);
|
||||
php_output_handler_set_context(h, my_context, my_context_dtor);
|
||||
php_output_handler_start(h TSRMLS_CC);
|
||||
|
||||
Testing whether a certain output handler has already been started:
|
||||
// php_ob_handler_used("output handler name" TSRMLS_CC);
|
||||
php_output_handler_started(handler_name, handler_name_len TSRMLS_CC);
|
||||
|
||||
Flushing one output buffer:
|
||||
// php_ob_end_buffer(1, 1 TSRMLS_CC);
|
||||
php_output_flush(TSRMLS_C);
|
||||
|
||||
Flushing all output buffers:
|
||||
// not possible with old API
|
||||
php_output_flush_all(TSRMLS_C);
|
||||
|
||||
Cleaning one output buffer:
|
||||
// php_ob_end_buffer(0, 1 TSRMLS_CC);
|
||||
php_output_clean(TSRMLS_C);
|
||||
|
||||
Cleaning all output buffers:
|
||||
// not possible with old API
|
||||
php_output_clean_all(TSRMLS_C);
|
||||
|
||||
Discarding one output buffer:
|
||||
// php_ob_end_buffer(0, 0 TSRMLS_CC);
|
||||
php_output_discard(TSRMLS_C);
|
||||
|
||||
Discarding all output buffers:
|
||||
// php_ob_end_buffers(0 TSRMLS_CC);
|
||||
php_output_discard_all(TSRMLS_C);
|
||||
|
||||
Stopping (and dropping) one output buffer:
|
||||
// php_ob_end_buffer(1, 0 TSRMLS_CC)
|
||||
php_output_end(TSRMLS_C);
|
||||
|
||||
Stopping (and dropping) all output buffers:
|
||||
// php_ob_end_buffers(1, 0 TSRMLS_CC);
|
||||
php_output_end_all(TSRMLS_C);
|
||||
|
||||
Retrieving output buffers contents:
|
||||
// php_ob_get_buffer(zstring TSRMLS_CC);
|
||||
php_output_get_contents(zstring TSRMLS_CC);
|
||||
|
||||
Retrieving output buffers length:
|
||||
// php_ob_get_length(zlength TSRMLS_CC);
|
||||
php_output_get_length(zlength TSRMLS_CC);
|
||||
|
||||
Retrieving output buffering level:
|
||||
// OG(nesting_level);
|
||||
php_output_get_level(TSRMLS_C);
|
||||
|
||||
Issue a warning because of an output handler conflict:
|
||||
// php_ob_init_conflict("to be started handler name", "to be tested if already started handler name" TSRMLS_CC);
|
||||
php_output_handler_conflict(new_handler_name, new_handler_name_len, set_handler_name, set_handler_name_len TSRMLS_CC);
|
||||
|
||||
Registering a conflict checking function, which will be checked prior starting the handler:
|
||||
// not possible with old API, unless hardcoding into output.c
|
||||
php_output_handler_conflict_register(handler_name, handler_name_len, my_php_output_handler_conflict_check_t TSRMLS_CC);
|
||||
|
||||
Registering a reverse conflict checking function, which will be checked prior starting the specified foreign handler:
|
||||
// not possible with old API
|
||||
php_output_handler_reverse_conflict_register(foreign_handler_name, foreign_handler_name_len, my_php_output_handler_conflict_check_t TSRMLS_CC);
|
||||
|
||||
Facilitating a context from within an output handler callable with ob_start():
|
||||
// not possible with old API
|
||||
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ, (void *) &custom_ctx_ptr_ptr TSRMLS_CC);
|
||||
|
||||
Disabling of the output handler by itself:
|
||||
//not possible with old API
|
||||
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_DISABLE, NULL TSRMLS_CC);
|
||||
|
||||
Marking an output handler immutable by itself because of irreversibility of its operation:
|
||||
// not possible with old API
|
||||
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL TSRMLS_CC);
|
||||
|
||||
Restarting the output handler because of a CLEAN operation:
|
||||
// not possible with old API
|
||||
if (flags & PHP_OUTPUT_HANDLER_CLEAN) { ... }
|
||||
|
||||
Recognizing by the output handler itself if it gets discarded:
|
||||
// not possible with old API
|
||||
if ((flags & PHP_OUTPUT_HANDLER_CLEAN) && (flags & PHP_OUTPUT_HANDLER_FINAL)) { ... }
|
||||
|
||||
|
||||
Output handler hooks
|
||||
|
||||
The output handler can change its abilities at runtime. Eg. the gz handler can
|
||||
remove the CLEANABLE and REMOVABLE bits when the first output has passed through it;
|
||||
or handlers implemented in C to be used with ob_start() can contain a non-global
|
||||
context:
|
||||
PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ
|
||||
pass a void*** pointer as second arg to receive the address of a pointer
|
||||
pointer to the opaque field of the output handler context
|
||||
PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS
|
||||
pass a int* pointer as second arg to receive the flags set for the output handler
|
||||
PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL
|
||||
pass a int* pointer as second arg to receive the level of this output handler
|
||||
(starts with 0)
|
||||
PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE
|
||||
the second arg is ignored; marks the output handler to be neither cleanable
|
||||
nor removable
|
||||
PHP_OUTPUT_HANDLER_HOOK_DISABLE
|
||||
the second arg is ignored; marks the output handler as disabled
|
||||
|
||||
|
||||
Open questions
|
||||
|
||||
Should the userland API be adjusted and unified?
|
||||
|
||||
Many bits of the manual (and very first implementation) do not comply
|
||||
with the behaviour of the current (to be obsoleted) code, thus should
|
||||
the manual or the behaviour be adjusted?
|
||||
|
||||
END
|
||||
@@ -1,219 +0,0 @@
|
||||
New parameter parsing functions
|
||||
===============================
|
||||
|
||||
It should be easier to parse input parameters to an extension function.
|
||||
Hence, borrowing from Python's example, there are now a set of functions
|
||||
that given the string of type specifiers, can parse the input parameters
|
||||
and store the results in the user specified variables. This avoids most
|
||||
of the IS_* checks and convert_to_* conversions. The functions also
|
||||
check for the appropriate number of parameters, and try to output
|
||||
meaningful error messages.
|
||||
|
||||
|
||||
Prototypes
|
||||
----------
|
||||
/* Implemented. */
|
||||
int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);
|
||||
int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...);
|
||||
|
||||
The zend_parse_parameters() function takes the number of parameters
|
||||
passed to the extension function, the type specifier string, and the
|
||||
list of pointers to variables to store the results in. The _ex() version
|
||||
also takes 'flags' argument -- current only ZEND_PARSE_PARAMS_QUIET can
|
||||
be used as 'flags' to specify that the function should operate quietly
|
||||
and not output any error messages.
|
||||
|
||||
Both functions return SUCCESS or FAILURE depending on the result.
|
||||
|
||||
The auto-conversions are performed as necessary. Arrays, objects, and
|
||||
resources cannot be auto-converted.
|
||||
|
||||
|
||||
Type specifiers
|
||||
---------------
|
||||
The following list shows the type specifier, its meaning and the parameter
|
||||
types that need to be passed by address. All passed paramaters are set
|
||||
if the PHP parameter is non optional and untouched if optional and the
|
||||
parameter is not present. The only exception is O where the zend_class_entry*
|
||||
has to be provided on input and is used to verify the PHP parameter is an
|
||||
instance of that class.
|
||||
|
||||
a - array (zval*)
|
||||
A - array or object (zval *)
|
||||
b - boolean (zend_bool)
|
||||
C - class (zend_class_entry*)
|
||||
d - double (double)
|
||||
f - function or array containing php method call info (returned as
|
||||
zend_fcall_info and zend_fcall_info_cache)
|
||||
h - array (returned as HashTable*)
|
||||
H - array or HASH_OF(object) (returned as HashTable*)
|
||||
l - long (long)
|
||||
L - long, limits out-of-range numbers to LONG_MAX/LONG_MIN (long)
|
||||
o - object of any type (zval*)
|
||||
O - object of specific type given by class entry (zval*, zend_class_entry)
|
||||
p - valid path (string without null bytes in the middle) and its length (char*, int)
|
||||
r - resource (zval*)
|
||||
s - string (with possible null bytes) and its length (char*, int)
|
||||
z - the actual zval (zval*)
|
||||
Z - the actual zval (zval**)
|
||||
* - variable arguments list (0 or more)
|
||||
+ - variable arguments list (1 or more)
|
||||
|
||||
The following characters also have a meaning in the specifier string:
|
||||
| - indicates that the remaining parameters are optional, they
|
||||
should be initialized to default values by the extension since they
|
||||
will not be touched by the parsing function if they are not
|
||||
passed to it.
|
||||
/ - use SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows
|
||||
! - the parameter it follows can be of specified type or NULL (applies
|
||||
to all specifiers except for 'b', 'l', and 'd'). If NULL is passed, the
|
||||
results pointer is set to NULL as well.
|
||||
|
||||
|
||||
Note on 64bit compatibility
|
||||
---------------------------
|
||||
Please do not forget that int and long are two different things on 64bit
|
||||
OSes (int is 4 bytes and long is 8 bytes), so make sure you pass longs to "l"
|
||||
and ints to strings length (i.e. for "s" you need to pass char * and int),
|
||||
not the other way round!
|
||||
Remember: "l" is the only case when you need to pass long (and that's why
|
||||
it's "l", not "i" btw).
|
||||
|
||||
Both mistakes cause memory corruptions and segfaults on 64bit OSes:
|
||||
1)
|
||||
char *str;
|
||||
long str_len; /* XXX THIS IS WRONG!! Use int instead. */
|
||||
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len)
|
||||
|
||||
2)
|
||||
int num; /* XXX THIS IS WRONG!! Use long instead. */
|
||||
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num)
|
||||
|
||||
If you're in doubt, use check_parameters.php script to the parameters
|
||||
and their types (it can be found in ./scripts/dev/ directory of PHP sources):
|
||||
|
||||
# php ./scripts/dev/check_parameters.php /path/to/your/sources/
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
/* Gets a long, a string and its length, and a zval */
|
||||
long l;
|
||||
char *s;
|
||||
int s_len;
|
||||
zval *param;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsz",
|
||||
&l, &s, &s_len, ¶m) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Gets an object of class specified by my_ce, and an optional double. */
|
||||
zval *obj;
|
||||
double d = 0.5;
|
||||
zend_class_entry *my_ce;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|d",
|
||||
&obj, my_ce, &d) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Gets an object or null, and an array.
|
||||
If null is passed for object, obj will be set to NULL. */
|
||||
zval *obj;
|
||||
zval *arr;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o!a",
|
||||
&obj, &arr) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Gets a separated array which can also be null. */
|
||||
zval *arr;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!",
|
||||
&arr) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get either a set of 3 longs or a string. */
|
||||
long l1, l2, l3;
|
||||
char *s;
|
||||
/*
|
||||
* The function expects a pointer to a integer in this case, not a long
|
||||
* or any other type. If you specify a type which is larger
|
||||
* than a 'int', the upper bits might not be initialized
|
||||
* properly, leading to random crashes on platforms like
|
||||
* Tru64 or Linux/Alpha.
|
||||
*/
|
||||
int length;
|
||||
|
||||
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
|
||||
"lll", &l1, &l2, &l3) == SUCCESS) {
|
||||
/* manipulate longs */
|
||||
} else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
|
||||
"s", &s, &length) == SUCCESS) {
|
||||
/* manipulate string */
|
||||
} else {
|
||||
/* output error */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Function that accepts only varargs (0 or more) */
|
||||
|
||||
int i, num_varargs;
|
||||
zval ***varargs = NULL;
|
||||
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", &varargs, &num_varargs) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_varargs; i++) {
|
||||
/* do something with varargs[i] */
|
||||
}
|
||||
|
||||
if (varargs) {
|
||||
efree(varargs);
|
||||
}
|
||||
|
||||
|
||||
/* Function that accepts a string, followed by varargs (1 or more) */
|
||||
|
||||
char *str;
|
||||
int str_len;
|
||||
int i, num_varargs;
|
||||
zval ***varargs = NULL;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s+", &str, &str_len, &varargs, &num_varargs) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_varargs; i++) {
|
||||
/* do something with varargs[i] */
|
||||
}
|
||||
|
||||
if (varargs) {
|
||||
efree(varargs);
|
||||
}
|
||||
|
||||
|
||||
/* Function that takes an array, followed by varargs, and ending with a long */
|
||||
long num;
|
||||
zval *array;
|
||||
int i, num_varargs;
|
||||
zval ***varargs = NULL;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a*l", &array, &varargs, &num_varargs, &num) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_varargs; i++) {
|
||||
/* do something with varargs[i] */
|
||||
}
|
||||
|
||||
if (varargs) {
|
||||
efree(varargs);
|
||||
}
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
1. strrpos() and strripos() now use the entire string as a needle. Be aware
|
||||
that the existing scripts may no longer work as you expect.
|
||||
|
||||
EX :
|
||||
<?php
|
||||
var_dump(strrpos("ABCDEF","DEF"));
|
||||
var_dump(strrpos("ABCDEF","DAF"));
|
||||
?>
|
||||
|
||||
Will give you different results. The former returns 3 while the latter
|
||||
returns false rather than the position of the last occurrence of 'D'.
|
||||
The same applies to strripos().
|
||||
|
||||
2. Illegal use of string offsets causes E_ERROR instead of E_WARNING.
|
||||
|
||||
EX :
|
||||
<?php
|
||||
$a = "foo";
|
||||
unset($a[0][1][2]);
|
||||
?>
|
||||
|
||||
Fatal error: Cannot use string offset as an array in ... on line 1
|
||||
|
||||
3. array_merge() was changed to accept only arrays. If a non-array variable is
|
||||
passed, a E_WARNING will be thrown for every such parameter. Be careful
|
||||
because your code may start emitting E_WARNING out of the blue.
|
||||
|
||||
4. Be careful when porting from ext/mysql to ext/mysqli. The following
|
||||
functions return NULL when no more data is available in the result set
|
||||
(ext/mysql's functions return FALSE).
|
||||
|
||||
- mysqli_fetch_row()
|
||||
- mysqli_fetch_array()
|
||||
- mysqli_fetch_assoc()
|
||||
|
||||
5. PATH_TRANSLATED server variable is no longer set implicitly under
|
||||
Apache2 SAPI in contrast to the situation in PHP 4, where it is set to the
|
||||
same value as the SCRIPT_FILENAME server variable when it is not populated
|
||||
by Apache. This change was made to comply with the CGI specification.
|
||||
Please refer to bug #23610 for further information.
|
||||
|
||||
6. Starting PHP 5.0.0 the T_ML_CONSTANT constant is no longer defined by the
|
||||
ext/tokenizer extension. If error_reporting is set to E_ALL notices will
|
||||
be produced. Instead of T_ML_CONSTANT for /* */ the T_COMMENT constant
|
||||
is used, thus both // and /* */ are resolved as the T_COMMENT constant.
|
||||
However the PHPDoc style comments /** */ ,which starting PHP 5 are parsed
|
||||
by PHP, are recongnized as T_DOC_COMMENT.
|
||||
|
||||
7. $_SERVER should be populated with argc and argv if variables_order
|
||||
includes "S". If you have specifically configured your system to not
|
||||
create $_SERVER, then of course it shouldn't be there. The change was to
|
||||
always make argc and argv available in the CLI version regardless of the
|
||||
variables_order setting. As in, the CLI version will now always populate
|
||||
the global $argc and $argv variables.
|
||||
|
||||
8. In some cases classes must be declared before used. It only happens only
|
||||
if some of the new features of PHP 5 are used. Otherwise the behaviour is
|
||||
the old.
|
||||
Example 1 (works with no errors):
|
||||
<?php
|
||||
$a = new a();
|
||||
class a {
|
||||
}
|
||||
?>
|
||||
|
||||
Example 2 (throws an error):
|
||||
<?php
|
||||
$a = new a();
|
||||
interface b{
|
||||
}
|
||||
class a implements b {
|
||||
}
|
||||
?>
|
||||
|
||||
Output (example 2) :
|
||||
Fatal error: Class 'a' not found in /tmp/cl.php on line 2
|
||||
|
||||
9. get_class() starting PHP 5 returns the name of the class as it was
|
||||
declared which may lead to problems in older scripts that rely on
|
||||
the previous behaviour - the class name is lowercased. Expect the
|
||||
same behaviour from get_parent_class() when applicable.
|
||||
Example :
|
||||
<?php
|
||||
class FooBar {
|
||||
}
|
||||
class ExtFooBar extends FooBar{}
|
||||
$a = new FooBar();
|
||||
var_dump(get_class($a), get_parent_class($a));
|
||||
?>
|
||||
|
||||
Output (PHP 4):
|
||||
string(6) "foobar"
|
||||
string(9) "extfoobar"
|
||||
|
||||
Output (PHP 5):
|
||||
string(6) "FooBar"
|
||||
string(9) "ExtFooBar"
|
||||
----------------------------------------------------------------------
|
||||
Example code that will break :
|
||||
//....
|
||||
function someMethod($p) {
|
||||
if (get_class($p) != 'helpingclass') {
|
||||
return FALSE;
|
||||
}
|
||||
//...
|
||||
}
|
||||
//...
|
||||
Possible solution is to search for get_class() and get_parent_class() in
|
||||
all your scripts and use strtolower().
|
||||
|
||||
10. get_class_methods() returns the names of the methods of a class as they
|
||||
declared. In PHP4 the names are all lowercased.
|
||||
Example code :
|
||||
<?php
|
||||
class Foo{
|
||||
function doFoo(){}
|
||||
function hasFoo(){}
|
||||
}
|
||||
var_dump(get_class_methods("Foo"));
|
||||
?>
|
||||
Output (PHP4):
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(5) "dofoo"
|
||||
[1]=>
|
||||
string(6) "hasfoo"
|
||||
}
|
||||
Output (PHP5):
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(5) "doFoo"
|
||||
[1]=>
|
||||
string(6) "hasFoo"
|
||||
}
|
||||
|
||||
11. Assignment $this is impossible. Starting PHP 5.0.0 $this has special
|
||||
meaning in class methods and is recognized by the PHP parser. The latter
|
||||
will generate a parse error when assignment to $this is found
|
||||
Example code :
|
||||
<?php
|
||||
class Foo {
|
||||
function assignNew($obj) {
|
||||
$this = $obj;
|
||||
}
|
||||
}
|
||||
$a = new Foo();
|
||||
$b = new Foo();
|
||||
$a->assignNew($b);
|
||||
echo "I was executed\n";
|
||||
?>
|
||||
Output (PHP 4):
|
||||
I was executed
|
||||
Output (PHP 5):
|
||||
PHP Fatal error: Cannot re-assign $this in /tmp/this_ex.php on line 4
|
||||
|
||||
@@ -1,442 +0,0 @@
|
||||
1. libmagic (ext/fileinfo) see ext/fileinfo/libmagic/LICENSE
|
||||
2. Oniguruma (ext/mbstring) see ext/mbstring/oniguruma/COPYING
|
||||
3. libmbfl (ext/mbstring) see ext/mbstring/libmbfl/LICENSE
|
||||
4. pcrelib (ext/pcre) see ext/pcre/pcrelib/LICENCE
|
||||
5. ext/standard crypt
|
||||
6. ext/standard crypt's blowfish implementation
|
||||
7. Sqlite/Sqlite3 ext/sqlite3 ext/sqlite
|
||||
8. ext/json/json_parser
|
||||
9. ext/standard/rand
|
||||
10. ext/standard/scanf
|
||||
11. ext/standard/strnatcmp.c
|
||||
12. ext/standard/uuencode
|
||||
13. libxmlrpc ext/xmlrpc
|
||||
14. libzip ext/zip
|
||||
15. main/snprintf.c
|
||||
16. main/strlcat
|
||||
17. main/strlcpy
|
||||
18. libgd see ext/gd/libgd/COPYING
|
||||
|
||||
5. ext/standard crypt
|
||||
|
||||
FreeSec: libcrypt for NetBSD
|
||||
|
||||
Copyright (c) 1994 David Burren
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the author nor the names of other contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
|
||||
6. ext/standard crypt's blowfish implementation
|
||||
|
||||
The crypt_blowfish homepage is:
|
||||
|
||||
http://www.openwall.com/crypt/
|
||||
|
||||
This code comes from John the Ripper password cracker, with reentrant
|
||||
and crypt(3) interfaces added, but optimizations specific to password
|
||||
cracking removed.
|
||||
|
||||
Written by Solar Designer <solar at openwall.com> in 1998-2011.
|
||||
No copyright is claimed, and the software is hereby placed in the public
|
||||
domain. In case this attempt to disclaim copyright and place the software
|
||||
in the public domain is deemed null and void, then the software is
|
||||
Copyright (c) 1998-2011 Solar Designer and it is hereby released to the
|
||||
general public under the following terms:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted.
|
||||
|
||||
There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
|
||||
It is my intent that you should be able to use this on your system,
|
||||
as part of a software package, or anywhere else to improve security,
|
||||
ensure compatibility, or for any other purpose. I would appreciate
|
||||
it if you give credit where it is due and keep your modifications in
|
||||
the public domain as well, but I don't require that in order to let
|
||||
you place this code and any modifications you make under a license
|
||||
of your choice.
|
||||
|
||||
This implementation is mostly compatible with OpenBSD's bcrypt.c (prefix
|
||||
"$2a$") by Niels Provos <provos at citi.umich.edu>, and uses some of his
|
||||
ideas. The password hashing algorithm was designed by David Mazieres
|
||||
<dm at lcs.mit.edu>. For more information on the level of compatibility,
|
||||
please refer to the comments in BF_set_key() and to the crypt(3) man page
|
||||
included in the crypt_blowfish tarball.
|
||||
|
||||
There's a paper on the algorithm that explains its design decisions:
|
||||
|
||||
http://www.usenix.org/events/usenix99/provos.html
|
||||
|
||||
Some of the tricks in BF_ROUND might be inspired by Eric Young's
|
||||
Blowfish library (I can't be sure if I would think of something if I
|
||||
hadn't seen his code).
|
||||
|
||||
|
||||
7. Sqlite/Sqlite3 ext/sqlite3 ext/sqlite
|
||||
|
||||
The author disclaims copyright to this source code. In place of
|
||||
a legal notice, here is a blessing:
|
||||
May you do good and not evil.
|
||||
May you find forgiveness for yourself and forgive others.
|
||||
May you share freely, never taking more than you give.
|
||||
|
||||
|
||||
8. ext/json/json_parser
|
||||
Copyright (c) 2005 JSON.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
The Software shall be used for Good, not Evil.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
9. ext/standard/rand
|
||||
The following php_mt_...() functions are based on a C++ class MTRand by
|
||||
Richard J. Wagner. For more information see the web page at
|
||||
http://www-personal.engin.umich.edu/~wagnerr/MersenneTwister.html
|
||||
|
||||
Mersenne Twister random number generator -- a C++ class MTRand
|
||||
Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
|
||||
Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com
|
||||
|
||||
The Mersenne Twister is an algorithm for generating random numbers. It
|
||||
was designed with consideration of the flaws in various other generators.
|
||||
The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
|
||||
are far greater. The generator is also fast; it avoids multiplication and
|
||||
division, and it benefits from caches and pipelines. For more information
|
||||
see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
|
||||
|
||||
Reference
|
||||
M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
|
||||
Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
|
||||
Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
|
||||
|
||||
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||
Copyright (C) 2000 - 2003, Richard J. Wagner
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The names of its contributors may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
10. ext/standard/scanf
|
||||
scanf.c --
|
||||
|
||||
This file contains the base code which implements sscanf and by extension
|
||||
fscanf. Original code is from TCL8.3.0 and bears the following copyright:
|
||||
|
||||
This software is copyrighted by the Regents of the University of
|
||||
California, Sun Microsystems, Inc., Scriptics Corporation,
|
||||
and other parties. The following terms apply to all files associated
|
||||
with the software unless explicitly disclaimed in individual files.
|
||||
|
||||
The authors hereby grant permission to use, copy, modify, distribute,
|
||||
and license this software and its documentation for any purpose, provided
|
||||
that existing copyright notices are retained in all copies and that this
|
||||
notice is included verbatim in any distributions. No written agreement,
|
||||
license, or royalty fee is required for any of the authorized uses.
|
||||
Modifications to this software may be copyrighted by their authors
|
||||
and need not follow the licensing terms described here, provided that
|
||||
the new terms are clearly indicated on the first page of each file where
|
||||
they apply.
|
||||
|
||||
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
|
||||
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
|
||||
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
|
||||
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
|
||||
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
||||
MODIFICATIONS.
|
||||
|
||||
GOVERNMENT USE: If you are acquiring this software on behalf of the
|
||||
U.S. government, the Government shall have only "Restricted Rights"
|
||||
in the software and related documentation as defined in the Federal
|
||||
Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
|
||||
are acquiring the software on behalf of the Department of Defense, the
|
||||
software shall be classified as "Commercial Computer Software" and the
|
||||
Government shall have only "Restricted Rights" as defined in Clause
|
||||
252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
|
||||
authors grant the U.S. Government and others acting in its behalf
|
||||
permission to use and distribute the software in accordance with the
|
||||
terms specified in this license.
|
||||
|
||||
11. ext/standard/strnatcmp.c
|
||||
|
||||
strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
|
||||
Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
12. ext/standard/uuencode
|
||||
Portions of this code are based on Berkeley's uuencode/uudecode
|
||||
implementation.
|
||||
|
||||
Copyright (c) 1983, 1993
|
||||
The Regents of the University of California. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the University of
|
||||
California, Berkeley and its contributors.
|
||||
4. Neither the name of the University nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
|
||||
13. libxmlrpc ext/xmlrpc
|
||||
|
||||
Copyright 2000 Epinions, Inc.
|
||||
|
||||
Subject to the following 3 conditions, Epinions, Inc. permits you, free
|
||||
of charge, to (a) use, copy, distribute, modify, perform and display this
|
||||
software and associated documentation files (the "Software"), and (b)
|
||||
permit others to whom the Software is furnished to do so as well.
|
||||
|
||||
1) The above copyright notice and this permission notice shall be included
|
||||
without modification in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF
|
||||
ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY
|
||||
IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE OR NONINFRINGEMENT.
|
||||
|
||||
3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING
|
||||
NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
14. libzip ext/zip
|
||||
zip.h -- exported declarations.
|
||||
Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
15. main/snprintf.c
|
||||
Copyright (c) 2002, 2006 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
Sponsored in part by the Defense Advanced Research Projects
|
||||
Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
|
||||
main/spprintf
|
||||
Copyright (c) 1995-1998 The Apache Group. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. All advertising materials mentioning features or use of this
|
||||
software must display the following acknowledgment:
|
||||
"This product includes software developed by the Apache Group
|
||||
for use in the Apache HTTP server project (http://www.apache.org/)."
|
||||
|
||||
4. The names "Apache Server" and "Apache Group" must not be used to
|
||||
endorse or promote products derived from this software without
|
||||
prior written permission.
|
||||
|
||||
5. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes software developed by the Apache Group
|
||||
for use in the Apache HTTP server project (http://www.apache.org/)."
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
|
||||
EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
|
||||
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
====================================================================
|
||||
|
||||
This software consists of voluntary contributions made by many
|
||||
individuals on behalf of the Apache Group and was originally based
|
||||
on public domain software written at the National Center for
|
||||
Supercomputing Applications, University of Illinois, Urbana-Champaign.
|
||||
For more information on the Apache Group and the Apache HTTP server
|
||||
project, please see <http://www.apache.org/>.
|
||||
|
||||
This code is based on, and used with the permission of, the
|
||||
SIO stdio-replacement strx_* functions by Panos Tsirigotis
|
||||
<panos@alumni.cs.colorado.edu> for xinetd.
|
||||
|
||||
16. main/strlcat
|
||||
17. main/strlcpy
|
||||
Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
@@ -1,270 +0,0 @@
|
||||
=======================
|
||||
PHP Release Process
|
||||
=======================
|
||||
|
||||
General notes and tips
|
||||
----------------------
|
||||
|
||||
1. Do not release on Fridays, Saturdays or Sundays
|
||||
because the sysadmins can not upgrade stuff then.
|
||||
|
||||
2. Package the day before a release. So if the release is to be on Thursday,
|
||||
package on Wednesday.
|
||||
|
||||
3. Ensure that Windows builds will work before packaging
|
||||
|
||||
4. Follow all steps to the letter. When unclear ask previous RM's (Derick/Ilia)
|
||||
before proceeding. Ideally make sure that for the first releases one of the
|
||||
previous RM's is around to answer questions. For the steps related to the
|
||||
php/QA/bug websites try to have someone from the webmaster team (Bjori) on hand.
|
||||
|
||||
5. Verify the tags to be extra sure everything was tagged properly.
|
||||
|
||||
6. Moving extensions from/to PECL requires write acces to the destination.
|
||||
Most developers should have this.
|
||||
|
||||
Moving extensions from php-src to PECL
|
||||
- Checkout the pecl directory, most likely you want a sparse-root checkout
|
||||
svn co --depth=empty https://svn.php.net/repository/pecl
|
||||
- Create an directory for the extension incl. branch and tag structure,
|
||||
no trunk at this point and commit this to svn
|
||||
cd pecl; mkdir foo foo/tags foo/branches; svn add foo; svn commit
|
||||
- Move the extension from php-src to the new location
|
||||
svn mv https://svn.php.net/repository/php/php-src/trunk/ext/foo \
|
||||
https://svn.php.net/repository/pecl/foo/trunk
|
||||
|
||||
If the extension is still usable or not dead, in cooperation with the extension
|
||||
maintainers if any:
|
||||
- create the pecl.php.net/foo package and its content, license, maintainer
|
||||
- create the package.xml, commit
|
||||
- release the package
|
||||
|
||||
For Moving extensions from PECL to php-src the svn mv has to be tone the other
|
||||
way round.
|
||||
|
||||
Rolling a non stable release (alpha/beta/RC)
|
||||
--------------------------------------------
|
||||
|
||||
1. Check windows snapshot builder logs (http://windows.php.net/downloads/snaps/ the last revision)
|
||||
|
||||
2. run the "scripts/dev/credits" script in php-src and commit the changes in the
|
||||
credits files in ext/standard.
|
||||
|
||||
3. Checkout the release branch for this release (e.g., PHP-5.4.2).
|
||||
|
||||
4. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``.
|
||||
Do not use abbreviations for alpha and beta.
|
||||
|
||||
5. Commit these changes to the branch with ``git commit -a``.
|
||||
|
||||
6. Tag the repository with the version, e.g.:
|
||||
``git tag -u YOURKEYID php-5.4.2RC2``
|
||||
|
||||
7. Push the changes to the main repo:
|
||||
``git push --tags origin HEAD``
|
||||
|
||||
8. run: ``./makedist 5.4.2RC2``, this will export the tree, create configure
|
||||
and build two tarballs (one gz and one bz2).
|
||||
|
||||
9. Copy those two tarballs to www.php.net, in your homedir there should be a
|
||||
directory "downloads/". Copy them into there, so that the system can generate
|
||||
MD5 sums. If you do not have this directory, talk to Derick.
|
||||
|
||||
10. Now the RC can be found on http://downloads.php.net/yourname,
|
||||
f.e. http://downloads.php.net/derick/
|
||||
|
||||
11. Once the release has been tagged, contact the PHP Windows development team
|
||||
(internals-win@lists.php.net) so that Windows binaries can be created. Once
|
||||
those are made, they should be placed into the same directory as the source snapshots.
|
||||
|
||||
Getting the non stable release (alpha/beta/RC) announced
|
||||
--------------------------------------------------------
|
||||
|
||||
1. Send an email (see example here: http://news.php.net/php.internals/19486)
|
||||
**To** ``internals@lists.php.net`` and ``php-general@lists.php.net`` lists
|
||||
pointing out "the location of the release" and "the possible release date of
|
||||
either the next RC, or the final release".
|
||||
|
||||
2. Send an email (see example here http://news.php.net/php.pear.qa/5201) **To**
|
||||
``php-qa@lists.php.net`` and ``primary-qa-tests@lists.php.net``.
|
||||
This email is to notify the selected projects about a new release so that they
|
||||
can make sure their projects keep working. Make sure that you have been setup
|
||||
as a moderator for ``primary-qa-tests@lists.php.net`` by having someone (Wez,
|
||||
Derick) run the following commands for you:
|
||||
|
||||
``ssh lists.php.net``
|
||||
|
||||
``sudo -u ezmlm ezmlm-sub ~ezmlm/primary-qa-tester/mod moderator-email-address``
|
||||
|
||||
3. Update ``qa.git/include/release-qa.php`` with the appropriate information.
|
||||
See the documentation within release-qa.php for more information, but all releases
|
||||
and RCs are configured here. Only $QA_RELEASES needs to be edited.
|
||||
|
||||
Example: When rolling an RC, set the 'rc' with appropriate information for the
|
||||
given version.
|
||||
|
||||
Note: Remember to update the MD5 checksum information.
|
||||
|
||||
4. Update ``php.git/include/version.inc`` (x=major version number)
|
||||
|
||||
a. ``$PHP_x_RC`` = "5.4.0RC1"
|
||||
|
||||
b. ``$PHP_x_RC_DATE`` = "06 September 2007"
|
||||
|
||||
5. Commit and push those changes:
|
||||
|
||||
a. ``git commit -a && git push origin master``
|
||||
|
||||
6. For the first RC, write the doc team (phpdoc@lists.php.net) about updating the
|
||||
INSTALL and win32/install.txt files which are generated from the PHP manual sources.
|
||||
|
||||
7. Publish the announce on www.php.net as well (for all releases, alpha, RCs or other)
|
||||
|
||||
Rolling a stable release
|
||||
------------------------
|
||||
|
||||
1. Check windows snapshot builder logs (http://snaps.php.net/win32/snapshot-STABLE.log f.e.)
|
||||
|
||||
2. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``.
|
||||
|
||||
3. **Merge** all related sections in NEWS (f.e. merge the 5.4.1RC1 and 5.4.0 sections)
|
||||
|
||||
4. Commit those changes
|
||||
|
||||
5. run the "scripts/dev/credits" script in php-src and commit the changes in the
|
||||
credits files in ext/standard.
|
||||
|
||||
6. tag the repository with the version f.e. "``git tag -s php-5.4.1``"
|
||||
(of course, you need to change that to the version you're rolling an RC for).
|
||||
When making 5.X release, you need to tag the Zend directory separately!!
|
||||
|
||||
7. Bump up the version numbers in ``main/php_version.h``, ``configure.in`` and
|
||||
possibly ``NEWS`` again, to the **next** version. F.e. if the release candidate
|
||||
was "5.4.1RC1" then the new one should be "5.4.1RC2-dev" - regardless if we get
|
||||
a new RC or not. This is to make sure ``version_compare()`` can correctly work.
|
||||
|
||||
8. Commit those changes
|
||||
|
||||
9. Log in onto the snaps box and go into the correct tree (f.e. the PHP-5.4
|
||||
branch if you're rolling 5.5.x releases).
|
||||
|
||||
10. You do not have to update the tree, but of course you can with "``git pull
|
||||
origin <branch>``".
|
||||
|
||||
11. run: ``./makedist php 5.4.1``, this will export the tree, create configure
|
||||
and build two tarballs (one gz and one bz2).
|
||||
|
||||
12. Commit those two tarballs to Git (php-distributions.git)
|
||||
|
||||
13. Once the release has been tagged, contact the PHP Windows development team
|
||||
(internals-win@lists.php.net) so that Windows binaries can be created. Once
|
||||
those are made, they should be committed to SVN too.
|
||||
|
||||
14. Check if the pear files are updated (phar for 5.1+ or run pear/make-pear-bundle.php with 4.4)
|
||||
|
||||
15. When making a final release, also remind the PHP Windows development team
|
||||
(internals-win@lists.php.net) to prepare the installer packages for Win32.
|
||||
|
||||
Getting the stable release announced
|
||||
------------------------------------
|
||||
|
||||
1. Run the bumpRelease script for phpweb on your local checkout
|
||||
|
||||
a. ``php bin/bumpRelease 5`` (or ``php bin/bumpRelease 4`` for PHP4)
|
||||
|
||||
b. In case multiple PHP minor versions are in active development you have
|
||||
to manually copy the old information to include/releases.inc
|
||||
|
||||
2. Edit ``phpweb/include/version.inc`` and change (X=major release number):
|
||||
|
||||
a. ``$PHP_X_VERSION`` to the correct version
|
||||
|
||||
b. ``$PHP_X_DATE`` to the release date
|
||||
|
||||
c. ``$PHP_X_MD5`` array and update all the md5 sums
|
||||
|
||||
d. set ``$PHP_X_RC`` to false!
|
||||
|
||||
e. Make sure there are no outdated "notes" or edited "date" keys in the
|
||||
``$RELEASES[X][$PHP_X_VERSION]["source"]`` array
|
||||
|
||||
f. if the windows builds aren't ready yet prefix the "windows" key with a dot (".windows")
|
||||
|
||||
3. Update the ChangeLog file for the given major version
|
||||
f.e. ``ChangeLog-5.php`` from the NEWS file
|
||||
|
||||
a. go over the list and put every element on one line
|
||||
|
||||
b. check for &, < and > and escape them if necessary
|
||||
|
||||
c. remove all the names at the ends of lines
|
||||
|
||||
d. for marking up, you can do the following (with VI):
|
||||
|
||||
I. ``s/^- /<li>/``
|
||||
|
||||
II. ``s/$/<\/li>/``
|
||||
|
||||
III. ``s/Fixed bug #\([0-9]\+\)/<?php bugfix(\1); ?>/``
|
||||
|
||||
IV. ``s/Fixed PECL bug #\([0-9]\+\)/<?php peclbugfix(\1); ?>/``
|
||||
|
||||
V. ``s/FR #\([0-9]\+\)/FR <?php bugl(\1); ?>/``
|
||||
|
||||
4. ``cp releases/5_4_0.php releases/5_4_1.php``
|
||||
|
||||
5. ``git add releases/5_4_1.php``
|
||||
|
||||
6. Update the ``releases/*.php`` file with relevant data. The release
|
||||
announcement file should list in detail:
|
||||
|
||||
a. security fixes,
|
||||
|
||||
b. changes in behavior (whether due to a bug fix or not)
|
||||
|
||||
7. Add a short notice to phpweb stating that there is a new release, and
|
||||
highlight the major important things (security fixes) and when it is important
|
||||
to upgrade.
|
||||
|
||||
a. Call php bin/createNewsEntry in your local phpweb checkout
|
||||
|
||||
b. Add the content for the news entry
|
||||
|
||||
8. Commit all the changes.
|
||||
|
||||
9. Wait an hour or two, then send a mail to php-announce@lists.php.net,
|
||||
php-general@lists.php.net and internals@lists.php.net with a text similar to
|
||||
http://news.php.net/php.internals/17222.
|
||||
|
||||
Re-releasing the same version (or -pl)
|
||||
--------------------------------------
|
||||
|
||||
1. Commit the new binaries to ``phpweb/distributions/``
|
||||
|
||||
2. Edit ``phpweb/include/version.inc`` and change (X=major release number):
|
||||
|
||||
a. If only releasing for one OS, make sure you edit only those variables
|
||||
|
||||
b. ``$PHP_X_VERSION`` to the correct version
|
||||
|
||||
c. ``$PHP_X_DATE`` to the release date
|
||||
|
||||
d. ``$PHP_X_MD5`` array and update all the md5 sums
|
||||
|
||||
e. Make sure there are no outdated "notes" or edited "date" keys in the
|
||||
``$RELEASES[X][$PHP_X_VERSION]["source"]`` array
|
||||
|
||||
3. Add a short notice to phpweb stating that there is a new release, and
|
||||
highlight the major important things (security fixes) and when it is important
|
||||
to upgrade.
|
||||
|
||||
a. Call php bin/createNewsEntry in your local phpweb checkout
|
||||
|
||||
b. Add the content for the news entry
|
||||
|
||||
4. Commit all the changes (``include/version.inc``, ``archive/archive.xml``,
|
||||
``archive/entries/YYYY-MM-DD-N.xml``)
|
||||
|
||||
5. Wait an hour or two, then send a mail to php-announce@lists.php.net,
|
||||
php-general@lists.php.net and internals@lists.php.net with a text similar to
|
||||
the news entry.
|
||||
@@ -1,155 +0,0 @@
|
||||
$Id$
|
||||
=============================================================================
|
||||
|
||||
HOW TO CREATE A SELF-CONTAINED PHP EXTENSION
|
||||
|
||||
A self-contained extension can be distributed independently of
|
||||
the PHP source. To create such an extension, two things are
|
||||
required:
|
||||
|
||||
- Configuration file (config.m4)
|
||||
- Source code for your module
|
||||
|
||||
We will describe now how to create these and how to put things
|
||||
together.
|
||||
|
||||
PREPARING YOUR SYSTEM
|
||||
|
||||
While the result will run on any system, a developer's setup needs these
|
||||
tools:
|
||||
|
||||
GNU autoconf
|
||||
GNU automake
|
||||
GNU libtool
|
||||
GNU m4
|
||||
|
||||
All of these are available from
|
||||
|
||||
ftp://ftp.gnu.org/pub/gnu/
|
||||
|
||||
CONVERTING AN EXISTING EXTENSION
|
||||
|
||||
Just to show you how easy it is to create a self-contained
|
||||
extension, we will convert an embedded extension into a
|
||||
self-contained one. Install PHP and execute the following
|
||||
commands.
|
||||
|
||||
$ mkdir /tmp/newext
|
||||
$ cd /tmp/newext
|
||||
|
||||
You now have an empty directory. We will copy the files from
|
||||
the mysql extension:
|
||||
|
||||
$ cp -rp php-4.0.X/ext/mysql/* .
|
||||
|
||||
It is time to finish the module. Run:
|
||||
|
||||
$ phpize
|
||||
|
||||
You can now ship the contents of the directory - the extension
|
||||
can live completely on its own.
|
||||
|
||||
The user instructions boil down to
|
||||
|
||||
$ ./configure \
|
||||
[--with-php-config=/path/to/php-config] \
|
||||
[--with-mysql=MYSQL-DIR]
|
||||
$ make install
|
||||
|
||||
The MySQL module will either use the embedded MySQL client
|
||||
library or the MySQL installation in MYSQL-DIR.
|
||||
|
||||
|
||||
DEFINING THE NEW EXTENSION
|
||||
|
||||
Our demo extension is called "foobar".
|
||||
|
||||
It consists of two source files "foo.c" and "bar.c"
|
||||
(and any arbitrary amount of header files, but that is not
|
||||
important here).
|
||||
|
||||
The demo extension does not reference any external
|
||||
libraries (that is important, because the user does not
|
||||
need to specify anything).
|
||||
|
||||
|
||||
LTLIBRARY_SOURCES specifies the names of the sources files. You can
|
||||
name an arbitrary number of source files here.
|
||||
|
||||
CREATING THE M4 CONFIGURATION FILE
|
||||
|
||||
The m4 configuration can perform additional checks. For a
|
||||
self-contained extension, you do not need more than a few
|
||||
macro calls.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
PHP_ARG_ENABLE(foobar,whether to enable foobar,
|
||||
[ --enable-foobar Enable foobar])
|
||||
|
||||
if test "$PHP_FOOBAR" != "no"; then
|
||||
PHP_NEW_EXTENSION(foobar, foo.c bar.c, $ext_shared)
|
||||
fi
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
PHP_ARG_ENABLE will automatically set the correct variables, so
|
||||
that the extension will be enabled by PHP_NEW_EXTENSION in shared mode.
|
||||
|
||||
The first argument of PHP_NEW_EXTENSION describes the name of the
|
||||
extension. The second names the source-code files. The third passes
|
||||
$ext_shared which is set by PHP_ARG_ENABLE/WITH to PHP_NEW_EXTENSION.
|
||||
|
||||
Please use always PHP_ARG_ENABLE or PHP_ARG_WITH. Even if you do not
|
||||
plan to distribute your module with PHP, these facilities allow you
|
||||
to integrate your module easily into the main PHP module framework.
|
||||
|
||||
CREATING SOURCE FILES
|
||||
|
||||
ext_skel can be of great help when creating the common code for all modules
|
||||
in PHP for you and also writing basic function definitions and C code for
|
||||
handling arguments passed to your functions. See README.EXT_SKEL for further
|
||||
information.
|
||||
|
||||
As for the rest, you are currently alone here. There are a lot of existing
|
||||
modules, use a simple module as a starting point and add your own code.
|
||||
|
||||
|
||||
CREATING THE SELF-CONTAINED EXTENSION
|
||||
|
||||
Put config.m4 and the source files into one directory. Then, run phpize
|
||||
(this is installed during make install by PHP 4.0).
|
||||
|
||||
For example, if you configured PHP with --prefix=/php, you would run
|
||||
|
||||
$ /php/bin/phpize
|
||||
|
||||
This will automatically copy the necessary build files and create
|
||||
configure from your config.m4.
|
||||
|
||||
And that's it. You now have a self-contained extension.
|
||||
|
||||
INSTALLING A SELF-CONTAINED EXTENSION
|
||||
|
||||
An extension can be installed by running:
|
||||
|
||||
$ ./configure \
|
||||
[--with-php-config=/path/to/php-config]
|
||||
$ make install
|
||||
|
||||
ADDING SHARED MODULE SUPPORT TO A MODULE
|
||||
|
||||
In order to be useful, a self-contained extension must be loadable
|
||||
as a shared module. I will explain now how you can add shared module
|
||||
support to an existing module called foo.
|
||||
|
||||
1. In config.m4, use PHP_ARG_WITH/PHP_ARG_ENABLE. Then you will
|
||||
automatically be able to use --with-foo=shared[,..] or
|
||||
--enable-foo=shared[,..].
|
||||
|
||||
2. In config.m4, use PHP_NEW_EXTENSION(foo,.., $ext_shared) to enable
|
||||
building the extension.
|
||||
|
||||
3. Add the following lines to your C source file:
|
||||
|
||||
#ifdef COMPILE_DL_FOO
|
||||
ZEND_GET_MODULE(foo)
|
||||
#endif
|
||||
-379
@@ -1,379 +0,0 @@
|
||||
An Overview of the PHP Streams abstraction
|
||||
==========================================
|
||||
$Id$
|
||||
|
||||
WARNING: some prototypes in this file are out of date.
|
||||
The information contained here is being integrated into
|
||||
the PHP manual - stay tuned...
|
||||
|
||||
Please send comments to: Wez Furlong <wez@thebrainroom.com>
|
||||
|
||||
Why Streams?
|
||||
============
|
||||
You may have noticed a shed-load of issock parameters flying around the PHP
|
||||
code; we don't want them - they are ugly and cumbersome and force you to
|
||||
special case sockets and files every time you need to work with a "user-level"
|
||||
PHP file pointer.
|
||||
Streams take care of that and present the PHP extension coder with an ANSI
|
||||
stdio-alike API that looks much nicer and can be extended to support non file
|
||||
based data sources.
|
||||
|
||||
Using Streams
|
||||
=============
|
||||
Streams use a php_stream* parameter just as ANSI stdio (fread etc.) use a
|
||||
FILE* parameter.
|
||||
|
||||
The main functions are:
|
||||
|
||||
PHPAPI size_t php_stream_read(php_stream * stream, char * buf, size_t count);
|
||||
PHPAPI size_t php_stream_write(php_stream * stream, const char * buf, size_t
|
||||
count);
|
||||
PHPAPI size_t php_stream_printf(php_stream * stream TSRMLS_DC,
|
||||
const char * fmt, ...);
|
||||
PHPAPI int php_stream_eof(php_stream * stream);
|
||||
PHPAPI int php_stream_getc(php_stream * stream);
|
||||
PHPAPI char *php_stream_gets(php_stream * stream, char *buf, size_t maxlen);
|
||||
PHPAPI int php_stream_close(php_stream * stream);
|
||||
PHPAPI int php_stream_flush(php_stream * stream);
|
||||
PHPAPI int php_stream_seek(php_stream * stream, off_t offset, int whence);
|
||||
PHPAPI off_t php_stream_tell(php_stream * stream);
|
||||
PHPAPI int php_stream_lock(php_stream * stream, int mode);
|
||||
|
||||
These (should) behave in the same way as the ANSI stdio functions with similar
|
||||
names: fread, fwrite, fprintf, feof, fgetc, fgets, fclose, fflush, fseek, ftell, flock.
|
||||
|
||||
Opening Streams
|
||||
===============
|
||||
In most cases, you should use this API:
|
||||
|
||||
PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode,
|
||||
int options, char **opened_path TSRMLS_DC);
|
||||
|
||||
Where:
|
||||
path is the file or resource to open.
|
||||
mode is the stdio compatible mode eg: "wb", "rb" etc.
|
||||
options is a combination of the following values:
|
||||
IGNORE_PATH (default) - don't use include path to search for the file
|
||||
USE_PATH - use include path to search for the file
|
||||
IGNORE_URL - do not use plugin wrappers
|
||||
REPORT_ERRORS - show errors in a standard format if something
|
||||
goes wrong.
|
||||
STREAM_MUST_SEEK - If you really need to be able to seek the stream
|
||||
and don't need to be able to write to the original
|
||||
file/URL, use this option to arrange for the stream
|
||||
to be copied (if needed) into a stream that can
|
||||
be seek()ed.
|
||||
|
||||
opened_path is used to return the path of the actual file opened,
|
||||
but if you used STREAM_MUST_SEEK, may not be valid. You are
|
||||
responsible for efree()ing opened_path. opened_path may be (and usually
|
||||
is) NULL.
|
||||
|
||||
If you need to open a specific stream, or convert standard resources into
|
||||
streams there are a range of functions to do this defined in php_streams.h.
|
||||
A brief list of the most commonly used functions:
|
||||
|
||||
PHPAPI php_stream *php_stream_fopen_from_file(FILE *file, const char *mode);
|
||||
Convert a FILE * into a stream.
|
||||
|
||||
PHPAPI php_stream *php_stream_fopen_tmpfile(void);
|
||||
Open a FILE * with tmpfile() and convert into a stream.
|
||||
|
||||
PHPAPI php_stream *php_stream_fopen_temporary_file(const char *dir,
|
||||
const char *pfx, char **opened_path TSRMLS_DC);
|
||||
Generate a temporary file name and open it.
|
||||
|
||||
There are some network enabled relatives in php_network.h:
|
||||
|
||||
PHPAPI php_stream *php_stream_sock_open_from_socket(int socket, int persistent);
|
||||
Convert a socket into a stream.
|
||||
|
||||
PHPAPI php_stream *php_stream_sock_open_host(const char *host, unsigned short port,
|
||||
int socktype, int timeout, int persistent);
|
||||
Open a connection to a host and return a stream.
|
||||
|
||||
PHPAPI php_stream *php_stream_sock_open_unix(const char *path, int persistent,
|
||||
struct timeval *timeout);
|
||||
Open a UNIX domain socket.
|
||||
|
||||
|
||||
Stream Utilities
|
||||
================
|
||||
|
||||
If you need to copy some data from one stream to another, you will be please
|
||||
to know that the streams API provides a standard way to do this:
|
||||
|
||||
PHPAPI size_t php_stream_copy_to_stream(php_stream *src,
|
||||
php_stream *dest, size_t maxlen);
|
||||
|
||||
If you want to copy all remaining data from the src stream, pass
|
||||
PHP_STREAM_COPY_ALL as the maxlen parameter, otherwise maxlen indicates the
|
||||
number of bytes to copy.
|
||||
This function will try to use mmap where available to make the copying more
|
||||
efficient.
|
||||
|
||||
If you want to read the contents of a stream into an allocated memory buffer,
|
||||
you should use:
|
||||
|
||||
PHPAPI size_t php_stream_copy_to_mem(php_stream *src, char **buf,
|
||||
size_t maxlen, int persistent);
|
||||
|
||||
This function will set buf to the address of the buffer that it allocated,
|
||||
which will be maxlen bytes in length, or will be the entire length of the
|
||||
data remaining on the stream if you set maxlen to PHP_STREAM_COPY_ALL.
|
||||
The buffer is allocated using pemalloc(); you need to call pefree() to
|
||||
release the memory when you are done.
|
||||
As with copy_to_stream, this function will try use mmap where it can.
|
||||
|
||||
If you have an existing stream and need to be able to seek() it, you
|
||||
can use this function to copy the contents into a new stream that can
|
||||
be seek()ed:
|
||||
|
||||
PHPAPI int php_stream_make_seekable(php_stream *origstream, php_stream **newstream);
|
||||
|
||||
It returns one of the following values:
|
||||
#define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */
|
||||
#define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */
|
||||
#define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */
|
||||
#define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */
|
||||
|
||||
make_seekable will always set newstream to be the stream that is valid
|
||||
if the function succeeds.
|
||||
When you have finished, remember to close the stream.
|
||||
|
||||
NOTE: If you only need to seek forward, there is no need to call this
|
||||
function, as the php_stream_seek can emulate forward seeking when the
|
||||
whence parameter is SEEK_CUR.
|
||||
|
||||
NOTE: Writing to the stream may not affect the original source, so it
|
||||
only makes sense to use this for read-only use.
|
||||
|
||||
NOTE: If the origstream is network based, this function will block
|
||||
until the whole contents have been downloaded.
|
||||
|
||||
NOTE: Never call this function with an origstream that is referenced
|
||||
as a resource! It will close the origstream on success, and this
|
||||
can lead to a crash when the resource is later used/released.
|
||||
|
||||
NOTE: If you are opening a stream and need it to be seekable, use the
|
||||
STREAM_MUST_SEEK option to php_stream_open_wrapper();
|
||||
|
||||
PHPAPI int php_stream_supports_lock(php_stream * stream);
|
||||
|
||||
This function will return either 1 (success) or 0 (failure) indicating whether or
|
||||
not a lock can be set on this stream. Typically you can only set locks on stdio streams.
|
||||
|
||||
Casting Streams
|
||||
===============
|
||||
What if your extension needs to access the FILE* of a user level file pointer?
|
||||
You need to "cast" the stream into a FILE*, and this is how you do it:
|
||||
|
||||
FILE * fp;
|
||||
php_stream * stream; /* already opened */
|
||||
|
||||
if (php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void*)&fp, REPORT_ERRORS) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
The prototype is:
|
||||
|
||||
PHPAPI int php_stream_cast(php_stream * stream, int castas, void ** ret, int
|
||||
show_err);
|
||||
|
||||
The show_err parameter, if non-zero, will cause the function to display an
|
||||
appropriate error message of type E_WARNING if the cast fails.
|
||||
|
||||
castas can be one of the following values:
|
||||
PHP_STREAM_AS_STDIO - a stdio FILE*
|
||||
PHP_STREAM_AS_FD - a generic file descriptor
|
||||
PHP_STREAM_AS_SOCKETD - a socket descriptor
|
||||
|
||||
If you ask a socket stream for a FILE*, the abstraction will use fdopen to
|
||||
create it for you. Be warned that doing so may cause buffered data to be lost
|
||||
if you mix ANSI stdio calls on the FILE* with php stream calls on the stream.
|
||||
|
||||
If your system has the fopencookie function, php streams can synthesize a
|
||||
FILE* on top of any stream, which is useful for SSL sockets, memory based
|
||||
streams, data base streams etc. etc.
|
||||
|
||||
In situations where this is not desirable, you should query the stream
|
||||
to see if it naturally supports FILE *. You can use this code snippet
|
||||
for this purpose:
|
||||
|
||||
if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) {
|
||||
/* can safely cast to FILE* with no adverse side effects */
|
||||
}
|
||||
|
||||
You can use:
|
||||
|
||||
PHPAPI int php_stream_can_cast(php_stream * stream, int castas)
|
||||
|
||||
to find out if a stream can be cast, without actually performing the cast, so
|
||||
to check if a stream is a socket you might use:
|
||||
|
||||
if (php_stream_can_cast(stream, PHP_STREAM_AS_SOCKETD) == SUCCESS) {
|
||||
/* it can be a socket */
|
||||
}
|
||||
|
||||
Please note the difference between php_stream_is and php_stream_can_cast;
|
||||
stream_is tells you if the stream is a particular type of stream, whereas
|
||||
can_cast tells you if the stream can be forced into the form you request.
|
||||
The former doesn't change anything, while the later *might* change some
|
||||
state in the stream.
|
||||
|
||||
Stream Internals
|
||||
================
|
||||
|
||||
There are two main structures associated with a stream - the php_stream
|
||||
itself, which holds some state information (and possibly a buffer) and a
|
||||
php_stream_ops structure, which holds the "virtual method table" for the
|
||||
underlying implementation.
|
||||
|
||||
The php_streams ops struct consists of pointers to methods that implement
|
||||
read, write, close, flush, seek, gets and cast operations. Of these, an
|
||||
implementation need only implement write, read, close and flush. The gets
|
||||
method is intended to be used for streams if there is an underlying method
|
||||
that can efficiently behave as fgets. The ops struct also contains a label
|
||||
for the implementation that will be used when printing error messages - the
|
||||
stdio implementation has a label of "STDIO" for example.
|
||||
|
||||
The idea is that a stream implementation defines a php_stream_ops struct, and
|
||||
associates it with a php_stream using php_stream_alloc.
|
||||
|
||||
As an example, the php_stream_fopen() function looks like this:
|
||||
|
||||
PHPAPI php_stream * php_stream_fopen(const char * filename, const char * mode)
|
||||
{
|
||||
FILE * fp = fopen(filename, mode);
|
||||
php_stream * ret;
|
||||
|
||||
if (fp) {
|
||||
ret = php_stream_alloc(&php_stream_stdio_ops, fp, 0, 0, mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
php_stream_stdio_ops is a php_stream_ops structure that can be used to handle
|
||||
FILE* based streams.
|
||||
|
||||
A socket based stream would use code similar to that above to create a stream
|
||||
to be passed back to fopen_wrapper (or it's yet to be implemented successor).
|
||||
|
||||
The prototype for php_stream_alloc is this:
|
||||
|
||||
PHPAPI php_stream * php_stream_alloc(php_stream_ops * ops, void * abstract,
|
||||
size_t bufsize, int persistent, const char * mode)
|
||||
|
||||
ops is a pointer to the implementation,
|
||||
abstract holds implementation specific data that is relevant to this instance
|
||||
of the stream,
|
||||
bufsize is the size of the buffer to use - if 0, then buffering at the stream
|
||||
level will be disabled (recommended for underlying sources that implement
|
||||
their own buffering - such a FILE*),
|
||||
persistent controls how the memory is to be allocated - persistently so that
|
||||
it lasts across requests, or non-persistently so that it is freed at the end
|
||||
of a request (it uses pemalloc),
|
||||
mode is the stdio-like mode of operation - php streams places no real meaning
|
||||
in the mode parameter, except that it checks for a 'w' in the string when
|
||||
attempting to write (this may change).
|
||||
|
||||
The mode parameter is passed on to fdopen/fopencookie when the stream is cast
|
||||
into a FILE*, so it should be compatible with the mode parameter of fopen().
|
||||
|
||||
Writing your own stream implementation
|
||||
======================================
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
RULE #1: when writing your own streams: make sure you have configured PHP with
|
||||
--enable-debug.
|
||||
I've taken some great pains to hook into the Zend memory manager to help track
|
||||
down allocation problems. It will also help you spot incorrect use of the
|
||||
STREAMS_DC, STREAMS_CC and the semi-private STREAMS_REL_CC macros for function
|
||||
definitions.
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
RULE #2: Please use the stdio stream as a reference; it will help you
|
||||
understand the semantics of the stream operations, and it will always
|
||||
be more up to date than these docs :-)
|
||||
|
||||
First, you need to figure out what data you need to associate with the
|
||||
php_stream. For example, you might need a pointer to some memory for memory
|
||||
based streams, or if you were making a stream to read data from an RDBMS like
|
||||
MySQL, you might want to store the connection and rowset handles.
|
||||
|
||||
The stream has a field called abstract that you can use to hold this data.
|
||||
If you need to store more than a single field of data, define a structure to
|
||||
hold it, allocate it (use pemalloc with the persistent flag set
|
||||
appropriately), and use the abstract pointer to refer to it.
|
||||
|
||||
For structured state you might have this:
|
||||
|
||||
struct my_state {
|
||||
MYSQL conn;
|
||||
MYSQL_RES * result;
|
||||
};
|
||||
|
||||
struct my_state * state = pemalloc(sizeof(struct my_state), persistent);
|
||||
|
||||
/* initialize the connection, and run a query, using the fields in state to
|
||||
* hold the results */
|
||||
|
||||
state->result = mysql_use_result(&state->conn);
|
||||
|
||||
/* now allocate the stream itself */
|
||||
stream = php_stream_alloc(&my_ops, state, 0, persistent, "r");
|
||||
|
||||
/* now stream->abstract == state */
|
||||
|
||||
Once you have that part figured out, you can write your implementation and
|
||||
define the your own php_stream_ops struct (we called it my_ops in the above
|
||||
example).
|
||||
|
||||
For example, for reading from this weird MySQL stream:
|
||||
|
||||
static size_t php_mysqlop_read(php_stream * stream, char * buf, size_t count)
|
||||
{
|
||||
struct my_state * state = (struct my_state*)stream->abstract;
|
||||
|
||||
if (buf == NULL && count == 0) {
|
||||
/* in this special case, php_streams is asking if we have reached the
|
||||
* end of file */
|
||||
if (... at end of file ...)
|
||||
return EOF;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* pull out some data from the stream and put it in buf */
|
||||
... mysql_fetch_row(state->result) ...
|
||||
/* we could do something strange, like format the data as XML here,
|
||||
and place that in the buf, but that brings in some complexities,
|
||||
such as coping with a buffer size too small to hold the data,
|
||||
so I won't even go in to how to do that here */
|
||||
}
|
||||
|
||||
Implement the other operations - remember that write, read, close and flush
|
||||
are all mandatory. The rest are optional. Declare your stream ops struct:
|
||||
|
||||
php_stream_ops my_ops = {
|
||||
php_mysqlop_write, php_mysqlop_read, php_mysqlop_close,
|
||||
php_mysqlop_flush, NULL, NULL, NULL,
|
||||
"Strange MySQL example"
|
||||
}
|
||||
|
||||
Thats it!
|
||||
|
||||
Take a look at the STDIO implementation in streams.c for more information
|
||||
about how these operations work.
|
||||
The main thing to remember is that in your close operation you need to release
|
||||
and free the resources you allocated for the abstract field. In the case of
|
||||
the example above, you need to use mysql_free_result on the rowset, close the
|
||||
connection and then use pefree to dispose of the struct you allocated.
|
||||
You may read the stream->persistent field to determine if your struct was
|
||||
allocated in persistent mode or not.
|
||||
|
||||
vim:tw=78:et
|
||||
@@ -1,182 +0,0 @@
|
||||
Submitting Enhancements and Patches to PHP
|
||||
==========================================
|
||||
|
||||
This document describes how to submit an enhancement or patch for PHP.
|
||||
It's easy!
|
||||
|
||||
You don't need any login accounts or special access to download,
|
||||
build, debug and begin submitting PHP, PECL or PEAR code, tests or
|
||||
documentation. Once you've followed this README and had several
|
||||
patches accepted, commit privileges are often quickly granted.
|
||||
|
||||
An excellent article to read first is:
|
||||
http://phpadvent.org/2008/less-whining-more-coding-by-elizabeth-smith
|
||||
|
||||
|
||||
Online Forums
|
||||
-------------
|
||||
There are several IRC channels where PHP developers are often
|
||||
available to discuss questions. They include #php.pecl, #php.doc and
|
||||
#pear on the EFNet network and #php-dev-win on FreeNode.
|
||||
|
||||
|
||||
PHP Patches
|
||||
-----------
|
||||
If you are fixing broken functionality in PHP C source code first
|
||||
create a bug or identify an existing bug at http://bugs.php.net/. A
|
||||
bug can be used to track the patch progress and prevent your changes
|
||||
getting lost in the PHP mail archives.
|
||||
|
||||
If your change is large then create a Request For Comment (RFC) page
|
||||
on http://wiki.php.net/rfc, discuss it with the extension maintainer,
|
||||
and discuss it on the development mail list internals@lists.php.net.
|
||||
RFC Wiki accounts can be requested on
|
||||
http://wiki.php.net/start?do=register. PHP extension maintainers can
|
||||
be found in the EXTENSIONS file in the PHP source. Mail list
|
||||
subscription is explained on http://www.php.net/mailing-lists.php.
|
||||
|
||||
Information on PHP internal C functions is at
|
||||
http://www.php.net/internals, though this is considered incomplete.
|
||||
Various external resources can be found on the web. A standard
|
||||
printed reference is the book "Extending and Embedding PHP" by Sara
|
||||
Golemon.
|
||||
|
||||
Attach the patch to the PHP bug and consider sending a notification
|
||||
email about the change to internals@lists.php.net. Also CC the
|
||||
extension maintainer. Explain what has been changed by your patch.
|
||||
Test scripts should be included.
|
||||
|
||||
Please make the mail subject prefix "[PATCH]". If attaching a patch,
|
||||
ensure it has a file extension of ".txt". This is because only MIME
|
||||
attachments of type 'text/*' are accepted.
|
||||
|
||||
|
||||
PHP Documentation Patches
|
||||
-------------------------
|
||||
If you are fixing incorrect PHP documentation first create a bug or
|
||||
identify an existing bug at http://bugs.php.net/. A bug can be used
|
||||
to track the patch progress and prevent your changes getting lost in
|
||||
the PHP mail archives.
|
||||
|
||||
If your change is large, then first discuss it with the mail list
|
||||
phpdoc@lists.php.net. Subscription is explained on
|
||||
http://www.php.net/mailing-lists.php.
|
||||
|
||||
Information on contributing to PHP documentation is at
|
||||
http://php.net/dochowto and http://wiki.php.net/doc/howto
|
||||
|
||||
Attach the patch to the PHP bug and consider sending a notification
|
||||
email about the change to phpdoc@lists.php.net. Explain what has been
|
||||
fixed/added/changed by your patch.
|
||||
|
||||
Please make the mail subject prefix "[PATCH]". Include the bug id(s)
|
||||
which can be closed by your patch. If attaching a patch, ensure it
|
||||
has a file extension of ".txt". This is because only MIME attachments
|
||||
of type 'text/*' are accepted.
|
||||
|
||||
|
||||
PECL Extension Patches: http://pecl.php.net/
|
||||
--------------------------------------------
|
||||
If you are fixing broken functionality in a PECL extension then create
|
||||
a bug or identify an existing bug at http://pecl.php.net/bugs/. A bug
|
||||
can be used to track the patch progress and prevent your changes
|
||||
getting lost in the PHP mail archives.
|
||||
|
||||
If your change is large then create a Request For Comment (RFC) page
|
||||
on http://wiki.php.net/rfc, discuss it with the extension maintainer,
|
||||
and discuss it on the development mail list pecl-dev@lists.php.net.
|
||||
PECL mail list subscription is explained on
|
||||
http://pecl.php.net/support.php. RFC Wiki accounts can be requested
|
||||
on http://wiki.php.net/start?do=register
|
||||
|
||||
Information on PHP internal C functions is at
|
||||
http://www.php.net/internals, though this is considered incomplete.
|
||||
Various external resources can be found on the web. A standard
|
||||
printed reference is the book "Extending and Embedding PHP" by Sara
|
||||
Golemon.
|
||||
|
||||
Update any open bugs and add a link to the source of your patch. Send
|
||||
the patch or pointer to the bug to pecl-dev@lists.php.net. Also CC
|
||||
the extension maintainer. Explain what has been changed by your
|
||||
patch. Test scripts should be included.
|
||||
|
||||
Please make the mail subject prefix "[PATCH] ...". Include the patch
|
||||
as an attachment with a file extension of ".txt". This is because
|
||||
only MIME attachments of type 'text/*' are accepted.
|
||||
|
||||
|
||||
PEAR Package Patches: http://pear.php.net/
|
||||
------------------------------------------
|
||||
Information on contributing to PEAR is available at
|
||||
http://pear.php.net/manual/en/developers-newmaint.php and
|
||||
http://pear.php.net/manual/en/guide-developers.php
|
||||
|
||||
|
||||
How to create your PHP, PHP Documentation or PECL patch
|
||||
-------------------------------------------------------
|
||||
PHP and PECL use Subversion (SVN) for revision control. Read
|
||||
http://www.php.net/svn.php for help on using SVN to get and build PHP
|
||||
source code. We recommend using a Sparse Directory checkout described
|
||||
in http://wiki.php.net/vcs/svnfaq. If you are new to SVN, read
|
||||
http://svnbook.red-bean.com.
|
||||
|
||||
Generally we ask that bug fix patches work on the current stable PHP
|
||||
development branches and on "trunk". New PHP features only need to
|
||||
work on "trunk".
|
||||
|
||||
Read CODING_STANDARDS before you start working.
|
||||
|
||||
After modifying the source see README.TESTING and
|
||||
http://qa.php.net/write-test.php for how to test. Submitting test
|
||||
scripts helps us to understand what functionality has changed. It is
|
||||
important for the stability and maintainability of PHP that tests are
|
||||
comprehensive.
|
||||
|
||||
After testing is finished, create a patch file using the command:
|
||||
|
||||
svn diff > your_patch.txt
|
||||
|
||||
For ease of review and later troubleshooting, submit individual
|
||||
patches for each bug or feature.
|
||||
|
||||
|
||||
Checklist for submitting your PHP or PECL code patch
|
||||
----------------------------------------------------
|
||||
- Update SVN source just before running your final 'diff' and
|
||||
before testing.
|
||||
- Add in-line comments and/or have external documentation ready.
|
||||
Use only "/* */" style comments, not "//".
|
||||
- Create test scripts for use with "make test".
|
||||
- Run "make test" to check your patch doesn't break other features.
|
||||
- Rebuild PHP with --enable-debug (which will show some kinds of
|
||||
memory errors) and check the PHP and web server error logs after
|
||||
running your PHP tests.
|
||||
- Rebuild PHP with --enable-maintainer-zts to check your patch
|
||||
compiles on multi-threaded web servers.
|
||||
- Review the patch once more just before submitting it.
|
||||
|
||||
|
||||
What happens after submitting your PHP, PHP Documentation or PECL patch
|
||||
-----------------------------------------------------------------------
|
||||
If your patch is easy to review and obviously has no side-effects,
|
||||
it might be committed relatively quickly.
|
||||
|
||||
Because PHP is a volunteer-driven effort more complex patches will
|
||||
require patience on your side. If you do not receive feedback in a
|
||||
few days, consider resubmitting the patch. Before doing this think
|
||||
about these questions:
|
||||
|
||||
- Did I send the patch to the right mail list?
|
||||
- Did I review the mail list archives to see if these kind of
|
||||
changes had been discussed before?
|
||||
- Did I explain my patch clearly?
|
||||
- Is my patch too hard to review? Because of what factors?
|
||||
|
||||
|
||||
What happens when your PHP or PECL patch is applied
|
||||
---------------------------------------------------
|
||||
Your name will likely be included in the SVN commit log. If your
|
||||
patch affects end users, a brief description and your name might be
|
||||
added to the NEWS file.
|
||||
|
||||
Thank you for patching PHP!
|
||||
-180
@@ -1,180 +0,0 @@
|
||||
[IMPORTANT NOTICE]
|
||||
------------------
|
||||
Failed tests usualy indicate a problem with your local system setup
|
||||
and not within PHP itself (at least for official PHP release versions).
|
||||
You may decide to automaticaly submit a test summary to our QA workflow
|
||||
at the end of a test run.
|
||||
Please do *not* submit a failed test as a bug or ask for help on why
|
||||
it failed on your system without providing substantial backup information
|
||||
on *why* the test failed on your special setup. Thank you :-)
|
||||
|
||||
|
||||
[Testing Basics]
|
||||
----------------
|
||||
The easiest way to test your PHP build is to run "make test" from the
|
||||
command line after successfully compiling. This will run the complete
|
||||
tests for all enabled functionalities and extensions using the PHP
|
||||
CLI binary.
|
||||
To execute test scripts, you must build PHP with some SAPI, then you
|
||||
type "make test" to execute all or some test scripts saved under
|
||||
"tests" directory under source root directory.
|
||||
|
||||
Usage:
|
||||
make test
|
||||
|
||||
"make test" basically executes "run-tests.php" script
|
||||
under the source root (parallel builds will not work). Therefore you
|
||||
can execute the script as follows:
|
||||
|
||||
TEST_PHP_EXECUTABLE=sapi/cli/php \
|
||||
sapi/cli/php [-c /path/to/php.ini] run-tests.php [ext/foo/tests/GLOB]
|
||||
|
||||
|
||||
[Which "php" executable "make test" look for]
|
||||
---------------------------------------------
|
||||
If you are running the run-tests.php script from the command line (as above)
|
||||
you must set the TEST_PHP_EXECUTABLE environment variable to explicitly
|
||||
select the PHP executable that is to be tested, that is, used to run the test scripts.
|
||||
|
||||
If you run the tests using make test, the PHP CLI and CGI executables are
|
||||
automatically set for you. "make test" executes "run-tests.php" script with the CLI binary. Some
|
||||
test scripts such as session must be executed by CGI SAPI. Therefore,
|
||||
you must build PHP with CGI SAPI to perform all tests.
|
||||
|
||||
NOTE: PHP binary executing "run-tests.php" and php binary used for
|
||||
executing test scripts may differ. If you use different PHP binary for
|
||||
executing "run-tests.php" script, you may get errors.
|
||||
|
||||
|
||||
[Which php.ini is used]
|
||||
-----------------------
|
||||
"make test" uses the same php.ini file as it would once installed.
|
||||
The tests have been written to be independent of that php.ini file,
|
||||
so if you find a test that is affected by a setting, please report
|
||||
this, so we can address the issue.
|
||||
|
||||
|
||||
[Which test scripts are executed]
|
||||
---------------------------------
|
||||
"run-tests.php" ("make test"), without any arguments executes all
|
||||
test scripts by extracting all directories named "tests"
|
||||
from the source root and any subdirectories below. If there are files,
|
||||
which have a "phpt" extension, "run-tests.php" looks at the sections
|
||||
in these files, determines whether it should run it, by evaluating
|
||||
the 'SKIP' section. If the test is eligible for execution, the 'FILE'
|
||||
section is extracted into a ".php" file (with the same name besides
|
||||
the extension) and gets executed.
|
||||
When an argument is given or TESTS environment variable is set, the
|
||||
GLOB is expanded by the shell and any file with extension "*.phpt" is
|
||||
regarded as a test file.
|
||||
|
||||
Tester can easily execute tests selectively with as follows.
|
||||
|
||||
Examples:
|
||||
./sapi/cli/php run-tests.php ext/mbstring/*
|
||||
./sapi/cli/php run-tests.php ext/mbstring/020.phpt
|
||||
|
||||
|
||||
[Test results]
|
||||
--------------
|
||||
Test results are printed to standard output. If there is a failed test,
|
||||
the "run-tests.php" script saves the result, the expected result and the
|
||||
code executed to the test script directory. For example, if
|
||||
ext/myext/tests/myext.phpt fails to pass, the following files are created:
|
||||
|
||||
ext/myext/tests/myext.php - actual test file executed
|
||||
ext/myext/tests/myext.log - log of test execution (L)
|
||||
ext/myext/tests/myext.exp - expected output (E)
|
||||
ext/myext/tests/myext.out - output from test script (O)
|
||||
ext/myext/tests/myext.diff - diff of .out and .exp (D)
|
||||
|
||||
Failed tests are always bugs. Either the test is bugged or not considering
|
||||
factors applying to the tester's environment, or there is a bug in PHP.
|
||||
If this is a known bug, we strive to provide bug numbers, in either the
|
||||
test name or the file name. You can check the status of such a bug, by
|
||||
going to: http://bugs.php.net/12345 where 12345 is the bug number.
|
||||
For clarity and automated processing, bug numbers are prefixed by a hash
|
||||
sign '#' in test names and/or test cases are named bug12345.phpt.
|
||||
|
||||
NOTE: The files generated by tests can be selected by setting the
|
||||
environment variable TEST_PHP_LOG_FORMAT. For each file you want to be
|
||||
generated use the character in brackets as shown above (default is LEOD).
|
||||
The php file will be generated always.
|
||||
|
||||
NOTE: You can set environment variable TEST_PHP_DETAILED to enable
|
||||
detailed test information.
|
||||
|
||||
[Automated testing]
|
||||
If you like to keep up to speed, with latest developments and quality
|
||||
assurance, setting the environment variable NO_INTERACTION to 1, will not
|
||||
prompt the tester for any user input.
|
||||
|
||||
Normally, the exit status of "make test" is zero, regardless of the results
|
||||
of independent tests. Set the environment variable REPORT_EXIT_STATUS to 1,
|
||||
and "make test" will set the exit status ("$?") to non-zero, when an
|
||||
individual test has failed.
|
||||
|
||||
Example script to be run by cron(1):
|
||||
========== qa-test.sh =============
|
||||
#!/bin/sh
|
||||
|
||||
CO_DIR=$HOME/cvs/php5
|
||||
MYMAIL=qa-test@domain.com
|
||||
TMPDIR=/var/tmp
|
||||
TODAY=`date +"%Y%m%d"`
|
||||
|
||||
# Make sure compilation enviroment is correct
|
||||
CONFIGURE_OPTS='--disable-all --enable-cli --with-pcre'
|
||||
export MAKE=gmake
|
||||
export CC=gcc
|
||||
|
||||
# Set test environment
|
||||
export NO_INTERACTION=1
|
||||
export REPORT_EXIT_STATUS=1
|
||||
|
||||
cd $CO_DIR
|
||||
cvs update . >>$TMPDIR/phpqatest.$TODAY
|
||||
./cvsclean ; ./buildconf ; ./configure $CONFIGURE_OPTS ; $MAKE
|
||||
$MAKE test >>$TMPDIR/phpqatest.$TODAY 2>&1
|
||||
if test $? -gt 0
|
||||
then
|
||||
cat $TMPDIR/phpqatest.$TODAY | mail -s"PHP-QA Test Failed for $TODAY" $MYMAIL
|
||||
fi
|
||||
========== end of qa-test.sh =============
|
||||
|
||||
NOTE: the exit status of run-tests.php will be 1 when
|
||||
REPORT_EXIT_STATUS is set. The result of "make test" may be higher
|
||||
than that. At present, gmake 3.79.1 returns 2, so it is
|
||||
advised to test for non-zero, rather then a specific value.
|
||||
|
||||
|
||||
[Creating new test files]
|
||||
-------------------------
|
||||
Writing test file is very easy if you are used to PHP.
|
||||
See the HOWTO at http://qa.php.net/write-test.php
|
||||
|
||||
|
||||
[How to help us]
|
||||
----------------
|
||||
If you find bug in PHP, you can submit bug report AND test script
|
||||
for us. You don't have to write complete script, just give us test
|
||||
script with following format. Please test the script and make sure
|
||||
you write the correct ACTUAL OUTPUT and EXPECTED OUTPUT before you
|
||||
submit.
|
||||
|
||||
<?php
|
||||
/*
|
||||
Bug #12345
|
||||
substr() bug. Do not return expected string.
|
||||
|
||||
ACTUAL OUTPUT
|
||||
XYXA
|
||||
|
||||
EXPECTED OUTPUT
|
||||
ABCD
|
||||
*/
|
||||
|
||||
$str = "XYZABCD";
|
||||
echo substr($str,3,7);
|
||||
|
||||
?>
|
||||
-137
@@ -1,137 +0,0 @@
|
||||
[IMPORTANT NOTICE]
|
||||
------------------
|
||||
This is an addendum to README.TESTING with additional information
|
||||
specific to server-tests.php.
|
||||
|
||||
server-tests.php is backward compatible with tests developed for
|
||||
the original run-tests.php script. server-tests is *not* used by
|
||||
'make test'. server-tests was developed to provide support for
|
||||
testing PHP under it's primary environment, HTTP, and can run the
|
||||
PHP tests under any of the SAPI modules that are direct executables,
|
||||
or are accessable via HTTP.
|
||||
|
||||
[New features]
|
||||
----------------
|
||||
* Command line interface:
|
||||
You can run 'php server-tests.php -h' to get all the possible options.
|
||||
* Configuration file:
|
||||
the -c argument will allow you to use a configuration file. This is
|
||||
handy if you are testing multiple environments and need various options
|
||||
depending on the environment.
|
||||
see server-tests-config.php for details.
|
||||
* CGI Emulation:
|
||||
Will emulate a CGI environment when testing with the cgi sapi executable.
|
||||
* HTTP testing:
|
||||
can be configured to run test scripts through an HTTP server running
|
||||
on localhost. localhost is required since either the web server must
|
||||
alias a directory to the php source directory, or the test scripts
|
||||
must be copied to a directory under the web server
|
||||
(see config options TEST_WEB_BASE_URL, TEST_BASE_PATH, and TEST_WEB_EXT)
|
||||
* New sections supported for test files (see below)
|
||||
|
||||
When running tests over http, tests that require ini settings different that what
|
||||
the web server runs under will be skipped. Since the test harness defines a number
|
||||
of ini settings by default, the web server may require special configuration to
|
||||
make testing work.
|
||||
|
||||
[Example Usage]
|
||||
----------------
|
||||
Some (but not all!) examples of usage:
|
||||
|
||||
1. run tests from the php source directory
|
||||
php server-tests.php -p /path/to/php-cli
|
||||
|
||||
2. run tests using cgi emulation
|
||||
php server-tests.php -p /path/to/php-cgi
|
||||
|
||||
3. run tests over http, copying test files into document root
|
||||
php server-tests.php -w -u http://localhost/test -m /path/to/htdocs/test
|
||||
|
||||
4. run tests over http, php sources have been aliased in web server
|
||||
php server-tests.php -w -u http://localhost/test
|
||||
|
||||
5. run tests using configuration file
|
||||
php server-tests.php -c /path/to/server-tests-config.php
|
||||
|
||||
6. run tests using configuration file, but overriding some settings:
|
||||
(config file must be first)
|
||||
php server-tests.php -c /path/to/server-tests-config.php -w -t 3 -d /path/to/testdir
|
||||
|
||||
NOTE: configuration as described in README.TESTING still works.
|
||||
|
||||
[New Test Sections]
|
||||
----------------
|
||||
In addition to the traditional test sections
|
||||
(see http://qa.php.net/write-test.php), several new sections are available
|
||||
under server-tests.
|
||||
|
||||
--POST--
|
||||
This is not a new section, but not multipart posts are supported for testing
|
||||
file uploads, or other types of POST data.
|
||||
|
||||
--CGI--
|
||||
This section takes no value. It merely provides a simple marker for tests
|
||||
that MUST be run as CGI, even if there is no --POST-- or --GET-- sections
|
||||
in the test file.
|
||||
|
||||
--DESCRIPTION--
|
||||
Not used for anything, just a section for documenting the test
|
||||
|
||||
--ENV--
|
||||
This section get's eval()'d to help build an environment for the
|
||||
execution of the test. This can be used to change environment
|
||||
vars that are used for CGI emulation, or simply to set env vars
|
||||
for cli testing. A full example looks like:
|
||||
|
||||
--ENV--
|
||||
return <<<END
|
||||
PATH_TRANSLATED=$filename
|
||||
PATH_INFO=$scriptname
|
||||
SCRIPT_NAME=$scriptname
|
||||
END;
|
||||
|
||||
Some variables are made easily available for use in this section, they
|
||||
include:
|
||||
$filename full native path to file, will become PATH_TRANSLATED
|
||||
$filepath =dirname($filename)
|
||||
$scriptname this is what will become SCRIPT_NAME unless you override it
|
||||
$docroot the equivelant of DOCUMENT_ROOT under Apache
|
||||
$cwd the directory that the test is being initiated from
|
||||
$this->conf all server-tests configuration vars
|
||||
$this->env all environment variables that will get passed to the test
|
||||
|
||||
|
||||
--REQUEST--
|
||||
This section is also eval'd, and is similar in nature to --ENV--. However,
|
||||
this section is used to build the url used in an HTTP request. Valid values
|
||||
to set in this section would include:
|
||||
SCRIPT_NAME The inital part of the request url
|
||||
PATH_INFO The pathinfo part of a request url
|
||||
FRAGMENT The fragment section of a url (after #)
|
||||
QUERY_STRING The query part of a url (after ?)
|
||||
|
||||
--REQUEST--
|
||||
return <<<END
|
||||
PATH_INFO=/path/info
|
||||
END;
|
||||
|
||||
--HEADERS--
|
||||
This section is also eval'd. It is used to provide additional headers sent
|
||||
in an HTTP request, such as content type for multipart posts, cookies, etc.
|
||||
|
||||
--HEADERS--
|
||||
return <<<END
|
||||
Content-Type=multipart/form-data; boundary=---------------------------240723202011929
|
||||
Content-Length=100
|
||||
END;
|
||||
|
||||
--EXPECTHEADERS--
|
||||
This section can be used to define what headers are required to be
|
||||
received back from a request, and is checked in addition to the
|
||||
regular expect sections. For example:
|
||||
|
||||
--EXPECTHEADERS--
|
||||
Status: 404
|
||||
|
||||
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
PHP Build System V5 Overview
|
||||
|
||||
- supports Makefile.ins during transition phase
|
||||
- not-really-portable Makefile includes have been eliminated
|
||||
- supports separate build directories without VPATH by using
|
||||
explicit rules only
|
||||
- does not waste disk-space/CPU-time for building temporary libraries
|
||||
=> especially noticeable on slower systems
|
||||
- slow recursive make replaced with one global Makefile
|
||||
- eases integration of proper dependencies
|
||||
- adds PHP_DEFINE(what[, value]) which creates a single include-file
|
||||
per what. This will allow more fine-grained dependencies.
|
||||
- abandoning the "one library per directory" concept
|
||||
- improved integration of the CLI
|
||||
- several new targets
|
||||
build-modules: builds and copies dynamic modules into modules/
|
||||
install-cli: installs the CLI only, so that the install-sapi
|
||||
target does only what its name says
|
||||
- finally abandoned automake (still requires aclocal at this time)
|
||||
- changed some configure-time constructs to run at buildconf-time
|
||||
- upgraded shtool to 1.5.4
|
||||
- removed $(moduledir) (use EXTENSION_DIR)
|
||||
|
||||
The Reason For a New System
|
||||
|
||||
It became more and more apparent that there is a severe need
|
||||
for addressing the portability concerns and improving the chance
|
||||
that your build is correct (how often have you been told to
|
||||
"make clean"? When this is done, you won't need to anymore).
|
||||
|
||||
|
||||
If You Build PHP on a Unix System
|
||||
|
||||
|
||||
You, as a user of PHP, will notice no changes. Of course, the build
|
||||
system will be faster, look better and work smarter.
|
||||
|
||||
|
||||
|
||||
If You Are Developing PHP
|
||||
|
||||
|
||||
|
||||
|
||||
Extension developers:
|
||||
|
||||
Makefile.ins are abandoned. The files which are to be compiled
|
||||
are specified in the config.m4 now using the following macro:
|
||||
|
||||
PHP_NEW_EXTENSION(foo, foo.c bar.c baz.cpp, $ext_shared)
|
||||
|
||||
E.g. this enables the extension foo which consists of three source-code
|
||||
modules, two in C and one in C++. And, depending on the user's wishes,
|
||||
the extension will even be built as a dynamic module.
|
||||
|
||||
The full syntax:
|
||||
|
||||
PHP_NEW_EXTENSION(extname, sources [, shared [,sapi_class[, extra-cflags]]])
|
||||
|
||||
Please have a look at acinclude.m4 for the gory details and meanings
|
||||
of the other parameters.
|
||||
|
||||
And that's basically it for the extension side.
|
||||
|
||||
If you previously built sub-libraries for this module, add
|
||||
the source-code files here as well. If you need to specify
|
||||
separate include directories, do it this way:
|
||||
|
||||
PHP_NEW_EXTENSION(foo, foo.c mylib/bar.c mylib/gregor.c,,,-I@ext_srcdir@/lib)
|
||||
|
||||
E.g. this builds the three files which are located relative to the
|
||||
extension source directory and compiles all three files with the
|
||||
special include directive (@ext_srcdir@ is automatically replaced).
|
||||
|
||||
Now, you need to tell the build system that you want to build files
|
||||
in a directory called $ext_builddir/lib:
|
||||
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/lib)
|
||||
|
||||
Make sure to call this after PHP_NEW_EXTENSION, because $ext_builddir
|
||||
is only set by the latter.
|
||||
|
||||
If you have a complex extension, you might to need add special
|
||||
Make rules. You can do this by calling PHP_ADD_MAKEFILE_FRAGMENT
|
||||
in your config.m4 after PHP_NEW_EXTENSION.
|
||||
|
||||
This will read a file in the source-dir of your extension called
|
||||
Makefile.frag. In this file, $(builddir) and $(srcdir) will be
|
||||
replaced by the values which are correct for your extension
|
||||
and which are again determined by the PHP_NEW_EXTENSION macro.
|
||||
|
||||
Make sure to prefix *all* relative paths correctly with either
|
||||
$(builddir) or $(srcdir). Because the build system does not
|
||||
change the working directory anymore, we must use either
|
||||
absolute paths or relative ones to the top build-directory.
|
||||
Correct prefixing ensures that.
|
||||
|
||||
|
||||
SAPI developers:
|
||||
|
||||
Instead of using PHP_SAPI=foo/PHP_BUILD_XYZ, you will need to type
|
||||
|
||||
PHP_SELECT_SAPI(name, type, sources.c)
|
||||
|
||||
I.e. specify the source-code files as above and also pass the
|
||||
information regarding how PHP is supposed to be built (shared
|
||||
module, program, etc).
|
||||
|
||||
For example for APXS:
|
||||
|
||||
PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php5.c php_apache.c)
|
||||
|
||||
|
||||
|
||||
General info
|
||||
|
||||
The foundation for the new system is the flexible handling of
|
||||
sources and their contexts. With the help of macros you
|
||||
can define special flags for each source-file, where it is
|
||||
located, in which target context it can work, etc.
|
||||
|
||||
Have a look at the well documented macros
|
||||
PHP_ADD_SOURCES(_X) in acinclude.m4.
|
||||
@@ -1,6 +0,0 @@
|
||||
The Win32 Build System.
|
||||
|
||||
See http://wiki.php.net/internals/windows/stepbystepbuild
|
||||
|
||||
vim:tw=78:sw=1:ts=1:et
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
Input Filter Support in PHP 5
|
||||
-----------------------------
|
||||
|
||||
XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
|
||||
and can be quite difficult to prevent. Whenever you accept user data
|
||||
and somehow display this data back to users, you are likely vulnerable
|
||||
to XSS hacks.
|
||||
|
||||
The Input Filter support in PHP 5 is aimed at providing the framework
|
||||
through which a company-wide or site-wide security policy can be
|
||||
enforced. It is implemented as a SAPI hook and is called from the
|
||||
treat_data and post handler functions. To implement your own security
|
||||
policy you will need to write a standard PHP extension. There is also
|
||||
a powerful standard implementation in ext/filter that should suit most
|
||||
peoples' needs. However, if you want to implement your own security
|
||||
policy, read on.
|
||||
|
||||
A simple implementation might look like the following. This stores the
|
||||
original raw user data and adds a my_get_raw() function while the normal
|
||||
$_POST, $_GET and $_COOKIE arrays are only populated with stripped
|
||||
data. In this simple example all I am doing is calling strip_tags() on
|
||||
the data.
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
|
||||
zval *post_array;
|
||||
zval *get_array;
|
||||
zval *cookie_array;
|
||||
ZEND_END_MODULE_GLOBALS(my_input_filter)
|
||||
|
||||
#ifdef ZTS
|
||||
#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
|
||||
#else
|
||||
#define IF_G(v) (my_input_filter_globals.v)
|
||||
#endif
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
|
||||
|
||||
zend_function_entry my_input_filter_functions[] = {
|
||||
PHP_FE(my_get_raw, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
zend_module_entry my_input_filter_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"my_input_filter",
|
||||
my_input_filter_functions,
|
||||
PHP_MINIT(my_input_filter),
|
||||
PHP_MSHUTDOWN(my_input_filter),
|
||||
NULL,
|
||||
PHP_RSHUTDOWN(my_input_filter),
|
||||
PHP_MINFO(my_input_filter),
|
||||
"0.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
|
||||
PHP_MINIT_FUNCTION(my_input_filter)
|
||||
{
|
||||
ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
|
||||
|
||||
REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
sapi_register_input_filter(my_sapi_input_filter);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
PHP_RSHUTDOWN_FUNCTION(my_input_filter)
|
||||
{
|
||||
if(IF_G(get_array)) {
|
||||
zval_ptr_dtor(&IF_G(get_array));
|
||||
IF_G(get_array) = NULL;
|
||||
}
|
||||
if(IF_G(post_array)) {
|
||||
zval_ptr_dtor(&IF_G(post_array));
|
||||
IF_G(post_array) = NULL;
|
||||
}
|
||||
if(IF_G(cookie_array)) {
|
||||
zval_ptr_dtor(&IF_G(cookie_array));
|
||||
IF_G(cookie_array) = NULL;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
PHP_MINFO_FUNCTION(my_input_filter)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
|
||||
php_info_print_table_row( 2, "Revision", "$Id$");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
|
||||
/* The filter handler. If you return 1 from it, then PHP also registers the
|
||||
* (modified) variable. Returning 0 prevents PHP from registering the variable;
|
||||
* you can use this if your filter already registers the variable under a
|
||||
* different name, or if you just don't want the variable registered at all. */
|
||||
SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
|
||||
{
|
||||
zval new_var;
|
||||
zval *array_ptr = NULL;
|
||||
char *raw_var;
|
||||
int var_len;
|
||||
|
||||
assert(*val != NULL);
|
||||
|
||||
switch(arg) {
|
||||
case PARSE_GET:
|
||||
if(!IF_G(get_array)) {
|
||||
ALLOC_ZVAL(array_ptr);
|
||||
array_init(array_ptr);
|
||||
INIT_PZVAL(array_ptr);
|
||||
}
|
||||
IF_G(get_array) = array_ptr;
|
||||
break;
|
||||
case PARSE_POST:
|
||||
if(!IF_G(post_array)) {
|
||||
ALLOC_ZVAL(array_ptr);
|
||||
array_init(array_ptr);
|
||||
INIT_PZVAL(array_ptr);
|
||||
}
|
||||
IF_G(post_array) = array_ptr;
|
||||
break;
|
||||
case PARSE_COOKIE:
|
||||
if(!IF_G(cookie_array)) {
|
||||
ALLOC_ZVAL(array_ptr);
|
||||
array_init(array_ptr);
|
||||
INIT_PZVAL(array_ptr);
|
||||
}
|
||||
IF_G(cookie_array) = array_ptr;
|
||||
break;
|
||||
}
|
||||
Z_STRLEN(new_var) = val_len;
|
||||
Z_STRVAL(new_var) = estrndup(*val, val_len);
|
||||
Z_TYPE(new_var) = IS_STRING;
|
||||
|
||||
var_len = strlen(var);
|
||||
raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
|
||||
strcpy(raw_var, "RAW_");
|
||||
strlcat(raw_var,var,var_len+5);
|
||||
|
||||
php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
|
||||
|
||||
php_strip_tags(*val, val_len, NULL, NULL, 0);
|
||||
|
||||
*new_val_len = strlen(*val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
PHP_FUNCTION(my_get_raw)
|
||||
{
|
||||
long arg;
|
||||
char *var;
|
||||
int var_len;
|
||||
zval **tmp;
|
||||
zval *array_ptr = NULL;
|
||||
|
||||
if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(arg) {
|
||||
case PARSE_GET:
|
||||
array_ptr = IF_G(get_array);
|
||||
break;
|
||||
case PARSE_POST:
|
||||
array_ptr = IF_G(post_array);
|
||||
break;
|
||||
case PARSE_COOKIE:
|
||||
array_ptr = IF_G(post_array);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!array_ptr) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if(zend_hash_find(HASH_OF(array_ptr), var, var_len+5, (void **)&tmp) == SUCCESS) {
|
||||
*return_value = **tmp;
|
||||
zval_copy_ctor(return_value);
|
||||
} else {
|
||||
RETVAL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
Design
|
||||
======
|
||||
|
||||
Main assumption of the model is that the problem that we are to solve is the
|
||||
problem of the very long class names in PHP libraries. We would not attempt
|
||||
to take autoloader's job or create packaging model - only make names
|
||||
manageable.
|
||||
|
||||
Namespaces are defined the following way:
|
||||
|
||||
Zend/DB/Connection.php:
|
||||
<?php
|
||||
namespace Zend\DB;
|
||||
|
||||
class Connection {
|
||||
}
|
||||
|
||||
function connect() {
|
||||
}
|
||||
?>
|
||||
|
||||
Namespace definition does the following:
|
||||
All class and function names inside are automatically prefixed with
|
||||
namespace name. Inside namespace, local name always takes precedence over
|
||||
global name. Several files may be using the same namespace.
|
||||
The namespace declaration statement must be the very first statement in
|
||||
the file. The only exception is "declare" statement that can be used before.
|
||||
|
||||
Every class and function in a namespace can be referred to by the full name
|
||||
- e.g. Zend\DB\Connection or Zend\DB\connect - at any time.
|
||||
|
||||
<?php
|
||||
require 'Zend/Db/Connection.php';
|
||||
$x = new Zend\DB\Connection;
|
||||
Zend\DB\connect();
|
||||
?>
|
||||
|
||||
Namespace or class name can be imported:
|
||||
|
||||
<?php
|
||||
require 'Zend/Db/Connection.php';
|
||||
use Zend\DB;
|
||||
use Zend\DB\Connection as DbConnection;
|
||||
|
||||
$x = new Zend\DB\Connection();
|
||||
$y = new DB\connection();
|
||||
$z = new DbConnection();
|
||||
DB\connect();
|
||||
?>
|
||||
|
||||
The use statement only defines name aliasing. It may create name alias for
|
||||
namespace or class. The simple form of statement "use A\B\C\D;" is
|
||||
equivalent to "use A\B\C\D as D;". The use statement can be used at any
|
||||
time in the global scope (not inside function/class) and takes effect from
|
||||
the point of definition down to the end of file. It is recommended however to
|
||||
place the use statements at the beginning of the file. The use statements have
|
||||
effect only on the file where they appear.
|
||||
|
||||
The special "empty" namespace (\ prefix) is useful as explicit global
|
||||
namespace qualification. All class and function names started from \
|
||||
interpreted as global.
|
||||
|
||||
<?php
|
||||
namespace A\B\C;
|
||||
|
||||
$con = \mysql_connect(...);
|
||||
?>
|
||||
|
||||
A special constant __NAMESPACE__ contains the name of the current namespace.
|
||||
It can be used to construct fully-qualified names to pass them as callbacks.
|
||||
|
||||
<?php
|
||||
namespace A\B\C;
|
||||
|
||||
function foo() {
|
||||
}
|
||||
|
||||
set_error_handler(__NAMESPACE__ . "\foo");
|
||||
?>
|
||||
|
||||
In global namespace __NAMESPACE__ constant has the value of empty string.
|
||||
|
||||
Names inside namespace are resolved according to the following rules:
|
||||
|
||||
1) all qualified names are translated during compilation according to
|
||||
current import rules. So if we have "use A\B\C" and then "C\D\e()"
|
||||
it is translated to "A\B\C\D\e()".
|
||||
2) unqualified class names translated during compilation according to
|
||||
current import rules. So if we have "use A\B\C" and then "new C()" it
|
||||
is translated to "new A\B\C()".
|
||||
3) inside namespace, calls to unqualified functions that are defined in
|
||||
current namespace (and are known at the time the call is parsed) are
|
||||
interpreted as calls to these namespace functions.
|
||||
4) inside namespace, calls to unqualified functions that are not defined
|
||||
in current namespace are resolved at run-time. The call to function foo()
|
||||
inside namespace (A\B) first tries to find and call function from current
|
||||
namespace A\B\foo() and if it doesn't exist PHP tries to call internal
|
||||
function foo(). Note that using foo() inside namespace you can call only
|
||||
internal PHP functions, however using \foo() you are able to call any
|
||||
function from the global namespace.
|
||||
5) unqualified class names are resolved at run-time. E.q. "new Exception()"
|
||||
first tries to use (and autoload) class from current namespace and in case
|
||||
of failure uses internal PHP class. Note that using "new A" in namespace
|
||||
you can only create class from this namespace or internal PHP class, however
|
||||
using "new \A" you are able to create any class from the global namespace.
|
||||
6) Calls to qualified functions are resolved at run-time. Call to
|
||||
A\B\foo() first tries to call function foo() from namespace A\B, then
|
||||
it tries to find class A\B (__autoload() it if necessary) and call its
|
||||
static method foo()
|
||||
7) qualified class names are interpreted as class from corresponding
|
||||
namespace. So "new A\B\C()" refers to class C from namespace A\B.
|
||||
|
||||
Examples
|
||||
--------
|
||||
<?php
|
||||
namespace A;
|
||||
foo(); // first tries to call "foo" defined in namespace "A"
|
||||
// then calls internal function "foo"
|
||||
\foo(); // calls function "foo" defined in global scope
|
||||
?>
|
||||
|
||||
<?php
|
||||
namespace A;
|
||||
new B(); // first tries to create object of class "B" defined in namespace "A"
|
||||
// then creates object of internal class "B"
|
||||
new \B(); // creates object of class "B" defined in global scope
|
||||
?>
|
||||
|
||||
<?php
|
||||
namespace A;
|
||||
new A(); // first tries to create object of class "A" from namespace "A" (A\A)
|
||||
// then creates object of internal class "A"
|
||||
?>
|
||||
|
||||
<?php
|
||||
namespace A;
|
||||
B\foo(); // first tries to call function "foo" from namespace "A\B"
|
||||
// then calls method "foo" of internal class "B"
|
||||
\B\foo(); // first tries to call function "foo" from namespace "B"
|
||||
// then calls method "foo" of class "B" from global scope
|
||||
?>
|
||||
|
||||
The worst case if class name conflicts with namespace name
|
||||
<?php
|
||||
namespace A;
|
||||
A\foo(); // first tries to call function "foo" from namespace "A\A"
|
||||
// then tries to call method "foo" of class "A" from namespace "A"
|
||||
// then tries to call function "foo" from namespace "A"
|
||||
// then calls method "foo" of internal class "A"
|
||||
\A\foo(); // first tries to call function "foo" from namespace "A"
|
||||
// then calls method "foo" of class "A" from global scope
|
||||
?>
|
||||
|
||||
TODO
|
||||
====
|
||||
|
||||
* Support for namespace constants?
|
||||
|
||||
* performance problems
|
||||
- calls to internal functions in namespaces are slower, because PHP first
|
||||
looks for such function in current namespace
|
||||
- calls to static methods are slower, because PHP first tries to look
|
||||
for corresponding function in namespace
|
||||
|
||||
* Extend the Reflection API?
|
||||
* Add ReflectionNamespace class
|
||||
+ getName()
|
||||
+ getClasses()
|
||||
+ getFunctions()
|
||||
+ getFiles()
|
||||
* Add getNamespace() methods to ReflectionClass and ReflectionFunction
|
||||
|
||||
* Rename namespaces to packages?
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
Copyright (c) 1999-2006, Andi Gutmans, Sascha Schumann, Zeev Suraski.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
- Neither name of the copyright holders nor the names of their contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
|
||||
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -1,6 +0,0 @@
|
||||
## process this file with automake to produce Makefile.am
|
||||
AUTOMAKE_OPTIONS=foreign
|
||||
noinst_LTLIBRARIES=libtsrm.la
|
||||
libtsrm_la_SOURCES = TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c
|
||||
|
||||
depend:
|
||||
@@ -1,2 +0,0 @@
|
||||
- Improve the lock in ts_resource_ex() in order to cover less code.
|
||||
This can probably be done by more careful hash table access
|
||||
-794
@@ -1,794 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Thread Safe Resource Manager |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1999-2011, Andi Gutmans, Sascha Schumann, Zeev Suraski |
|
||||
| This source file is subject to the TSRM license, that is bundled |
|
||||
| with this package in the file LICENSE |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "TSRM.h"
|
||||
|
||||
#ifdef ZTS
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
typedef struct _tsrm_tls_entry tsrm_tls_entry;
|
||||
|
||||
struct _tsrm_tls_entry {
|
||||
void **storage;
|
||||
int count;
|
||||
THREAD_T thread_id;
|
||||
tsrm_tls_entry *next;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
ts_allocate_ctor ctor;
|
||||
ts_allocate_dtor dtor;
|
||||
int done;
|
||||
} tsrm_resource_type;
|
||||
|
||||
|
||||
/* The memory manager table */
|
||||
static tsrm_tls_entry **tsrm_tls_table=NULL;
|
||||
static int tsrm_tls_table_size;
|
||||
static ts_rsrc_id id_count;
|
||||
|
||||
/* The resource sizes table */
|
||||
static tsrm_resource_type *resource_types_table=NULL;
|
||||
static int resource_types_table_size;
|
||||
|
||||
|
||||
static MUTEX_T tsmm_mutex; /* thread-safe memory manager mutex */
|
||||
|
||||
/* New thread handlers */
|
||||
static tsrm_thread_begin_func_t tsrm_new_thread_begin_handler;
|
||||
static tsrm_thread_end_func_t tsrm_new_thread_end_handler;
|
||||
|
||||
/* Debug support */
|
||||
int tsrm_error(int level, const char *format, ...);
|
||||
|
||||
/* Read a resource from a thread's resource storage */
|
||||
static int tsrm_error_level;
|
||||
static FILE *tsrm_error_file;
|
||||
|
||||
#if TSRM_DEBUG
|
||||
#define TSRM_ERROR(args) tsrm_error args
|
||||
#define TSRM_SAFE_RETURN_RSRC(array, offset, range) \
|
||||
{ \
|
||||
int unshuffled_offset = TSRM_UNSHUFFLE_RSRC_ID(offset); \
|
||||
\
|
||||
if (offset==0) { \
|
||||
return &array; \
|
||||
} else if ((unshuffled_offset)>=0 && (unshuffled_offset)<(range)) { \
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Successfully fetched resource id %d for thread id %ld - 0x%0.8X", \
|
||||
unshuffled_offset, (long) thread_resources->thread_id, array[unshuffled_offset])); \
|
||||
return array[unshuffled_offset]; \
|
||||
} else { \
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Resource id %d is out of range (%d..%d)", \
|
||||
unshuffled_offset, TSRM_SHUFFLE_RSRC_ID(0), TSRM_SHUFFLE_RSRC_ID(thread_resources->count-1))); \
|
||||
return NULL; \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define TSRM_ERROR(args)
|
||||
#define TSRM_SAFE_RETURN_RSRC(array, offset, range) \
|
||||
if (offset==0) { \
|
||||
return &array; \
|
||||
} else { \
|
||||
return array[TSRM_UNSHUFFLE_RSRC_ID(offset)]; \
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PTHREADS)
|
||||
/* Thread local storage */
|
||||
static pthread_key_t tls_key;
|
||||
# define tsrm_tls_set(what) pthread_setspecific(tls_key, (void*)(what))
|
||||
# define tsrm_tls_get() pthread_getspecific(tls_key)
|
||||
|
||||
#elif defined(TSRM_ST)
|
||||
static int tls_key;
|
||||
# define tsrm_tls_set(what) st_thread_setspecific(tls_key, (void*)(what))
|
||||
# define tsrm_tls_get() st_thread_getspecific(tls_key)
|
||||
|
||||
#elif defined(TSRM_WIN32)
|
||||
static DWORD tls_key;
|
||||
# define tsrm_tls_set(what) TlsSetValue(tls_key, (void*)(what))
|
||||
# define tsrm_tls_get() TlsGetValue(tls_key)
|
||||
|
||||
#elif defined(BETHREADS)
|
||||
static int32 tls_key;
|
||||
# define tsrm_tls_set(what) tls_set(tls_key, (void*)(what))
|
||||
# define tsrm_tls_get() (tsrm_tls_entry*)tls_get(tls_key)
|
||||
|
||||
#else
|
||||
# define tsrm_tls_set(what)
|
||||
# define tsrm_tls_get() NULL
|
||||
# warning tsrm_set_interpreter_context is probably broken on this platform
|
||||
#endif
|
||||
|
||||
/* Startup TSRM (call once for the entire process) */
|
||||
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename)
|
||||
{
|
||||
#if defined(GNUPTH)
|
||||
pth_init();
|
||||
#elif defined(PTHREADS)
|
||||
pthread_key_create( &tls_key, 0 );
|
||||
#elif defined(TSRM_ST)
|
||||
st_init();
|
||||
st_key_create(&tls_key, 0);
|
||||
#elif defined(TSRM_WIN32)
|
||||
tls_key = TlsAlloc();
|
||||
#elif defined(BETHREADS)
|
||||
tls_key = tls_allocate();
|
||||
#endif
|
||||
|
||||
tsrm_error_file = stderr;
|
||||
tsrm_error_set(debug_level, debug_filename);
|
||||
tsrm_tls_table_size = expected_threads;
|
||||
|
||||
tsrm_tls_table = (tsrm_tls_entry **) calloc(tsrm_tls_table_size, sizeof(tsrm_tls_entry *));
|
||||
if (!tsrm_tls_table) {
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate TLS table"));
|
||||
return 0;
|
||||
}
|
||||
id_count=0;
|
||||
|
||||
resource_types_table_size = expected_resources;
|
||||
resource_types_table = (tsrm_resource_type *) calloc(resource_types_table_size, sizeof(tsrm_resource_type));
|
||||
if (!resource_types_table) {
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate resource types table"));
|
||||
free(tsrm_tls_table);
|
||||
tsrm_tls_table = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tsmm_mutex = tsrm_mutex_alloc();
|
||||
|
||||
tsrm_new_thread_begin_handler = tsrm_new_thread_end_handler = NULL;
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Started up TSRM, %d expected threads, %d expected resources", expected_threads, expected_resources));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Shutdown TSRM (call once for the entire process) */
|
||||
TSRM_API void tsrm_shutdown(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (tsrm_tls_table) {
|
||||
for (i=0; i<tsrm_tls_table_size; i++) {
|
||||
tsrm_tls_entry *p = tsrm_tls_table[i], *next_p;
|
||||
|
||||
while (p) {
|
||||
int j;
|
||||
|
||||
next_p = p->next;
|
||||
for (j=0; j<p->count; j++) {
|
||||
if (p->storage[j]) {
|
||||
if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) {
|
||||
resource_types_table[j].dtor(p->storage[j], &p->storage);
|
||||
}
|
||||
free(p->storage[j]);
|
||||
}
|
||||
}
|
||||
free(p->storage);
|
||||
free(p);
|
||||
p = next_p;
|
||||
}
|
||||
}
|
||||
free(tsrm_tls_table);
|
||||
tsrm_tls_table = NULL;
|
||||
}
|
||||
if (resource_types_table) {
|
||||
free(resource_types_table);
|
||||
resource_types_table=NULL;
|
||||
}
|
||||
tsrm_mutex_free(tsmm_mutex);
|
||||
tsmm_mutex = NULL;
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Shutdown TSRM"));
|
||||
if (tsrm_error_file!=stderr) {
|
||||
fclose(tsrm_error_file);
|
||||
}
|
||||
#if defined(GNUPTH)
|
||||
pth_kill();
|
||||
#elif defined(PTHREADS)
|
||||
pthread_setspecific(tls_key, 0);
|
||||
pthread_key_delete(tls_key);
|
||||
#elif defined(TSRM_WIN32)
|
||||
TlsFree(tls_key);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* allocates a new thread-safe-resource id */
|
||||
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
|
||||
{
|
||||
int i;
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", size));
|
||||
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
|
||||
/* obtain a resource id */
|
||||
*rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++);
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtained resource id %d", *rsrc_id));
|
||||
|
||||
/* store the new resource type in the resource sizes table */
|
||||
if (resource_types_table_size < id_count) {
|
||||
resource_types_table = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
|
||||
if (!resource_types_table) {
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));
|
||||
*rsrc_id = 0;
|
||||
return 0;
|
||||
}
|
||||
resource_types_table_size = id_count;
|
||||
}
|
||||
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].size = size;
|
||||
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor;
|
||||
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].dtor = dtor;
|
||||
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0;
|
||||
|
||||
/* enlarge the arrays for the already active threads */
|
||||
for (i=0; i<tsrm_tls_table_size; i++) {
|
||||
tsrm_tls_entry *p = tsrm_tls_table[i];
|
||||
|
||||
while (p) {
|
||||
if (p->count < id_count) {
|
||||
int j;
|
||||
|
||||
p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count);
|
||||
for (j=p->count; j<id_count; j++) {
|
||||
p->storage[j] = (void *) malloc(resource_types_table[j].size);
|
||||
if (resource_types_table[j].ctor) {
|
||||
resource_types_table[j].ctor(p->storage[j], &p->storage);
|
||||
}
|
||||
}
|
||||
p->count = id_count;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id));
|
||||
return *rsrc_id;
|
||||
}
|
||||
|
||||
|
||||
static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_T thread_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Creating data structures for thread %x", thread_id));
|
||||
(*thread_resources_ptr) = (tsrm_tls_entry *) malloc(sizeof(tsrm_tls_entry));
|
||||
(*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count);
|
||||
(*thread_resources_ptr)->count = id_count;
|
||||
(*thread_resources_ptr)->thread_id = thread_id;
|
||||
(*thread_resources_ptr)->next = NULL;
|
||||
|
||||
/* Set thread local storage to this new thread resources structure */
|
||||
tsrm_tls_set(*thread_resources_ptr);
|
||||
|
||||
if (tsrm_new_thread_begin_handler) {
|
||||
tsrm_new_thread_begin_handler(thread_id, &((*thread_resources_ptr)->storage));
|
||||
}
|
||||
for (i=0; i<id_count; i++) {
|
||||
if (resource_types_table[i].done) {
|
||||
(*thread_resources_ptr)->storage[i] = NULL;
|
||||
} else
|
||||
{
|
||||
(*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size);
|
||||
if (resource_types_table[i].ctor) {
|
||||
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i], &(*thread_resources_ptr)->storage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tsrm_new_thread_end_handler) {
|
||||
tsrm_new_thread_end_handler(thread_id, &((*thread_resources_ptr)->storage));
|
||||
}
|
||||
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
}
|
||||
|
||||
|
||||
/* fetches the requested resource for the current thread */
|
||||
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
|
||||
{
|
||||
THREAD_T thread_id;
|
||||
int hash_value;
|
||||
tsrm_tls_entry *thread_resources;
|
||||
|
||||
#ifdef NETWARE
|
||||
/* The below if loop is added for NetWare to fix an abend while unloading PHP
|
||||
* when an Apache unload command is issued on the system console.
|
||||
* While exiting from PHP, at the end for some reason, this function is called
|
||||
* with tsrm_tls_table = NULL. When this happened, the server abends when
|
||||
* tsrm_tls_table is accessed since it is NULL.
|
||||
*/
|
||||
if(tsrm_tls_table) {
|
||||
#endif
|
||||
if (!th_id) {
|
||||
/* Fast path for looking up the resources for the current
|
||||
* thread. Its used by just about every call to
|
||||
* ts_resource_ex(). This avoids the need for a mutex lock
|
||||
* and our hashtable lookup.
|
||||
*/
|
||||
thread_resources = tsrm_tls_get();
|
||||
|
||||
if (thread_resources) {
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for current thread %d", id, (long) thread_resources->thread_id));
|
||||
/* Read a specific resource from the thread's resources.
|
||||
* This is called outside of a mutex, so have to be aware about external
|
||||
* changes to the structure as we read it.
|
||||
*/
|
||||
TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
|
||||
}
|
||||
thread_id = tsrm_thread_id();
|
||||
} else {
|
||||
thread_id = *th_id;
|
||||
}
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for thread %ld", id, (long) thread_id));
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
|
||||
hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
|
||||
thread_resources = tsrm_tls_table[hash_value];
|
||||
|
||||
if (!thread_resources) {
|
||||
allocate_new_resource(&tsrm_tls_table[hash_value], thread_id);
|
||||
return ts_resource_ex(id, &thread_id);
|
||||
} else {
|
||||
do {
|
||||
if (thread_resources->thread_id == thread_id) {
|
||||
break;
|
||||
}
|
||||
if (thread_resources->next) {
|
||||
thread_resources = thread_resources->next;
|
||||
} else {
|
||||
allocate_new_resource(&thread_resources->next, thread_id);
|
||||
return ts_resource_ex(id, &thread_id);
|
||||
/*
|
||||
* thread_resources = thread_resources->next;
|
||||
* break;
|
||||
*/
|
||||
}
|
||||
} while (thread_resources);
|
||||
}
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
/* Read a specific resource from the thread's resources.
|
||||
* This is called outside of a mutex, so have to be aware about external
|
||||
* changes to the structure as we read it.
|
||||
*/
|
||||
TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
|
||||
#ifdef NETWARE
|
||||
} /* if(tsrm_tls_table) */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* frees an interpreter context. You are responsible for making sure that
|
||||
* it is not linked into the TSRM hash, and not marked as the current interpreter */
|
||||
void tsrm_free_interpreter_context(void *context)
|
||||
{
|
||||
tsrm_tls_entry *next, *thread_resources = (tsrm_tls_entry*)context;
|
||||
int i;
|
||||
|
||||
while (thread_resources) {
|
||||
next = thread_resources->next;
|
||||
|
||||
for (i=0; i<thread_resources->count; i++) {
|
||||
if (resource_types_table[i].dtor) {
|
||||
resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage);
|
||||
}
|
||||
}
|
||||
for (i=0; i<thread_resources->count; i++) {
|
||||
free(thread_resources->storage[i]);
|
||||
}
|
||||
free(thread_resources->storage);
|
||||
free(thread_resources);
|
||||
thread_resources = next;
|
||||
}
|
||||
}
|
||||
|
||||
void *tsrm_set_interpreter_context(void *new_ctx)
|
||||
{
|
||||
tsrm_tls_entry *current;
|
||||
|
||||
current = tsrm_tls_get();
|
||||
|
||||
/* TODO: unlink current from the global linked list, and replace it
|
||||
* it with the new context, protected by mutex where/if appropriate */
|
||||
|
||||
/* Set thread local storage to this new thread resources structure */
|
||||
tsrm_tls_set(new_ctx);
|
||||
|
||||
/* return old context, so caller can restore it when they're done */
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
/* allocates a new interpreter context */
|
||||
void *tsrm_new_interpreter_context(void)
|
||||
{
|
||||
tsrm_tls_entry *new_ctx, *current;
|
||||
THREAD_T thread_id;
|
||||
|
||||
thread_id = tsrm_thread_id();
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
|
||||
current = tsrm_tls_get();
|
||||
|
||||
allocate_new_resource(&new_ctx, thread_id);
|
||||
|
||||
/* switch back to the context that was in use prior to our creation
|
||||
* of the new one */
|
||||
return tsrm_set_interpreter_context(current);
|
||||
}
|
||||
|
||||
|
||||
/* frees all resources allocated for the current thread */
|
||||
void ts_free_thread(void)
|
||||
{
|
||||
tsrm_tls_entry *thread_resources;
|
||||
int i;
|
||||
THREAD_T thread_id = tsrm_thread_id();
|
||||
int hash_value;
|
||||
tsrm_tls_entry *last=NULL;
|
||||
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
|
||||
thread_resources = tsrm_tls_table[hash_value];
|
||||
|
||||
while (thread_resources) {
|
||||
if (thread_resources->thread_id == thread_id) {
|
||||
for (i=0; i<thread_resources->count; i++) {
|
||||
if (resource_types_table[i].dtor) {
|
||||
resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage);
|
||||
}
|
||||
}
|
||||
for (i=0; i<thread_resources->count; i++) {
|
||||
free(thread_resources->storage[i]);
|
||||
}
|
||||
free(thread_resources->storage);
|
||||
if (last) {
|
||||
last->next = thread_resources->next;
|
||||
} else {
|
||||
tsrm_tls_table[hash_value] = thread_resources->next;
|
||||
}
|
||||
tsrm_tls_set(0);
|
||||
free(thread_resources);
|
||||
break;
|
||||
}
|
||||
if (thread_resources->next) {
|
||||
last = thread_resources;
|
||||
}
|
||||
thread_resources = thread_resources->next;
|
||||
}
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
}
|
||||
|
||||
|
||||
/* frees all resources allocated for all threads except current */
|
||||
void ts_free_worker_threads(void)
|
||||
{
|
||||
tsrm_tls_entry *thread_resources;
|
||||
int i;
|
||||
THREAD_T thread_id = tsrm_thread_id();
|
||||
int hash_value;
|
||||
tsrm_tls_entry *last=NULL;
|
||||
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
|
||||
thread_resources = tsrm_tls_table[hash_value];
|
||||
|
||||
while (thread_resources) {
|
||||
if (thread_resources->thread_id != thread_id) {
|
||||
for (i=0; i<thread_resources->count; i++) {
|
||||
if (resource_types_table[i].dtor) {
|
||||
resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage);
|
||||
}
|
||||
}
|
||||
for (i=0; i<thread_resources->count; i++) {
|
||||
free(thread_resources->storage[i]);
|
||||
}
|
||||
free(thread_resources->storage);
|
||||
if (last) {
|
||||
last->next = thread_resources->next;
|
||||
} else {
|
||||
tsrm_tls_table[hash_value] = thread_resources->next;
|
||||
}
|
||||
free(thread_resources);
|
||||
if (last) {
|
||||
thread_resources = last->next;
|
||||
} else {
|
||||
thread_resources = tsrm_tls_table[hash_value];
|
||||
}
|
||||
} else {
|
||||
if (thread_resources->next) {
|
||||
last = thread_resources;
|
||||
}
|
||||
thread_resources = thread_resources->next;
|
||||
}
|
||||
}
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
}
|
||||
|
||||
|
||||
/* deallocates all occurrences of a given id */
|
||||
void ts_free_id(ts_rsrc_id id)
|
||||
{
|
||||
int i;
|
||||
int j = TSRM_UNSHUFFLE_RSRC_ID(id);
|
||||
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Freeing resource id %d", id));
|
||||
|
||||
if (tsrm_tls_table) {
|
||||
for (i=0; i<tsrm_tls_table_size; i++) {
|
||||
tsrm_tls_entry *p = tsrm_tls_table[i];
|
||||
|
||||
while (p) {
|
||||
if (p->count > j && p->storage[j]) {
|
||||
if (resource_types_table && resource_types_table[j].dtor) {
|
||||
resource_types_table[j].dtor(p->storage[j], &p->storage);
|
||||
}
|
||||
free(p->storage[j]);
|
||||
p->storage[j] = NULL;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
resource_types_table[j].done = 1;
|
||||
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully freed resource id %d", id));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Utility Functions
|
||||
*/
|
||||
|
||||
/* Obtain the current thread id */
|
||||
TSRM_API THREAD_T tsrm_thread_id(void)
|
||||
{
|
||||
#ifdef TSRM_WIN32
|
||||
return GetCurrentThreadId();
|
||||
#elif defined(GNUPTH)
|
||||
return pth_self();
|
||||
#elif defined(PTHREADS)
|
||||
return pthread_self();
|
||||
#elif defined(NSAPI)
|
||||
return systhread_current();
|
||||
#elif defined(PI3WEB)
|
||||
return PIThread_getCurrent();
|
||||
#elif defined(TSRM_ST)
|
||||
return st_thread_self();
|
||||
#elif defined(BETHREADS)
|
||||
return find_thread(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Allocate a mutex */
|
||||
TSRM_API MUTEX_T tsrm_mutex_alloc(void)
|
||||
{
|
||||
MUTEX_T mutexp;
|
||||
#ifdef TSRM_WIN32
|
||||
mutexp = malloc(sizeof(CRITICAL_SECTION));
|
||||
InitializeCriticalSection(mutexp);
|
||||
#elif defined(GNUPTH)
|
||||
mutexp = (MUTEX_T) malloc(sizeof(*mutexp));
|
||||
pth_mutex_init(mutexp);
|
||||
#elif defined(PTHREADS)
|
||||
mutexp = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutex_init(mutexp,NULL);
|
||||
#elif defined(NSAPI)
|
||||
mutexp = crit_init();
|
||||
#elif defined(PI3WEB)
|
||||
mutexp = PIPlatform_allocLocalMutex();
|
||||
#elif defined(TSRM_ST)
|
||||
mutexp = st_mutex_new();
|
||||
#elif defined(BETHREADS)
|
||||
mutexp = (beos_ben*)malloc(sizeof(beos_ben));
|
||||
mutexp->ben = 0;
|
||||
mutexp->sem = create_sem(1, "PHP sempahore");
|
||||
#endif
|
||||
#ifdef THR_DEBUG
|
||||
printf("Mutex created thread: %d\n",mythreadid());
|
||||
#endif
|
||||
return( mutexp );
|
||||
}
|
||||
|
||||
|
||||
/* Free a mutex */
|
||||
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
|
||||
{
|
||||
if (mutexp) {
|
||||
#ifdef TSRM_WIN32
|
||||
DeleteCriticalSection(mutexp);
|
||||
free(mutexp);
|
||||
#elif defined(GNUPTH)
|
||||
free(mutexp);
|
||||
#elif defined(PTHREADS)
|
||||
pthread_mutex_destroy(mutexp);
|
||||
free(mutexp);
|
||||
#elif defined(NSAPI)
|
||||
crit_terminate(mutexp);
|
||||
#elif defined(PI3WEB)
|
||||
PISync_delete(mutexp);
|
||||
#elif defined(TSRM_ST)
|
||||
st_mutex_destroy(mutexp);
|
||||
#elif defined(BETHREADS)
|
||||
delete_sem(mutexp->sem);
|
||||
free(mutexp);
|
||||
#endif
|
||||
}
|
||||
#ifdef THR_DEBUG
|
||||
printf("Mutex freed thread: %d\n",mythreadid());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Lock a mutex.
|
||||
A return value of 0 indicates success
|
||||
*/
|
||||
TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp)
|
||||
{
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Mutex locked thread: %ld", tsrm_thread_id()));
|
||||
#ifdef TSRM_WIN32
|
||||
EnterCriticalSection(mutexp);
|
||||
return 0;
|
||||
#elif defined(GNUPTH)
|
||||
if (pth_mutex_acquire(mutexp, 0, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
#elif defined(PTHREADS)
|
||||
return pthread_mutex_lock(mutexp);
|
||||
#elif defined(NSAPI)
|
||||
crit_enter(mutexp);
|
||||
return 0;
|
||||
#elif defined(PI3WEB)
|
||||
return PISync_lock(mutexp);
|
||||
#elif defined(TSRM_ST)
|
||||
return st_mutex_lock(mutexp);
|
||||
#elif defined(BETHREADS)
|
||||
if (atomic_add(&mutexp->ben, 1) != 0)
|
||||
return acquire_sem(mutexp->sem);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Unlock a mutex.
|
||||
A return value of 0 indicates success
|
||||
*/
|
||||
TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
|
||||
{
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Mutex unlocked thread: %ld", tsrm_thread_id()));
|
||||
#ifdef TSRM_WIN32
|
||||
LeaveCriticalSection(mutexp);
|
||||
return 0;
|
||||
#elif defined(GNUPTH)
|
||||
if (pth_mutex_release(mutexp)) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
#elif defined(PTHREADS)
|
||||
return pthread_mutex_unlock(mutexp);
|
||||
#elif defined(NSAPI)
|
||||
crit_exit(mutexp);
|
||||
return 0;
|
||||
#elif defined(PI3WEB)
|
||||
return PISync_unlock(mutexp);
|
||||
#elif defined(TSRM_ST)
|
||||
return st_mutex_unlock(mutexp);
|
||||
#elif defined(BETHREADS)
|
||||
if (atomic_add(&mutexp->ben, -1) != 1)
|
||||
return release_sem(mutexp->sem);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
Changes the signal mask of the calling thread
|
||||
*/
|
||||
#ifdef HAVE_SIGPROCMASK
|
||||
TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset)
|
||||
{
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Changed sigmask in thread: %ld", tsrm_thread_id()));
|
||||
/* TODO: add support for other APIs */
|
||||
#ifdef PTHREADS
|
||||
return pthread_sigmask(how, set, oldset);
|
||||
#else
|
||||
return sigprocmask(how, set, oldset);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler)
|
||||
{
|
||||
void *retval = (void *) tsrm_new_thread_begin_handler;
|
||||
|
||||
tsrm_new_thread_begin_handler = new_thread_begin_handler;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler)
|
||||
{
|
||||
void *retval = (void *) tsrm_new_thread_end_handler;
|
||||
|
||||
tsrm_new_thread_end_handler = new_thread_end_handler;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Debug support
|
||||
*/
|
||||
|
||||
#if TSRM_DEBUG
|
||||
int tsrm_error(int level, const char *format, ...)
|
||||
{
|
||||
if (level<=tsrm_error_level) {
|
||||
va_list args;
|
||||
int size;
|
||||
|
||||
fprintf(tsrm_error_file, "TSRM: ");
|
||||
va_start(args, format);
|
||||
size = vfprintf(tsrm_error_file, format, args);
|
||||
va_end(args);
|
||||
fprintf(tsrm_error_file, "\n");
|
||||
fflush(tsrm_error_file);
|
||||
return size;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void tsrm_error_set(int level, char *debug_filename)
|
||||
{
|
||||
tsrm_error_level = level;
|
||||
|
||||
#if TSRM_DEBUG
|
||||
if (tsrm_error_file!=stderr) { /* close files opened earlier */
|
||||
fclose(tsrm_error_file);
|
||||
}
|
||||
|
||||
if (debug_filename) {
|
||||
tsrm_error_file = fopen(debug_filename, "w");
|
||||
if (!tsrm_error_file) {
|
||||
tsrm_error_file = stderr;
|
||||
}
|
||||
} else {
|
||||
tsrm_error_file = stderr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* ZTS */
|
||||
-186
@@ -1,186 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="TSRM" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=TSRM - Win32 Debug_TS
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "TSRM.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "TSRM.mak" CFG="TSRM - Win32 Debug_TS"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "TSRM - Win32 Debug_TS" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "TSRM - Win32 Release_TS" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "TSRM - Win32 Release_TS_inline" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "TSRM - Win32 Release_TSDbg" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "TSRM - Win32 Debug_TS"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "TSRM___Win32_Debug_TS"
|
||||
# PROP BASE Intermediate_Dir "TSRM___Win32_Debug_TS"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug_TS"
|
||||
# PROP Intermediate_Dir "Debug_TS"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "C:\Projects\TSRM" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_DEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=1 /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x40d /d "_DEBUG"
|
||||
# ADD RSC /l 0x40d /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "TSRM - Win32 Release_TS"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "TSRM___Win32_Release_TS"
|
||||
# PROP BASE Intermediate_Dir "TSRM___Win32_Release_TS"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release_TS"
|
||||
# PROP Intermediate_Dir "Release_TS"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c
|
||||
# ADD BASE RSC /l 0x40d /d "NDEBUG"
|
||||
# ADD RSC /l 0x40d /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "TSRM - Win32 Release_TS_inline"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "TSRM___Win32_Release_TS_inline"
|
||||
# PROP BASE Intermediate_Dir "TSRM___Win32_Release_TS_inline"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release_TS_inline"
|
||||
# PROP Intermediate_Dir "Release_TS_inline"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "TSRM_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c
|
||||
# ADD BASE RSC /l 0x40d /d "NDEBUG"
|
||||
# ADD RSC /l 0x40d /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "TSRM - Win32 Release_TSDbg"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "TSRM___Win32_Release_TSDbg"
|
||||
# PROP BASE Intermediate_Dir "TSRM___Win32_Release_TSDbg"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release_TSDbg"
|
||||
# PROP Intermediate_Dir "Release_TSDbg"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /Zi /Od /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c
|
||||
# ADD BASE RSC /l 0x40d /d "NDEBUG"
|
||||
# ADD RSC /l 0x40d /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "TSRM - Win32 Debug_TS"
|
||||
# Name "TSRM - Win32 Release_TS"
|
||||
# Name "TSRM - Win32 Release_TS_inline"
|
||||
# Name "TSRM - Win32 Release_TSDbg"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TSRM.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_strtok_r.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_virtual_cwd.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_win32.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\readdir.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TSRM.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_config.w32.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_config_common.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_strtok_r.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_virtual_cwd.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_win32.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
-186
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Thread Safe Resource Manager |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1999-2011, Andi Gutmans, Sascha Schumann, Zeev Suraski |
|
||||
| This source file is subject to the TSRM license, that is bundled |
|
||||
| with this package in the file LICENSE |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef TSRM_H
|
||||
#define TSRM_H
|
||||
|
||||
#if !defined(__CYGWIN__) && defined(WIN32)
|
||||
# define TSRM_WIN32
|
||||
# include "tsrm_config.w32.h"
|
||||
#else
|
||||
# include <tsrm_config.h>
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
# ifdef TSRM_EXPORTS
|
||||
# define TSRM_API __declspec(dllexport)
|
||||
# else
|
||||
# define TSRM_API __declspec(dllimport)
|
||||
# endif
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define TSRM_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
# define TSRM_API
|
||||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
typedef __int64 tsrm_intptr_t;
|
||||
typedef unsigned __int64 tsrm_uintptr_t;
|
||||
#else
|
||||
typedef long tsrm_intptr_t;
|
||||
typedef unsigned long tsrm_uintptr_t;
|
||||
#endif
|
||||
|
||||
/* Only compile multi-threading functions if we're in ZTS mode */
|
||||
#ifdef ZTS
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
# ifndef TSRM_INCLUDE_FULL_WINDOWS_HEADERS
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# include <shellapi.h>
|
||||
#elif defined(GNUPTH)
|
||||
# include <pth.h>
|
||||
#elif defined(PTHREADS)
|
||||
# include <pthread.h>
|
||||
#elif defined(TSRM_ST)
|
||||
# include <st.h>
|
||||
#elif defined(BETHREADS)
|
||||
#include <kernel/OS.h>
|
||||
#include <TLS.h>
|
||||
#endif
|
||||
|
||||
typedef int ts_rsrc_id;
|
||||
|
||||
/* Define THREAD_T and MUTEX_T */
|
||||
#ifdef TSRM_WIN32
|
||||
# define THREAD_T DWORD
|
||||
# define MUTEX_T CRITICAL_SECTION *
|
||||
#elif defined(GNUPTH)
|
||||
# define THREAD_T pth_t
|
||||
# define MUTEX_T pth_mutex_t *
|
||||
#elif defined(PTHREADS)
|
||||
# define THREAD_T pthread_t
|
||||
# define MUTEX_T pthread_mutex_t *
|
||||
#elif defined(NSAPI)
|
||||
# define THREAD_T SYS_THREAD
|
||||
# define MUTEX_T CRITICAL
|
||||
#elif defined(PI3WEB)
|
||||
# define THREAD_T PIThread *
|
||||
# define MUTEX_T PISync *
|
||||
#elif defined(TSRM_ST)
|
||||
# define THREAD_T st_thread_t
|
||||
# define MUTEX_T st_mutex_t
|
||||
#elif defined(BETHREADS)
|
||||
# define THREAD_T thread_id
|
||||
typedef struct {
|
||||
sem_id sem;
|
||||
int32 ben;
|
||||
} beos_ben;
|
||||
# define MUTEX_T beos_ben *
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
typedef void (*ts_allocate_ctor)(void *, void ***);
|
||||
typedef void (*ts_allocate_dtor)(void *, void ***);
|
||||
|
||||
#define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* startup/shutdown */
|
||||
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename);
|
||||
TSRM_API void tsrm_shutdown(void);
|
||||
|
||||
/* allocates a new thread-safe-resource id */
|
||||
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);
|
||||
|
||||
/* fetches the requested resource for the current thread */
|
||||
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id);
|
||||
#define ts_resource(id) ts_resource_ex(id, NULL)
|
||||
|
||||
/* frees all resources allocated for the current thread */
|
||||
TSRM_API void ts_free_thread(void);
|
||||
|
||||
/* frees all resources allocated for all threads except current */
|
||||
void ts_free_worker_threads(void);
|
||||
|
||||
/* deallocates all occurrences of a given id */
|
||||
TSRM_API void ts_free_id(ts_rsrc_id id);
|
||||
|
||||
|
||||
/* Debug support */
|
||||
#define TSRM_ERROR_LEVEL_ERROR 1
|
||||
#define TSRM_ERROR_LEVEL_CORE 2
|
||||
#define TSRM_ERROR_LEVEL_INFO 3
|
||||
|
||||
typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id, void ***tsrm_ls);
|
||||
typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id, void ***tsrm_ls);
|
||||
|
||||
|
||||
TSRM_API int tsrm_error(int level, const char *format, ...);
|
||||
TSRM_API void tsrm_error_set(int level, char *debug_filename);
|
||||
|
||||
/* utility functions */
|
||||
TSRM_API THREAD_T tsrm_thread_id(void);
|
||||
TSRM_API MUTEX_T tsrm_mutex_alloc(void);
|
||||
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp);
|
||||
TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp);
|
||||
TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp);
|
||||
#ifdef HAVE_SIGPROCMASK
|
||||
TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset);
|
||||
#endif
|
||||
|
||||
TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler);
|
||||
TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler);
|
||||
|
||||
/* these 3 APIs should only be used by people that fully understand the threading model
|
||||
* used by PHP/Zend and the selected SAPI. */
|
||||
TSRM_API void *tsrm_new_interpreter_context(void);
|
||||
TSRM_API void *tsrm_set_interpreter_context(void *new_ctx);
|
||||
TSRM_API void tsrm_free_interpreter_context(void *context);
|
||||
|
||||
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
|
||||
#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
|
||||
|
||||
#define TSRMLS_FETCH() void ***tsrm_ls = (void ***) ts_resource_ex(0, NULL)
|
||||
#define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx
|
||||
#define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_ls
|
||||
#define TSRMG(id, type, element) (((type) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
|
||||
#define TSRMLS_D void ***tsrm_ls
|
||||
#define TSRMLS_DC , TSRMLS_D
|
||||
#define TSRMLS_C tsrm_ls
|
||||
#define TSRMLS_CC , TSRMLS_C
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* non ZTS */
|
||||
|
||||
#define TSRMLS_FETCH()
|
||||
#define TSRMLS_FETCH_FROM_CTX(ctx)
|
||||
#define TSRMLS_SET_CTX(ctx)
|
||||
#define TSRMLS_D void
|
||||
#define TSRMLS_DC
|
||||
#define TSRMLS_C
|
||||
#define TSRMLS_CC
|
||||
|
||||
#endif /* ZTS */
|
||||
|
||||
#endif /* TSRM_H */
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
AC_DEFUN([AM_SET_LIBTOOL_VARIABLE],[
|
||||
LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
|
||||
])
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
# Makefile to generate build tools
|
||||
#
|
||||
# Standard usage:
|
||||
# make -f build.mk
|
||||
#
|
||||
# Written by Sascha Schumann
|
||||
#
|
||||
# $Id$
|
||||
|
||||
|
||||
LT_TARGETS = ltmain.sh ltconfig
|
||||
|
||||
config_h_in = tsrm_config.h.in
|
||||
|
||||
makefile_am_files = Makefile.am
|
||||
makefile_in_files = $(makefile_am_files:.am=.in)
|
||||
makefile_files = $(makefile_am_files:e.am=e)
|
||||
|
||||
targets = $(makefile_in_files) $(LT_TARGETS) configure $(config_h_in)
|
||||
|
||||
all: $(targets)
|
||||
|
||||
clean:
|
||||
rm -f $(targets)
|
||||
|
||||
$(LT_TARGETS):
|
||||
rm -f $(LT_TARGETS)
|
||||
libtoolize --automake $(AMFLAGS) -f
|
||||
|
||||
$(makefile_in_files): $(makefile_am_files)
|
||||
automake -a -i $(AMFLAGS) $(makefile_files)
|
||||
|
||||
aclocal.m4: configure.in acinclude.m4
|
||||
aclocal
|
||||
|
||||
$(config_h_in): configure.in
|
||||
# explicitly remove target since autoheader does not seem to work
|
||||
# correctly otherwise (timestamps are not updated)
|
||||
@rm -f $@
|
||||
autoheader
|
||||
|
||||
configure: aclocal.m4 configure.in
|
||||
autoconf
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
case "$1" in
|
||||
--copy)
|
||||
automake_flags=--copy
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
|
||||
libtoolize --force --automake $automake_flags
|
||||
|
||||
mv aclocal.m4 aclocal.m4.old 2>/dev/null
|
||||
aclocal
|
||||
if cmp aclocal.m4.old aclocal.m4 > /dev/null 2>&1; then
|
||||
echo "buildconf: keeping ${1}aclocal.m4"
|
||||
mv aclocal.m4.old aclocal.m4
|
||||
else
|
||||
echo "buildconf: created or modified ${1}aclocal.m4"
|
||||
fi
|
||||
|
||||
autoheader
|
||||
|
||||
automake --add-missing --include-deps $automake_flags
|
||||
|
||||
mv configure configure.old 2>/dev/null
|
||||
autoconf
|
||||
if cmp configure.old configure > /dev/null 2>&1; then
|
||||
echo "buildconf: keeping ${1}configure"
|
||||
mv configure.old configure
|
||||
else
|
||||
echo "buildconf: created or modified ${1}configure"
|
||||
fi
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
// vim:ft=javascript
|
||||
// $Id$
|
||||
|
||||
ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c tsrm_win32.c");
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl
|
||||
dnl Minimalistic configure.in for TSRM.
|
||||
dnl
|
||||
|
||||
AC_INIT(TSRM.c)
|
||||
AM_INIT_AUTOMAKE(TSRM, 1.0, nodefine)
|
||||
AM_CONFIG_HEADER(tsrm_config.h)
|
||||
|
||||
AH_TOP([
|
||||
#undef PTHREADS
|
||||
])
|
||||
|
||||
sinclude(tsrm.m4)
|
||||
|
||||
TSRM_BASIC_CHECKS
|
||||
TSRM_THREADS_CHECKS
|
||||
|
||||
AM_PROG_LIBTOOL
|
||||
if test "$enable_debug" != "yes"; then
|
||||
AM_SET_LIBTOOL_VARIABLE([--silent])
|
||||
fi
|
||||
|
||||
dnl TSRM_PTHREAD
|
||||
|
||||
AC_CHECK_HEADERS(
|
||||
utime.h \
|
||||
dirent.h \
|
||||
stdarg.h \
|
||||
alloca.h \
|
||||
unistd.h \
|
||||
limits.h
|
||||
)
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
@@ -1,45 +0,0 @@
|
||||
#ifndef READDIR_H
|
||||
#define READDIR_H
|
||||
|
||||
|
||||
/*
|
||||
* Structures and types used to implement opendir/readdir/closedir
|
||||
* on Windows 95/NT.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <direct.h>
|
||||
|
||||
/* struct dirent - same as Unix */
|
||||
|
||||
struct dirent {
|
||||
long d_ino; /* inode (always 1 in WIN32) */
|
||||
off_t d_off; /* offset to this dirent */
|
||||
unsigned short d_reclen; /* length of d_name */
|
||||
char d_name[_MAX_FNAME + 1]; /* filename (null terminated) */
|
||||
};
|
||||
|
||||
|
||||
/* typedef DIR - not the same as Unix */
|
||||
typedef struct {
|
||||
HANDLE handle; /* _findfirst/_findnext handle */
|
||||
short offset; /* offset into directory */
|
||||
short finished; /* 1 if there are not more files */
|
||||
WIN32_FIND_DATA fileinfo; /* from _findfirst/_findnext */
|
||||
char *dir; /* the dir we are reading */
|
||||
struct dirent dent; /* the dirent to return */
|
||||
} DIR;
|
||||
|
||||
/* Function prototypes */
|
||||
DIR *opendir(const char *);
|
||||
struct dirent *readdir(DIR *);
|
||||
int readdir_r(DIR *, struct dirent *, struct dirent **);
|
||||
int closedir(DIR *);
|
||||
int rewinddir(DIR *);
|
||||
|
||||
#endif /* READDIR_H */
|
||||
-173
@@ -1,173 +0,0 @@
|
||||
dnl Copyright (c) 1999, 2000 Sascha Schumann. All rights reserved.
|
||||
dnl
|
||||
dnl Redistribution and use in source and binary forms, with or without
|
||||
dnl modification, are permitted provided that the following conditions
|
||||
dnl are met:
|
||||
dnl
|
||||
dnl 1. Redistributions of source code must retain the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer.
|
||||
dnl
|
||||
dnl 2. Redistributions in binary form must reproduce the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer in
|
||||
dnl the documentation and/or other materials provided with the
|
||||
dnl distribution.
|
||||
dnl
|
||||
dnl THIS SOFTWARE IS PROVIDED BY SASCHA SCHUMANN ``AS IS'' AND ANY
|
||||
dnl EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
dnl IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
dnl PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SASCHA SCHUMANN OR
|
||||
dnl HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
dnl NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
dnl LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
dnl HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
dnl STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
dnl ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
dnl OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
dnl
|
||||
dnl PTHREADS_FLAGS
|
||||
dnl
|
||||
dnl Set some magic defines to achieve POSIX threads conformance
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_FLAGS],[
|
||||
if test -z "$host_alias" && test -n "$host"; then
|
||||
host_alias=$host
|
||||
fi
|
||||
if test -z "$host_alias"; then
|
||||
AC_MSG_ERROR(host_alias is not set. Make sure to run config.guess)
|
||||
fi
|
||||
case $host_alias in
|
||||
*solaris*)
|
||||
PTHREAD_FLAGS="-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT";;
|
||||
*freebsd*)
|
||||
PTHREAD_FLAGS="-D_REENTRANT -D_THREAD_SAFE";;
|
||||
*linux*)
|
||||
PTHREAD_FLAGS=-D_REENTRANT;;
|
||||
*aix*)
|
||||
PTHREAD_FLAGS=-D_THREAD_SAFE;;
|
||||
*irix*)
|
||||
PTHREAD_FLAGS=-D_POSIX_THREAD_SAFE_FUNCTIONS;;
|
||||
*hpux*)
|
||||
PTHREAD_FLAGS=-D_REENTRANT;;
|
||||
*sco*)
|
||||
PTHREAD_FLAGS=-D_REENTRANT;;
|
||||
dnl Solves sigwait() problem, creates problems with u_long etc.
|
||||
dnl PTHREAD_FLAGS="-D_REENTRANT -D_XOPEN_SOURCE=500 -D_POSIX_C_SOURCE=199506 -D_XOPEN_SOURCE_EXTENDED=1";;
|
||||
esac
|
||||
|
||||
if test -n "$PTHREAD_FLAGS"; then
|
||||
CPPFLAGS="$CPPFLAGS $PTHREAD_FLAGS"
|
||||
fi
|
||||
])dnl
|
||||
dnl
|
||||
dnl PTHREADS_CHECK_COMPILE
|
||||
dnl
|
||||
dnl Check whether the current setup can use POSIX threads calls
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_CHECK_COMPILE], [
|
||||
AC_TRY_RUN( [
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
|
||||
void *thread_routine(void *data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
int main() {
|
||||
pthread_t thd;
|
||||
pthread_mutexattr_t mattr;
|
||||
int data = 1;
|
||||
pthread_mutexattr_init(&mattr);
|
||||
return pthread_create(&thd, NULL, thread_routine, &data);
|
||||
} ], [
|
||||
pthreads_working=yes
|
||||
], [
|
||||
pthreads_working=no
|
||||
], [
|
||||
dnl For cross compiling running this test is of no use. NetWare supports pthreads
|
||||
pthreads_working=no
|
||||
case $host_alias in
|
||||
*netware*)
|
||||
pthreads_working=yes
|
||||
esac
|
||||
]
|
||||
) ] )dnl
|
||||
dnl
|
||||
dnl PTHREADS_CHECK()
|
||||
dnl
|
||||
dnl Try to find a way to enable POSIX threads
|
||||
dnl
|
||||
dnl Magic flags
|
||||
dnl -kthread gcc (FreeBSD)
|
||||
dnl -Kthread UDK cc (UnixWare)
|
||||
dnl -mt WorkShop cc (Solaris)
|
||||
dnl -mthreads gcc (AIX)
|
||||
dnl -pthread gcc (Linux, FreeBSD, NetBSD, OpenBSD)
|
||||
dnl -pthreads gcc (Solaris)
|
||||
dnl -qthreaded AIX cc V5
|
||||
dnl -threads gcc (HP-UX)
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_CHECK],[
|
||||
|
||||
if test "$beos_threads" = "1"; then
|
||||
pthreads_working="yes"
|
||||
ac_cv_pthreads_cflags=""
|
||||
else
|
||||
save_CFLAGS=$CFLAGS
|
||||
save_LIBS=$LIBS
|
||||
PTHREADS_ASSIGN_VARS
|
||||
PTHREADS_CHECK_COMPILE
|
||||
LIBS=$save_LIBS
|
||||
CFLAGS=$save_CFLAGS
|
||||
|
||||
AC_CACHE_CHECK(for pthreads_cflags,ac_cv_pthreads_cflags,[
|
||||
ac_cv_pthreads_cflags=
|
||||
if test "$pthreads_working" != "yes"; then
|
||||
for flag in -kthread -pthread -pthreads -mthreads -Kthread -threads -mt -qthreaded; do
|
||||
ac_save=$CFLAGS
|
||||
CFLAGS="$CFLAGS $flag"
|
||||
PTHREADS_CHECK_COMPILE
|
||||
CFLAGS=$ac_save
|
||||
if test "$pthreads_working" = "yes"; then
|
||||
ac_cv_pthreads_cflags=$flag
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
AC_CACHE_CHECK(for pthreads_lib, ac_cv_pthreads_lib,[
|
||||
ac_cv_pthreads_lib=
|
||||
if test "$pthreads_working" != "yes"; then
|
||||
for lib in pthread pthreads c_r; do
|
||||
ac_save=$LIBS
|
||||
LIBS="$LIBS -l$lib"
|
||||
PTHREADS_CHECK_COMPILE
|
||||
LIBS=$ac_save
|
||||
if test "$pthreads_working" = "yes"; then
|
||||
ac_cv_pthreads_lib=$lib
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
|
||||
if test "$pthreads_working" = "yes"; then
|
||||
threads_result="POSIX-Threads found"
|
||||
else
|
||||
threads_result="POSIX-Threads not found"
|
||||
fi
|
||||
])dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_ASSIGN_VARS],[
|
||||
if test -n "$ac_cv_pthreads_lib"; then
|
||||
LIBS="$LIBS -l$ac_cv_pthreads_lib"
|
||||
fi
|
||||
|
||||
if test -n "$ac_cv_pthreads_cflags"; then
|
||||
CFLAGS="$CFLAGS $ac_cv_pthreads_cflags"
|
||||
fi
|
||||
])dnl
|
||||
-130
@@ -1,130 +0,0 @@
|
||||
|
||||
dnl TSRM_CHECK_GCC_ARG(ARG, ACTION-IF-FOUND, ACTION-IF-NOT_FOUND)
|
||||
AC_DEFUN([TSRM_CHECK_GCC_ARG],[
|
||||
gcc_arg_name=[ac_cv_gcc_arg]translit($1,A-Z-,a-z_)
|
||||
AC_CACHE_CHECK([whether $CC supports $1], [ac_cv_gcc_arg]translit($1,A-Z-,a-z_), [
|
||||
echo 'void somefunc() { };' > conftest.c
|
||||
cmd='$CC $1 -c conftest.c'
|
||||
if eval $cmd 2>&1 | egrep -e $1 >/dev/null ; then
|
||||
ac_result=no
|
||||
else
|
||||
ac_result=yes
|
||||
fi
|
||||
eval $gcc_arg_name=$ac_result
|
||||
rm -f conftest.*
|
||||
])
|
||||
if eval test "\$$gcc_arg_name" = "yes"; then
|
||||
$2
|
||||
else
|
||||
:
|
||||
$3
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([TSRM_BASIC_CHECKS],[
|
||||
|
||||
AC_REQUIRE([AC_PROG_CC])dnl
|
||||
dnl AC_REQUIRE([AM_PROG_CC_STDC])dnl
|
||||
AC_REQUIRE([AC_PROG_CC_C_O])dnl
|
||||
AC_REQUIRE([AC_PROG_RANLIB])dnl
|
||||
|
||||
AC_CHECK_HEADERS(stdarg.h)
|
||||
|
||||
AC_CHECK_FUNCS(sigprocmask)
|
||||
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([TSRM_CHECK_PTH],[
|
||||
|
||||
AC_MSG_CHECKING(for GNU Pth)
|
||||
PTH_PREFIX="`$1 --prefix`"
|
||||
if test -z "$PTH_PREFIX"; then
|
||||
AC_MSG_RESULT(Please check your Pth installation)
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS `$1 --cflags`"
|
||||
LDFLAGS="$LDFLAGS `$1 --ldflags`"
|
||||
LIBS="$LIBS `$1 --libs`"
|
||||
|
||||
AC_DEFINE(GNUPTH, 1, [Whether you use GNU Pth])
|
||||
AC_MSG_RESULT(yes - installed in $PTH_PREFIX)
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([TSRM_CHECK_ST],[
|
||||
if test -r "$1/include/st.h"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$1/include"
|
||||
LDFLAGS="$LDFLAGS -L$1/lib"
|
||||
elif test -r "$1/st.h"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$1"
|
||||
LDFLAGS="$LDFLAGS -L$1"
|
||||
fi
|
||||
AC_CHECK_HEADERS(st.h,[],[
|
||||
AC_MSG_ERROR([Sorry[,] I was unable to locate the State Threads header file. Please specify the prefix using --with-tsrm-st=/prefix])
|
||||
])
|
||||
LIBS="$LIBS -lst"
|
||||
AC_MSG_CHECKING(for SGI's State Threads)
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(TSRM_ST, 1, [ ])
|
||||
])
|
||||
|
||||
sinclude(threads.m4)
|
||||
|
||||
AC_DEFUN([TSRM_CHECK_PTHREADS],[
|
||||
|
||||
PTHREADS_CHECK
|
||||
|
||||
if test "$beos_threads" = "1"; then
|
||||
AC_DEFINE(BETHREADS, 1, Whether to use native BeOS threads)
|
||||
else
|
||||
if test "$pthreads_working" != "yes"; then
|
||||
AC_MSG_ERROR(Your system seems to lack POSIX threads.)
|
||||
fi
|
||||
|
||||
AC_DEFINE(PTHREADS, 1, Whether to use Pthreads)
|
||||
|
||||
AC_MSG_CHECKING(for POSIX threads)
|
||||
AC_MSG_RESULT(yes)
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([TSRM_THREADS_CHECKS],[
|
||||
|
||||
dnl For the thread implementations, we always use --with-*
|
||||
dnl to maintain consistency
|
||||
|
||||
AC_ARG_WITH(tsrm-pth,
|
||||
[ --with-tsrm-pth[=pth-config]
|
||||
Use GNU Pth],[
|
||||
TSRM_PTH=$withval
|
||||
],[
|
||||
TSRM_PTH=no
|
||||
])
|
||||
|
||||
AC_ARG_WITH(tsrm-st,
|
||||
[ --with-tsrm-st Use SGI's State Threads],[
|
||||
TSRM_ST=$withval
|
||||
],[
|
||||
TSRM_ST=no
|
||||
])
|
||||
|
||||
AC_ARG_WITH(tsrm-pthreads,
|
||||
[ --with-tsrm-pthreads Use POSIX threads (default)],[
|
||||
TSRM_PTHREADS=$withval
|
||||
],[
|
||||
TSRM_PTHREADS=yes
|
||||
])
|
||||
|
||||
test "$TSRM_PTH" = "yes" && TSRM_PTH=pth-config
|
||||
|
||||
if test "$TSRM_PTH" != "no"; then
|
||||
TSRM_CHECK_PTH($TSRM_PTH)
|
||||
elif test "$TSRM_ST" != "no"; then
|
||||
TSRM_CHECK_ST($TSRM_ST)
|
||||
elif test "$TSRM_PTHREADS" != "no"; then
|
||||
TSRM_CHECK_PTHREADS
|
||||
fi
|
||||
|
||||
])
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef TSRM_CONFIG_W32_H
|
||||
#define TSRM_CONFIG_W32_H
|
||||
|
||||
#include <../main/config.w32.h>
|
||||
|
||||
#define HAVE_UTIME 1
|
||||
#define HAVE_ALLOCA 1
|
||||
#define HAVE_REALPATH 1
|
||||
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
|
||||
#undef inline
|
||||
#ifdef ZEND_WIN32_FORCE_INLINE
|
||||
# define inline __forceinline
|
||||
#else
|
||||
# define inline
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,70 +0,0 @@
|
||||
#ifndef TSRM_CONFIG_COMMON_H
|
||||
#define TSRM_CONFIG_COMMON_H
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
# if WINNT|WIN32
|
||||
# define TSRM_WIN32
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
# include "tsrm_config.w32.h"
|
||||
#else
|
||||
# include <tsrm_config.h>
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
|
||||
# include <alloca.h>
|
||||
#endif
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#ifndef __GNUC__
|
||||
# ifndef HAVE_ALLOCA_H
|
||||
# ifdef _AIX
|
||||
#pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
# ifndef NETWARE
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
# ifdef PATH_MAX
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
# elif defined(MAX_PATH)
|
||||
# define MAXPATHLEN MAX_PATH
|
||||
# else
|
||||
# define MAXPATHLEN 256
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2))
|
||||
# define TSRM_ALLOCA_MAX_SIZE 4096
|
||||
# define TSRM_ALLOCA_FLAG(name) \
|
||||
int name;
|
||||
# define tsrm_do_alloca_ex(size, limit, use_heap) \
|
||||
((use_heap = ((size) > (limit))) ? malloc(size) : alloca(size))
|
||||
# define tsrm_do_alloca(size, use_heap) \
|
||||
tsrm_do_alloca_ex(size, TSRM_ALLOCA_MAX_SIZE, use_heap)
|
||||
# define tsrm_free_alloca(p, use_heap) \
|
||||
do { if (use_heap) free(p); } while (0)
|
||||
#else
|
||||
# define TSRM_ALLOCA_FLAG(name)
|
||||
# define tsrm_do_alloca(p, use_heap) malloc(p)
|
||||
# define tsrm_free_alloca(p, use_heap) free(p)
|
||||
#endif
|
||||
|
||||
#endif /* TSRM_CONFIG_COMMON_H */
|
||||
-240
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2013 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Venkat Raghavan S <rvenkat@novell.com> |
|
||||
| Anantha Kesari H Y <hyanantha@novell.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "TSRM.h"
|
||||
|
||||
#ifdef NETWARE
|
||||
|
||||
#ifdef USE_MKFIFO
|
||||
#include <sys/stat.h>
|
||||
#elif !defined(USE_PIPE_OPEN) /* NXFifoOpen */
|
||||
#include <nks/fsio.h>
|
||||
#endif
|
||||
|
||||
#include <nks/vm.h>
|
||||
#include <nks/memory.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mktemp.h"
|
||||
|
||||
/* strtok() call in LibC is abending when used in a different address space
|
||||
* -- hence using PHP's version itself for now
|
||||
*/
|
||||
#include "tsrm_strtok_r.h"
|
||||
#define tsrm_strtok_r(a,b,c) strtok((a),(b))
|
||||
|
||||
#define WHITESPACE " \t"
|
||||
#define MAX_ARGS 10
|
||||
|
||||
|
||||
TSRM_API FILE* popen(const char *commandline, const char *type)
|
||||
{
|
||||
char *command = NULL, *argv[MAX_ARGS] = {'\0'}, **env = NULL;
|
||||
char *tempName = "sys:/php/temp/phpXXXXXX.tmp";
|
||||
char *filePath = NULL;
|
||||
char *ptr = NULL;
|
||||
int ptrLen = 0, argc = 0, i = 0, envCount = 0, err = 0;
|
||||
FILE *stream = NULL;
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
int pipe_handle;
|
||||
int mode = O_RDONLY;
|
||||
#else
|
||||
NXHandle_t pipe_handle;
|
||||
NXMode_t mode = NX_O_RDONLY;
|
||||
#endif
|
||||
NXExecEnvSpec_t envSpec;
|
||||
NXNameSpec_t nameSpec;
|
||||
NXVmId_t newVM = 0;
|
||||
|
||||
/* Check for validity of input parameters */
|
||||
if (!commandline || !type)
|
||||
return NULL;
|
||||
|
||||
/* Get temporary file name */
|
||||
filePath = mktemp(tempName);
|
||||
if (!filePath)
|
||||
return NULL;
|
||||
|
||||
/* Set pipe mode according to type -- for now allow only "r" or "w" */
|
||||
if (strcmp(type, "r") == 0)
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
mode = O_RDONLY;
|
||||
#else
|
||||
mode = NX_O_RDONLY;
|
||||
#endif
|
||||
else if (strcmp(type, "w") == 0)
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
mode = O_WRONLY;
|
||||
#else
|
||||
mode = NX_O_WRONLY;
|
||||
#endif
|
||||
else
|
||||
return NULL;
|
||||
|
||||
#ifdef USE_PIPE_OPEN
|
||||
pipe_handle = pipe_open(filePath, mode);
|
||||
if (pipe_handle == -1)
|
||||
return NULL;
|
||||
#elif defined(USE_MKFIFO)
|
||||
pipe_handle = mkfifo(filePath, mode);
|
||||
if (pipe_handle == -1)
|
||||
return NULL;
|
||||
#else
|
||||
/* - NetWare doesn't require first parameter
|
||||
* - Allowing LibC to choose the buffer size for now
|
||||
*/
|
||||
err = NXFifoOpen(0, filePath, mode, 0, &pipe_handle);
|
||||
if (err)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
/* Copy the environment variables in preparation for the spawn call */
|
||||
envCount = NXGetEnvCount() + 1; /* add one for NULL */
|
||||
env = (char **) NXMemAlloc(sizeof(char *) * envCount, 0);
|
||||
if (!env)
|
||||
return NULL;
|
||||
|
||||
err = NXCopyEnv(env, envCount);
|
||||
if (err) {
|
||||
NXMemFree (env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Separate commandline string into words */
|
||||
ptr = tsrm_strtok_r((char*)commandline, WHITESPACE, NULL);
|
||||
ptrLen = strlen(ptr);
|
||||
|
||||
command = (char*)malloc(ptrLen + 1);
|
||||
if (!command) {
|
||||
NXMemFree (env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy (command, ptr);
|
||||
|
||||
ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
|
||||
while (ptr && (argc < MAX_ARGS)) {
|
||||
ptrLen = strlen(ptr);
|
||||
|
||||
argv[argc] = (char*)malloc(ptrLen + 1);
|
||||
if (!argv[argc]) {
|
||||
NXMemFree (env);
|
||||
if (command)
|
||||
free (command);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i])
|
||||
free (argv[i]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy (argv[argc], ptr);
|
||||
argc++;
|
||||
ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
|
||||
}
|
||||
|
||||
/* Setup the execution environment and spawn new process */
|
||||
envSpec.esFlags = 0; /* Not used */
|
||||
envSpec.esArgc = argc;
|
||||
envSpec.esArgv = (void **) argv;
|
||||
envSpec.esEnv = (void **) env;
|
||||
|
||||
/* envSpec.esStdin.ssType = */
|
||||
envSpec.esStdout.ssType = NX_OBJ_FIFO;
|
||||
envSpec.esStderr.ssType = NX_OBJ_FILE;
|
||||
|
||||
/* 'ssHandle' is not a struct/union/class member */
|
||||
/*
|
||||
envSpec.esStdin.ssHandle =
|
||||
envSpec.esStdout.ssHandle =
|
||||
envSpec.esStderr.ssHandle = -1;
|
||||
*/
|
||||
envSpec.esStdin.ssPathCtx = NULL;
|
||||
envSpec.esStdout.ssPathCtx = NULL;
|
||||
envSpec.esStderr.ssPathCtx = NULL;
|
||||
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
if (mode == O_RDONLY) {
|
||||
#else
|
||||
if (mode == NX_O_RDONLY) {
|
||||
#endif
|
||||
envSpec.esStdin.ssPath = filePath;
|
||||
envSpec.esStdout.ssPath = stdout;
|
||||
} else { /* Write Only */
|
||||
envSpec.esStdin.ssPath = stdin;
|
||||
envSpec.esStdout.ssPath = filePath;
|
||||
}
|
||||
|
||||
envSpec.esStderr.ssPath = stdout;
|
||||
|
||||
nameSpec.ssType = NX_OBJ_FIFO;
|
||||
/* nameSpec.ssHandle = 0; */ /* 'ssHandle' is not a struct/union/class member */
|
||||
nameSpec.ssPathCtx = NULL; /* Not used */
|
||||
nameSpec.ssPath = argv[0];
|
||||
err = NXVmSpawn(&nameSpec, &envSpec, 0, &newVM);
|
||||
if (!err)
|
||||
/* Get file pointer corresponding to the pipe (file) opened */
|
||||
stream = fdopen(pipe_handle, type);
|
||||
|
||||
/* Clean-up */
|
||||
if (env)
|
||||
NXMemFree (env);
|
||||
|
||||
if (pipe_handle)
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
close(pipe_handle);
|
||||
#else
|
||||
NXClose(pipe_handle);
|
||||
#endif
|
||||
|
||||
if (command)
|
||||
free (command);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i])
|
||||
free (argv[i]);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
TSRM_API int pclose(FILE* stream)
|
||||
{
|
||||
int err = 0;
|
||||
NXHandle_t fd = 0;
|
||||
|
||||
/* Get the process associated with this pipe (file) handle and terminate it */
|
||||
fd = fileno(stream);
|
||||
NXClose (fd);
|
||||
|
||||
err = fclose(stream);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* NETWARE */
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2013 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Venkat Raghavan S <rvenkat@novell.com> |
|
||||
| Anantha Kesari H Y <hyanantha@novell.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TSRM_NW_H
|
||||
#define TSRM_NW_H
|
||||
|
||||
#include "TSRM.h"
|
||||
|
||||
TSRM_API FILE* popen(const char *command, const char *type);
|
||||
TSRM_API int pclose(FILE* stream);
|
||||
|
||||
#endif
|
||||
@@ -1,63 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tsrm_config_common.h"
|
||||
#include "tsrm_strtok_r.h"
|
||||
|
||||
static inline int in_character_class(char ch, const char *delim)
|
||||
{
|
||||
while (*delim) {
|
||||
if (*delim == ch) {
|
||||
return 1;
|
||||
}
|
||||
delim++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *tsrm_strtok_r(char *s, const char *delim, char **last)
|
||||
{
|
||||
char *token;
|
||||
|
||||
if (s == NULL) {
|
||||
s = *last;
|
||||
}
|
||||
|
||||
while (*s && in_character_class(*s, delim)) {
|
||||
s++;
|
||||
}
|
||||
if (!*s) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
token = s;
|
||||
|
||||
while (*s && !in_character_class(*s, delim)) {
|
||||
s++;
|
||||
}
|
||||
if (!*s) {
|
||||
*last = s;
|
||||
} else {
|
||||
*s = '\0';
|
||||
*last = s + 1;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
main()
|
||||
{
|
||||
char foo[] = "/foo/bar//\\barbara";
|
||||
char *last;
|
||||
char *token;
|
||||
|
||||
token = tsrm_strtok_r(foo, "/\\", &last);
|
||||
while (token) {
|
||||
printf ("Token = '%s'\n", token);
|
||||
token = tsrm_strtok_r(NULL, "/\\", &last);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef TSRM_STRTOK_R
|
||||
#define TSRM_STRTOK_R
|
||||
|
||||
char *tsrm_strtok_r(char *s, const char *delim, char **last);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,338 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2013 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Sascha Schumann <sascha@schumann.cx> |
|
||||
| Pierre Joye <pierre@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef VIRTUAL_CWD_H
|
||||
#define VIRTUAL_CWD_H
|
||||
|
||||
#include "TSRM.h"
|
||||
#include "tsrm_config_common.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_UTIME_H
|
||||
#include <utime.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#define VIRTUAL_DIR
|
||||
#endif
|
||||
|
||||
#ifndef TSRM_WIN32
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
#if defined(__osf__) || defined(_AIX)
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
#include "readdir.h"
|
||||
#include <sys/utime.h>
|
||||
/* mode_t isn't defined on Windows */
|
||||
typedef unsigned short mode_t;
|
||||
|
||||
#define DEFAULT_SLASH '\\'
|
||||
#define DEFAULT_DIR_SEPARATOR ';'
|
||||
#define IS_SLASH(c) ((c) == '/' || (c) == '\\')
|
||||
#define IS_SLASH_P(c) (*(c) == '/' || \
|
||||
(*(c) == '\\' && !IsDBCSLeadByte(*(c-1))))
|
||||
|
||||
/* COPY_WHEN_ABSOLUTE is 2 under Win32 because by chance both regular absolute paths
|
||||
in the file system and UNC paths need copying of two characters */
|
||||
#define COPY_WHEN_ABSOLUTE(path) 2
|
||||
#define IS_UNC_PATH(path, len) \
|
||||
(len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1]))
|
||||
#define IS_ABSOLUTE_PATH(path, len) \
|
||||
(len >= 2 && ((isalpha(path[0]) && path[1] == ':') || IS_UNC_PATH(path, len)))
|
||||
|
||||
#elif defined(NETWARE)
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#define DEFAULT_SLASH '/'
|
||||
#define DEFAULT_DIR_SEPARATOR ';'
|
||||
#define IS_SLASH(c) ((c) == '/' || (c) == '\\')
|
||||
#define IS_SLASH_P(c) IS_SLASH(*(c))
|
||||
/* Colon indicates volume name, either first character should be forward slash or backward slash */
|
||||
#define IS_ABSOLUTE_PATH(path, len) \
|
||||
((strchr(path, ':') != NULL) || ((len >= 1) && ((path[0] == '/') || (path[0] == '\\'))))
|
||||
|
||||
#else
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#define DEFAULT_SLASH '/'
|
||||
|
||||
#ifdef __riscos__
|
||||
#define DEFAULT_DIR_SEPARATOR ';'
|
||||
#else
|
||||
#define DEFAULT_DIR_SEPARATOR ':'
|
||||
#endif
|
||||
|
||||
#define IS_SLASH(c) ((c) == '/')
|
||||
#define IS_SLASH_P(c) (*(c) == '/')
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef COPY_WHEN_ABSOLUTE
|
||||
#define COPY_WHEN_ABSOLUTE(path) 0
|
||||
#endif
|
||||
|
||||
#ifndef IS_ABSOLUTE_PATH
|
||||
#define IS_ABSOLUTE_PATH(path, len) \
|
||||
(IS_SLASH(path[0]))
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_EXPORTS
|
||||
#define CWD_EXPORTS
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
# ifdef CWD_EXPORTS
|
||||
# define CWD_API __declspec(dllexport)
|
||||
# else
|
||||
# define CWD_API __declspec(dllimport)
|
||||
# endif
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define CWD_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
# define CWD_API
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat);
|
||||
# define php_sys_stat(path, buf) php_sys_stat_ex(path, buf, 0)
|
||||
# define php_sys_lstat(path, buf) php_sys_stat_ex(path, buf, 1)
|
||||
CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len);
|
||||
#else
|
||||
# define php_sys_stat stat
|
||||
# define php_sys_lstat lstat
|
||||
# ifdef HAVE_SYMLINK
|
||||
# define php_sys_readlink(link, target, target_len) readlink(link, target, target_len)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef struct _cwd_state {
|
||||
char *cwd;
|
||||
int cwd_length;
|
||||
} cwd_state;
|
||||
|
||||
typedef int (*verify_path_func)(const cwd_state *);
|
||||
|
||||
CWD_API void virtual_cwd_startup(void);
|
||||
CWD_API void virtual_cwd_shutdown(void);
|
||||
CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
|
||||
CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC);
|
||||
CWD_API int virtual_chdir(const char *path TSRMLS_DC);
|
||||
CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path TSRMLS_DC) TSRMLS_DC);
|
||||
CWD_API int virtual_filepath(const char *path, char **filepath TSRMLS_DC);
|
||||
CWD_API int virtual_filepath_ex(const char *path, char **filepath, verify_path_func verify_path TSRMLS_DC);
|
||||
CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC);
|
||||
CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC);
|
||||
CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...);
|
||||
CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC);
|
||||
CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC);
|
||||
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC);
|
||||
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC);
|
||||
CWD_API int virtual_unlink(const char *path TSRMLS_DC);
|
||||
CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC);
|
||||
CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC);
|
||||
CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC);
|
||||
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC);
|
||||
CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC);
|
||||
#if defined(TSRM_WIN32)
|
||||
/* these are not defined in win32 headers */
|
||||
#ifndef W_OK
|
||||
#define W_OK 0x02
|
||||
#endif
|
||||
#ifndef R_OK
|
||||
#define R_OK 0x04
|
||||
#endif
|
||||
#ifndef X_OK
|
||||
#define X_OK 0x01
|
||||
#endif
|
||||
#ifndef F_OK
|
||||
#define F_OK 0x00
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_UTIME
|
||||
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC);
|
||||
#endif
|
||||
CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC);
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link TSRMLS_DC);
|
||||
#endif
|
||||
|
||||
/* One of the following constants must be used as the last argument
|
||||
in virtual_file_ex() call. */
|
||||
|
||||
#define CWD_EXPAND 0 /* expand "." and ".." but dont resolve symlinks */
|
||||
#define CWD_FILEPATH 1 /* resolve symlinks if file is exist otherwise expand */
|
||||
#define CWD_REALPATH 2 /* call realpath(), resolve symlinks. File must exist */
|
||||
|
||||
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath TSRMLS_DC);
|
||||
|
||||
CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC);
|
||||
|
||||
#define REALPATH_CACHE_TTL (2*60) /* 2 minutes */
|
||||
#define REALPATH_CACHE_SIZE 0 /* disabled while php.ini isn't loaded */
|
||||
|
||||
typedef struct _realpath_cache_bucket {
|
||||
unsigned long key;
|
||||
char *path;
|
||||
int path_len;
|
||||
char *realpath;
|
||||
int realpath_len;
|
||||
int is_dir;
|
||||
time_t expires;
|
||||
#ifdef PHP_WIN32
|
||||
unsigned char is_rvalid;
|
||||
unsigned char is_readable;
|
||||
unsigned char is_wvalid;
|
||||
unsigned char is_writable;
|
||||
#endif
|
||||
struct _realpath_cache_bucket *next;
|
||||
} realpath_cache_bucket;
|
||||
|
||||
typedef struct _virtual_cwd_globals {
|
||||
cwd_state cwd;
|
||||
long realpath_cache_size;
|
||||
long realpath_cache_size_limit;
|
||||
long realpath_cache_ttl;
|
||||
realpath_cache_bucket *realpath_cache[1024];
|
||||
} virtual_cwd_globals;
|
||||
|
||||
#ifdef ZTS
|
||||
extern ts_rsrc_id cwd_globals_id;
|
||||
# define CWDG(v) TSRMG(cwd_globals_id, virtual_cwd_globals *, v)
|
||||
#else
|
||||
extern virtual_cwd_globals cwd_globals;
|
||||
# define CWDG(v) (cwd_globals.v)
|
||||
#endif
|
||||
|
||||
CWD_API void realpath_cache_clean(TSRMLS_D);
|
||||
CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC);
|
||||
CWD_API realpath_cache_bucket* realpath_cache_lookup(const char *path, int path_len, time_t t TSRMLS_DC);
|
||||
CWD_API int realpath_cache_size(TSRMLS_D);
|
||||
CWD_API int realpath_cache_max_buckets(TSRMLS_D);
|
||||
CWD_API realpath_cache_bucket** realpath_cache_get_buckets(TSRMLS_D);
|
||||
|
||||
/* The actual macros to be used in programs using TSRM
|
||||
* If the program defines VIRTUAL_DIR it will use the
|
||||
* virtual_* functions
|
||||
*/
|
||||
|
||||
#ifdef VIRTUAL_DIR
|
||||
|
||||
#define VCWD_GETCWD(buff, size) virtual_getcwd(buff, size TSRMLS_CC)
|
||||
#define VCWD_FOPEN(path, mode) virtual_fopen(path, mode TSRMLS_CC)
|
||||
/* Because open() has two modes, we have to macros to replace it */
|
||||
#define VCWD_OPEN(path, flags) virtual_open(path TSRMLS_CC, flags)
|
||||
#define VCWD_OPEN_MODE(path, flags, mode) virtual_open(path TSRMLS_CC, flags, mode)
|
||||
#define VCWD_CREAT(path, mode) virtual_creat(path, mode TSRMLS_CC)
|
||||
#define VCWD_CHDIR(path) virtual_chdir(path TSRMLS_CC)
|
||||
#define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, virtual_chdir TSRMLS_CC)
|
||||
#define VCWD_GETWD(buf)
|
||||
#define VCWD_REALPATH(path, real_path) virtual_realpath(path, real_path TSRMLS_CC)
|
||||
#define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC)
|
||||
#define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
|
||||
# define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
|
||||
#define VCWD_UNLINK(path) virtual_unlink(path TSRMLS_CC)
|
||||
#define VCWD_MKDIR(pathname, mode) virtual_mkdir(pathname, mode TSRMLS_CC)
|
||||
#define VCWD_RMDIR(pathname) virtual_rmdir(pathname TSRMLS_CC)
|
||||
#define VCWD_OPENDIR(pathname) virtual_opendir(pathname TSRMLS_CC)
|
||||
#define VCWD_POPEN(command, type) virtual_popen(command, type TSRMLS_CC)
|
||||
#define VCWD_ACCESS(pathname, mode) virtual_access(pathname, mode TSRMLS_CC)
|
||||
#if HAVE_UTIME
|
||||
#define VCWD_UTIME(path, time) virtual_utime(path, time TSRMLS_CC)
|
||||
#endif
|
||||
#define VCWD_CHMOD(path, mode) virtual_chmod(path, mode TSRMLS_CC)
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
#define VCWD_CHOWN(path, owner, group) virtual_chown(path, owner, group, 0 TSRMLS_CC)
|
||||
#if HAVE_LCHOWN
|
||||
#define VCWD_LCHOWN(path, owner, group) virtual_chown(path, owner, group, 1 TSRMLS_CC)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define VCWD_GETCWD(buff, size) getcwd(buff, size)
|
||||
#define VCWD_FOPEN(path, mode) fopen(path, mode)
|
||||
#define VCWD_OPEN(path, flags) open(path, flags)
|
||||
#define VCWD_OPEN_MODE(path, flags, mode) open(path, flags, mode)
|
||||
#define VCWD_CREAT(path, mode) creat(path, mode)
|
||||
/* rename on windows will fail if newname already exists.
|
||||
MoveFileEx has to be used */
|
||||
#if defined(TSRM_WIN32)
|
||||
# define VCWD_RENAME(oldname, newname) (MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED) == 0 ? -1 : 0)
|
||||
#else
|
||||
# define VCWD_RENAME(oldname, newname) rename(oldname, newname)
|
||||
#endif
|
||||
#define VCWD_CHDIR(path) chdir(path)
|
||||
#define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, chdir)
|
||||
#define VCWD_GETWD(buf) getwd(buf)
|
||||
#define VCWD_STAT(path, buff) php_sys_stat(path, buff)
|
||||
#define VCWD_LSTAT(path, buff) lstat(path, buff)
|
||||
#define VCWD_UNLINK(path) unlink(path)
|
||||
#define VCWD_MKDIR(pathname, mode) mkdir(pathname, mode)
|
||||
#define VCWD_RMDIR(pathname) rmdir(pathname)
|
||||
#define VCWD_OPENDIR(pathname) opendir(pathname)
|
||||
#define VCWD_POPEN(command, type) popen(command, type)
|
||||
#if defined(TSRM_WIN32)
|
||||
#define VCWD_ACCESS(pathname, mode) tsrm_win32_access(pathname, mode TSRMLS_CC)
|
||||
#else
|
||||
#define VCWD_ACCESS(pathname, mode) access(pathname, mode)
|
||||
#endif
|
||||
|
||||
#define VCWD_REALPATH(path, real_path) tsrm_realpath(path, real_path TSRMLS_CC)
|
||||
|
||||
#if HAVE_UTIME
|
||||
# ifdef TSRM_WIN32
|
||||
# define VCWD_UTIME(path, time) win32_utime(path, time)
|
||||
# else
|
||||
# define VCWD_UTIME(path, time) utime(path, time)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define VCWD_CHMOD(path, mode) chmod(path, mode)
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
#define VCWD_CHOWN(path, owner, group) chown(path, owner, group)
|
||||
#if HAVE_LCHOWN
|
||||
#define VCWD_LCHOWN(path, owner, group) lchown(path, owner, group)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* VIRTUAL_CWD_H */
|
||||
@@ -1,723 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2013 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Daniel Beulshausen <daniel@php4win.de> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define TSRM_INCLUDE_FULL_WINDOWS_HEADERS
|
||||
#include "SAPI.h"
|
||||
#include "TSRM.h"
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
#include <Sddl.h>
|
||||
#include "tsrm_win32.h"
|
||||
#include "tsrm_virtual_cwd.h"
|
||||
|
||||
#ifdef ZTS
|
||||
static ts_rsrc_id win32_globals_id;
|
||||
#else
|
||||
static tsrm_win32_globals win32_globals;
|
||||
#endif
|
||||
|
||||
static void tsrm_win32_ctor(tsrm_win32_globals *globals TSRMLS_DC)
|
||||
{
|
||||
globals->process = NULL;
|
||||
globals->shm = NULL;
|
||||
globals->process_size = 0;
|
||||
globals->shm_size = 0;
|
||||
globals->comspec = _strdup((GetVersion()<0x80000000)?"cmd.exe":"command.com");
|
||||
|
||||
/* Set it to INVALID_HANDLE_VALUE
|
||||
* It will be initialized correctly in tsrm_win32_access or set to
|
||||
* NULL if no impersonation has been done.
|
||||
* the impersonated token can't be set here as the impersonation
|
||||
* will happen later, in fcgi_accept_request (or whatever is the
|
||||
* SAPI being used).
|
||||
*/
|
||||
globals->impersonation_token = INVALID_HANDLE_VALUE;
|
||||
globals->impersonation_token_sid = NULL;
|
||||
}
|
||||
|
||||
static void tsrm_win32_dtor(tsrm_win32_globals *globals TSRMLS_DC)
|
||||
{
|
||||
shm_pair *ptr;
|
||||
|
||||
if (globals->process) {
|
||||
free(globals->process);
|
||||
}
|
||||
|
||||
if (globals->shm) {
|
||||
for (ptr = globals->shm; ptr < (globals->shm + globals->shm_size); ptr++) {
|
||||
UnmapViewOfFile(ptr->addr);
|
||||
CloseHandle(ptr->segment);
|
||||
UnmapViewOfFile(ptr->descriptor);
|
||||
CloseHandle(ptr->info);
|
||||
}
|
||||
free(globals->shm);
|
||||
}
|
||||
|
||||
free(globals->comspec);
|
||||
|
||||
if (globals->impersonation_token && globals->impersonation_token != INVALID_HANDLE_VALUE ) {
|
||||
CloseHandle(globals->impersonation_token);
|
||||
}
|
||||
if (globals->impersonation_token_sid) {
|
||||
free(globals->impersonation_token_sid);
|
||||
}
|
||||
}
|
||||
|
||||
TSRM_API void tsrm_win32_startup(void)
|
||||
{
|
||||
#ifdef ZTS
|
||||
ts_allocate_id(&win32_globals_id, sizeof(tsrm_win32_globals), (ts_allocate_ctor)tsrm_win32_ctor, (ts_allocate_ctor)tsrm_win32_dtor);
|
||||
#else
|
||||
tsrm_win32_ctor(&win32_globals TSRMLS_CC);
|
||||
#endif
|
||||
}
|
||||
|
||||
TSRM_API void tsrm_win32_shutdown(void)
|
||||
{
|
||||
#ifndef ZTS
|
||||
tsrm_win32_dtor(&win32_globals TSRMLS_CC);
|
||||
#endif
|
||||
}
|
||||
|
||||
char * tsrm_win32_get_path_sid_key(const char *pathname TSRMLS_DC)
|
||||
{
|
||||
PSID pSid = TWG(impersonation_token_sid);
|
||||
DWORD sid_len = pSid ? GetLengthSid(pSid) : 0;
|
||||
TCHAR *ptcSid = NULL;
|
||||
char *bucket_key = NULL;
|
||||
|
||||
if (!pSid) {
|
||||
bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, strlen(pathname) + 1);
|
||||
if (!bucket_key) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(bucket_key, pathname, strlen(pathname));
|
||||
return bucket_key;
|
||||
}
|
||||
|
||||
if (!ConvertSidToStringSid(pSid, &ptcSid)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, strlen(pathname) + strlen(ptcSid) + 1);
|
||||
if (!bucket_key) {
|
||||
LocalFree(ptcSid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(bucket_key, ptcSid, strlen(ptcSid));
|
||||
memcpy(bucket_key + strlen(ptcSid), pathname, strlen(pathname) + 1);
|
||||
|
||||
LocalFree(ptcSid);
|
||||
return bucket_key;
|
||||
}
|
||||
|
||||
|
||||
PSID tsrm_win32_get_token_sid(HANDLE hToken)
|
||||
{
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD dwLength = 0;
|
||||
PTOKEN_USER pTokenUser = NULL;
|
||||
PSID sid;
|
||||
PSID *ppsid = &sid;
|
||||
DWORD sid_len;
|
||||
PSID pResultSid = NULL;
|
||||
|
||||
/* Get the actual size of the TokenUser structure */
|
||||
if (!GetTokenInformation(
|
||||
hToken, TokenUser, (LPVOID) pTokenUser, 0, &dwLength)) {
|
||||
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
pTokenUser = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
|
||||
if (pTokenUser == NULL) {
|
||||
goto Finished;
|
||||
}
|
||||
}
|
||||
|
||||
/* and fetch it now */
|
||||
if (!GetTokenInformation(
|
||||
hToken, TokenUser, (LPVOID) pTokenUser, dwLength, &dwLength)) {
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
sid_len = GetLengthSid(pTokenUser->User.Sid);
|
||||
|
||||
/* ConvertSidToStringSid(pTokenUser->User.Sid, &ptcSidOwner); */
|
||||
pResultSid = malloc(sid_len);
|
||||
if (!pResultSid) {
|
||||
goto Finished;
|
||||
}
|
||||
if (!CopySid(sid_len, pResultSid, pTokenUser->User.Sid)) {
|
||||
goto Finished;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, (LPVOID)pTokenUser);
|
||||
return pResultSid;
|
||||
|
||||
Finished:
|
||||
if (pResultSid) {
|
||||
free(pResultSid);
|
||||
}
|
||||
/* Free the buffer for the token groups. */
|
||||
if (pTokenUser != NULL) {
|
||||
HeapFree(GetProcessHeap(), 0, (LPVOID)pTokenUser);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TSRM_API int tsrm_win32_access(const char *pathname, int mode TSRMLS_DC)
|
||||
{
|
||||
time_t t;
|
||||
HANDLE thread_token = NULL;
|
||||
PSID token_sid;
|
||||
SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
|
||||
GENERIC_MAPPING gen_map = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS };
|
||||
DWORD priv_set_length = sizeof(PRIVILEGE_SET);
|
||||
|
||||
PRIVILEGE_SET privilege_set = {0};
|
||||
DWORD sec_desc_length = 0, desired_access = 0, granted_access = 0;
|
||||
BYTE * psec_desc = NULL;
|
||||
BOOL fAccess = FALSE;
|
||||
|
||||
BOOL bucket_key_alloc = FALSE;
|
||||
realpath_cache_bucket * bucket = NULL;
|
||||
char * real_path = NULL;
|
||||
|
||||
if (mode == 1 /*X_OK*/) {
|
||||
DWORD type;
|
||||
return GetBinaryType(pathname, &type) ? 0 : -1;
|
||||
} else {
|
||||
if(!IS_ABSOLUTE_PATH(pathname, strlen(pathname)+1)) {
|
||||
real_path = (char *)malloc(MAX_PATH);
|
||||
if(tsrm_realpath(pathname, real_path TSRMLS_CC) == NULL) {
|
||||
goto Finished;
|
||||
}
|
||||
pathname = real_path;
|
||||
}
|
||||
|
||||
if(access(pathname, mode)) {
|
||||
free(real_path);
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* If only existence check is made, return now */
|
||||
if (mode == 0) {
|
||||
free(real_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only in NTS when impersonate==1 (aka FastCGI) */
|
||||
|
||||
/*
|
||||
AccessCheck() requires an impersonation token. We first get a primary
|
||||
token and then create a duplicate impersonation token. The
|
||||
impersonation token is not actually assigned to the thread, but is
|
||||
used in the call to AccessCheck. Thus, this function itself never
|
||||
impersonates, but does use the identity of the thread. If the thread
|
||||
was impersonating already, this function uses that impersonation context.
|
||||
*/
|
||||
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) {
|
||||
DWORD err = GetLastError();
|
||||
if (GetLastError() == ERROR_NO_TOKEN) {
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &thread_token)) {
|
||||
TWG(impersonation_token) = NULL;
|
||||
goto Finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* token_sid will be freed in tsrmwin32_dtor */
|
||||
token_sid = tsrm_win32_get_token_sid(thread_token);
|
||||
if (!token_sid) {
|
||||
if (TWG(impersonation_token_sid)) {
|
||||
free(TWG(impersonation_token_sid));
|
||||
}
|
||||
TWG(impersonation_token_sid) = NULL;
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
/* Different identity, we need a new impersontated token as well */
|
||||
if (!TWG(impersonation_token_sid) || !EqualSid(token_sid, TWG(impersonation_token_sid))) {
|
||||
if (TWG(impersonation_token_sid)) {
|
||||
free(TWG(impersonation_token_sid));
|
||||
}
|
||||
TWG(impersonation_token_sid) = token_sid;
|
||||
|
||||
/* Duplicate the token as impersonated token */
|
||||
if (!DuplicateToken(thread_token, SecurityImpersonation, &TWG(impersonation_token))) {
|
||||
goto Finished;
|
||||
}
|
||||
} else {
|
||||
/* we already have it, free it then */
|
||||
free(token_sid);
|
||||
}
|
||||
|
||||
if (CWDG(realpath_cache_size_limit)) {
|
||||
t = time(0);
|
||||
bucket = realpath_cache_lookup(pathname, strlen(pathname), t TSRMLS_CC);
|
||||
if(bucket == NULL && real_path == NULL) {
|
||||
/* We used the pathname directly. Call tsrm_realpath */
|
||||
/* so that entry is created in realpath cache */
|
||||
real_path = (char *)malloc(MAX_PATH);
|
||||
if(tsrm_realpath(pathname, real_path TSRMLS_CC) != NULL) {
|
||||
pathname = real_path;
|
||||
bucket = realpath_cache_lookup(pathname, strlen(pathname), t TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do a full access check because access() will only check read-only attribute */
|
||||
if(mode == 0 || mode > 6) {
|
||||
if(bucket != NULL && bucket->is_rvalid) {
|
||||
fAccess = bucket->is_readable;
|
||||
goto Finished;
|
||||
}
|
||||
desired_access = FILE_GENERIC_READ;
|
||||
} else if(mode <= 2) {
|
||||
if(bucket != NULL && bucket->is_wvalid) {
|
||||
fAccess = bucket->is_writable;
|
||||
goto Finished;
|
||||
}
|
||||
desired_access = FILE_GENERIC_WRITE;
|
||||
} else if(mode <= 4) {
|
||||
if(bucket != NULL && bucket->is_rvalid) {
|
||||
fAccess = bucket->is_readable;
|
||||
goto Finished;
|
||||
}
|
||||
desired_access = FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS;
|
||||
} else { // if(mode <= 6)
|
||||
if(bucket != NULL && bucket->is_rvalid && bucket->is_wvalid) {
|
||||
fAccess = bucket->is_readable & bucket->is_writable;
|
||||
goto Finished;
|
||||
}
|
||||
desired_access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
|
||||
}
|
||||
|
||||
if(TWG(impersonation_token) == NULL) {
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
/* Get size of security buffer. Call is expected to fail */
|
||||
if(GetFileSecurity(pathname, sec_info, NULL, 0, &sec_desc_length)) {
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
psec_desc = (BYTE *)malloc(sec_desc_length);
|
||||
if(psec_desc == NULL ||
|
||||
!GetFileSecurity(pathname, sec_info, (PSECURITY_DESCRIPTOR)psec_desc, sec_desc_length, &sec_desc_length)) {
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
MapGenericMask(&desired_access, &gen_map);
|
||||
|
||||
if(!AccessCheck((PSECURITY_DESCRIPTOR)psec_desc, TWG(impersonation_token), desired_access, &gen_map, &privilege_set, &priv_set_length, &granted_access, &fAccess)) {
|
||||
goto Finished_Impersonate;
|
||||
}
|
||||
|
||||
/* Keep the result in realpath_cache */
|
||||
if(bucket != NULL) {
|
||||
if(desired_access == (FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS)) {
|
||||
bucket->is_rvalid = 1;
|
||||
bucket->is_readable = fAccess;
|
||||
}
|
||||
else if(desired_access == FILE_GENERIC_WRITE) {
|
||||
bucket->is_wvalid = 1;
|
||||
bucket->is_writable = fAccess;
|
||||
} else if (desired_access == (FILE_GENERIC_READ | FILE_GENERIC_WRITE)) {
|
||||
bucket->is_rvalid = 1;
|
||||
bucket->is_readable = fAccess;
|
||||
bucket->is_wvalid = 1;
|
||||
bucket->is_writable = fAccess;
|
||||
}
|
||||
}
|
||||
|
||||
Finished_Impersonate:
|
||||
if(psec_desc != NULL) {
|
||||
free(psec_desc);
|
||||
psec_desc = NULL;
|
||||
}
|
||||
|
||||
Finished:
|
||||
if(thread_token != NULL) {
|
||||
CloseHandle(thread_token);
|
||||
}
|
||||
if(real_path != NULL) {
|
||||
free(real_path);
|
||||
real_path = NULL;
|
||||
}
|
||||
|
||||
if(fAccess == FALSE) {
|
||||
errno = EACCES;
|
||||
return errno;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static process_pair *process_get(FILE *stream TSRMLS_DC)
|
||||
{
|
||||
process_pair *ptr;
|
||||
process_pair *newptr;
|
||||
|
||||
for (ptr = TWG(process); ptr < (TWG(process) + TWG(process_size)); ptr++) {
|
||||
if (ptr->stream == stream) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr < (TWG(process) + TWG(process_size))) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
newptr = (process_pair*)realloc((void*)TWG(process), (TWG(process_size)+1)*sizeof(process_pair));
|
||||
if (newptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TWG(process) = newptr;
|
||||
ptr = newptr + TWG(process_size);
|
||||
TWG(process_size)++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static shm_pair *shm_get(int key, void *addr)
|
||||
{
|
||||
shm_pair *ptr;
|
||||
shm_pair *newptr;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
for (ptr = TWG(shm); ptr < (TWG(shm) + TWG(shm_size)); ptr++) {
|
||||
if (!ptr->descriptor) {
|
||||
continue;
|
||||
}
|
||||
if (!addr && ptr->descriptor->shm_perm.key == key) {
|
||||
break;
|
||||
} else if (ptr->addr == addr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr < (TWG(shm) + TWG(shm_size))) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
newptr = (shm_pair*)realloc((void*)TWG(shm), (TWG(shm_size)+1)*sizeof(shm_pair));
|
||||
if (newptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TWG(shm) = newptr;
|
||||
ptr = newptr + TWG(shm_size);
|
||||
TWG(shm_size)++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static HANDLE dupHandle(HANDLE fh, BOOL inherit) {
|
||||
HANDLE copy, self = GetCurrentProcess();
|
||||
if (!DuplicateHandle(self, fh, self, ©, 0, inherit, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE)) {
|
||||
return NULL;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
TSRM_API FILE *popen(const char *command, const char *type)
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
|
||||
return popen_ex(command, type, NULL, NULL TSRMLS_CC);
|
||||
}
|
||||
|
||||
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env TSRMLS_DC)
|
||||
{
|
||||
FILE *stream = NULL;
|
||||
int fno, type_len = strlen(type), read, mode;
|
||||
STARTUPINFO startup;
|
||||
PROCESS_INFORMATION process;
|
||||
SECURITY_ATTRIBUTES security;
|
||||
HANDLE in, out;
|
||||
DWORD dwCreateFlags = 0;
|
||||
BOOL res;
|
||||
process_pair *proc;
|
||||
char *cmd;
|
||||
int i;
|
||||
char *ptype = (char *)type;
|
||||
HANDLE thread_token = NULL;
|
||||
HANDLE token_user = NULL;
|
||||
BOOL asuser = TRUE;
|
||||
|
||||
if (!type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*The following two checks can be removed once we drop XP support */
|
||||
type_len = strlen(type);
|
||||
if (type_len <1 || type_len > 2) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i < type_len; i++) {
|
||||
if (!(*ptype == 'r' || *ptype == 'w' || *ptype == 'b' || *ptype == 't')) {
|
||||
return NULL;
|
||||
}
|
||||
ptype++;
|
||||
}
|
||||
|
||||
security.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
security.bInheritHandle = TRUE;
|
||||
security.lpSecurityDescriptor = NULL;
|
||||
|
||||
if (!type_len || !CreatePipe(&in, &out, &security, 2048L)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(&startup, 0, sizeof(STARTUPINFO));
|
||||
memset(&process, 0, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
startup.cb = sizeof(STARTUPINFO);
|
||||
startup.dwFlags = STARTF_USESTDHANDLES;
|
||||
startup.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
||||
read = (type[0] == 'r') ? TRUE : FALSE;
|
||||
mode = ((type_len == 2) && (type[1] == 'b')) ? O_BINARY : O_TEXT;
|
||||
|
||||
if (read) {
|
||||
in = dupHandle(in, FALSE);
|
||||
startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
startup.hStdOutput = out;
|
||||
} else {
|
||||
out = dupHandle(out, FALSE);
|
||||
startup.hStdInput = in;
|
||||
startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
}
|
||||
|
||||
dwCreateFlags = NORMAL_PRIORITY_CLASS;
|
||||
if (strcmp(sapi_module.name, "cli") != 0) {
|
||||
dwCreateFlags |= CREATE_NO_WINDOW;
|
||||
}
|
||||
|
||||
/* Get a token with the impersonated user. */
|
||||
if(OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) {
|
||||
DuplicateTokenEx(thread_token, MAXIMUM_ALLOWED, &security, SecurityImpersonation, TokenPrimary, &token_user);
|
||||
} else {
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_NO_TOKEN) {
|
||||
asuser = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c ")+2);
|
||||
if (!cmd) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sprintf(cmd, "%s /c \"%s\"", TWG(comspec), command);
|
||||
if (asuser) {
|
||||
res = CreateProcessAsUser(token_user, NULL, cmd, &security, &security, security.bInheritHandle, dwCreateFlags, env, cwd, &startup, &process);
|
||||
CloseHandle(token_user);
|
||||
} else {
|
||||
res = CreateProcess(NULL, cmd, &security, &security, security.bInheritHandle, dwCreateFlags, env, cwd, &startup, &process);
|
||||
}
|
||||
free(cmd);
|
||||
|
||||
if (!res) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CloseHandle(process.hThread);
|
||||
proc = process_get(NULL TSRMLS_CC);
|
||||
|
||||
if (read) {
|
||||
fno = _open_osfhandle((tsrm_intptr_t)in, _O_RDONLY | mode);
|
||||
CloseHandle(out);
|
||||
} else {
|
||||
fno = _open_osfhandle((tsrm_intptr_t)out, _O_WRONLY | mode);
|
||||
CloseHandle(in);
|
||||
}
|
||||
|
||||
stream = _fdopen(fno, type);
|
||||
proc->prochnd = process.hProcess;
|
||||
proc->stream = stream;
|
||||
return stream;
|
||||
}
|
||||
|
||||
TSRM_API int pclose(FILE *stream)
|
||||
{
|
||||
DWORD termstat = 0;
|
||||
process_pair *process;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if ((process = process_get(stream TSRMLS_CC)) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fflush(process->stream);
|
||||
fclose(process->stream);
|
||||
|
||||
WaitForSingleObject(process->prochnd, INFINITE);
|
||||
GetExitCodeProcess(process->prochnd, &termstat);
|
||||
process->stream = NULL;
|
||||
CloseHandle(process->prochnd);
|
||||
|
||||
return termstat;
|
||||
}
|
||||
|
||||
TSRM_API int shmget(int key, int size, int flags)
|
||||
{
|
||||
shm_pair *shm;
|
||||
char shm_segment[26], shm_info[29];
|
||||
HANDLE shm_handle, info_handle;
|
||||
BOOL created = FALSE;
|
||||
|
||||
if (size < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(shm_segment, "TSRM_SHM_SEGMENT:%d", key);
|
||||
sprintf(shm_info, "TSRM_SHM_DESCRIPTOR:%d", key);
|
||||
|
||||
shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
|
||||
info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
|
||||
|
||||
if ((!shm_handle && !info_handle)) {
|
||||
if (flags & IPC_CREAT) {
|
||||
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shm_segment);
|
||||
info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info);
|
||||
created = TRUE;
|
||||
}
|
||||
if ((!shm_handle || !info_handle)) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (flags & IPC_EXCL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
shm = shm_get(key, NULL);
|
||||
shm->segment = shm_handle;
|
||||
shm->info = info_handle;
|
||||
shm->descriptor = MapViewOfFileEx(shm->info, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
|
||||
|
||||
if (created) {
|
||||
shm->descriptor->shm_perm.key = key;
|
||||
shm->descriptor->shm_segsz = size;
|
||||
shm->descriptor->shm_ctime = time(NULL);
|
||||
shm->descriptor->shm_cpid = getpid();
|
||||
shm->descriptor->shm_perm.mode = flags;
|
||||
|
||||
shm->descriptor->shm_perm.cuid = shm->descriptor->shm_perm.cgid= 0;
|
||||
shm->descriptor->shm_perm.gid = shm->descriptor->shm_perm.uid = 0;
|
||||
shm->descriptor->shm_atime = shm->descriptor->shm_dtime = 0;
|
||||
shm->descriptor->shm_lpid = shm->descriptor->shm_nattch = 0;
|
||||
shm->descriptor->shm_perm.mode = shm->descriptor->shm_perm.seq = 0;
|
||||
}
|
||||
|
||||
if (shm->descriptor->shm_perm.key != key || size > shm->descriptor->shm_segsz ) {
|
||||
CloseHandle(shm->segment);
|
||||
UnmapViewOfFile(shm->descriptor);
|
||||
CloseHandle(shm->info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
TSRM_API void *shmat(int key, const void *shmaddr, int flags)
|
||||
{
|
||||
shm_pair *shm = shm_get(key, NULL);
|
||||
|
||||
if (!shm->segment) {
|
||||
return (void*)-1;
|
||||
}
|
||||
|
||||
shm->descriptor->shm_atime = time(NULL);
|
||||
shm->descriptor->shm_lpid = getpid();
|
||||
shm->descriptor->shm_nattch++;
|
||||
|
||||
shm->addr = MapViewOfFileEx(shm->segment, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
|
||||
|
||||
return shm->addr;
|
||||
}
|
||||
|
||||
TSRM_API int shmdt(const void *shmaddr)
|
||||
{
|
||||
shm_pair *shm = shm_get(0, (void*)shmaddr);
|
||||
|
||||
if (!shm->segment) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
shm->descriptor->shm_dtime = time(NULL);
|
||||
shm->descriptor->shm_lpid = getpid();
|
||||
shm->descriptor->shm_nattch--;
|
||||
|
||||
return UnmapViewOfFile(shm->addr) ? 0 : -1;
|
||||
}
|
||||
|
||||
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf) {
|
||||
shm_pair *shm = shm_get(key, NULL);
|
||||
|
||||
if (!shm->segment) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case IPC_STAT:
|
||||
memcpy(buf, shm->descriptor, sizeof(struct shmid_ds));
|
||||
return 0;
|
||||
|
||||
case IPC_SET:
|
||||
shm->descriptor->shm_ctime = time(NULL);
|
||||
shm->descriptor->shm_perm.uid = buf->shm_perm.uid;
|
||||
shm->descriptor->shm_perm.gid = buf->shm_perm.gid;
|
||||
shm->descriptor->shm_perm.mode = buf->shm_perm.mode;
|
||||
return 0;
|
||||
|
||||
case IPC_RMID:
|
||||
if (shm->descriptor->shm_nattch < 1) {
|
||||
shm->descriptor->shm_perm.key = -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
TSRM_API char *realpath(char *orig_path, char *buffer)
|
||||
{
|
||||
int ret = GetFullPathName(orig_path, _MAX_PATH, buffer, NULL);
|
||||
if(!ret || ret > _MAX_PATH) {
|
||||
return NULL;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2013 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Daniel Beulshausen <daniel@php4win.de> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef TSRM_WIN32_H
|
||||
#define TSRM_WIN32_H
|
||||
|
||||
#include "TSRM.h"
|
||||
#include <windows.h>
|
||||
|
||||
struct ipc_perm {
|
||||
int key;
|
||||
unsigned short uid;
|
||||
unsigned short gid;
|
||||
unsigned short cuid;
|
||||
unsigned short cgid;
|
||||
unsigned short mode;
|
||||
unsigned short seq;
|
||||
};
|
||||
|
||||
struct shmid_ds {
|
||||
struct ipc_perm shm_perm;
|
||||
int shm_segsz;
|
||||
time_t shm_atime;
|
||||
time_t shm_dtime;
|
||||
time_t shm_ctime;
|
||||
unsigned short shm_cpid;
|
||||
unsigned short shm_lpid;
|
||||
short shm_nattch;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
FILE *stream;
|
||||
HANDLE prochnd;
|
||||
} process_pair;
|
||||
|
||||
typedef struct {
|
||||
void *addr;
|
||||
HANDLE info;
|
||||
HANDLE segment;
|
||||
struct shmid_ds *descriptor;
|
||||
} shm_pair;
|
||||
|
||||
typedef struct {
|
||||
process_pair *process;
|
||||
shm_pair *shm;
|
||||
int process_size;
|
||||
int shm_size;
|
||||
char *comspec;
|
||||
HANDLE impersonation_token;
|
||||
PSID impersonation_token_sid;
|
||||
} tsrm_win32_globals;
|
||||
|
||||
#ifdef ZTS
|
||||
# define TWG(v) TSRMG(win32_globals_id, tsrm_win32_globals *, v)
|
||||
#else
|
||||
# define TWG(v) (win32_globals.v)
|
||||
#endif
|
||||
|
||||
#define IPC_PRIVATE 0
|
||||
#define IPC_CREAT 00001000
|
||||
#define IPC_EXCL 00002000
|
||||
#define IPC_NOWAIT 00004000
|
||||
|
||||
#define IPC_RMID 0
|
||||
#define IPC_SET 1
|
||||
#define IPC_STAT 2
|
||||
#define IPC_INFO 3
|
||||
|
||||
#define SHM_R PAGE_READONLY
|
||||
#define SHM_W PAGE_READWRITE
|
||||
|
||||
#define SHM_RDONLY FILE_MAP_READ
|
||||
#define SHM_RND FILE_MAP_WRITE
|
||||
#define SHM_REMAP FILE_MAP_COPY
|
||||
|
||||
char * tsrm_win32_get_path_sid_key(const char *pathname TSRMLS_DC);
|
||||
|
||||
TSRM_API void tsrm_win32_startup(void);
|
||||
TSRM_API void tsrm_win32_shutdown(void);
|
||||
|
||||
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env TSRMLS_DC);
|
||||
TSRM_API FILE *popen(const char *command, const char *type);
|
||||
TSRM_API int pclose(FILE *stream);
|
||||
TSRM_API int tsrm_win32_access(const char *pathname, int mode TSRMLS_DC);
|
||||
TSRM_API int win32_utime(const char *filename, struct utimbuf *buf);
|
||||
|
||||
TSRM_API int shmget(int key, int size, int flags);
|
||||
TSRM_API void *shmat(int key, const void *shmaddr, int flags);
|
||||
TSRM_API int shmdt(const void *shmaddr);
|
||||
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf);
|
||||
|
||||
TSRM_API char *realpath(char *orig_path, char *buffer);
|
||||
#endif
|
||||
@@ -1,817 +0,0 @@
|
||||
$Id$
|
||||
|
||||
PHP 5.4 UPGRADE NOTES
|
||||
|
||||
===========
|
||||
0. Contents
|
||||
===========
|
||||
|
||||
1. Changes to INI directives
|
||||
2. Changes to reserved words and classes
|
||||
3. Changes to engine behavior
|
||||
4. Changes to existing functions
|
||||
5. Changes to existing classes
|
||||
6. Changes to existing methods
|
||||
7. Deprecated Functionality
|
||||
8. Removed Functionality
|
||||
a. Removed features
|
||||
b. Removed functions
|
||||
c. Removed syntax
|
||||
d. Removed hash algorithms
|
||||
9. Extension Changes:
|
||||
a. Extensions no longer maintained
|
||||
b. Extensions with changed behavior
|
||||
10. Changes in SAPI support
|
||||
11. Windows support
|
||||
12. New in PHP 5.4:
|
||||
a. New features
|
||||
b. Syntax additions
|
||||
c. New functions
|
||||
d. New global constants
|
||||
e. New classes
|
||||
f. New methods
|
||||
g. New hash algorithms
|
||||
|
||||
=============================
|
||||
1. Changes to INI directives
|
||||
=============================
|
||||
|
||||
- PHP 5.4 now checks at compile time if /dev/urandom or /dev/arandom
|
||||
are present. If either is available, session.entropy_file now
|
||||
defaults to that file and session.entropy_length defaults to 32.
|
||||
This provides non-blocking entropy to session id generation. If you
|
||||
do not want extra entropy for your session ids, add:
|
||||
|
||||
session.entropy_file=
|
||||
session.entropy_length=0
|
||||
|
||||
to your php.ini to preserve pre-PHP 5.4 behavior.
|
||||
|
||||
- Deprecated php.ini directives will now throw an E_CORE_WARNING's
|
||||
instead of the previous E_WARNING's.
|
||||
|
||||
- The following php.ini directives are no longer available in PHP 5.4
|
||||
and will now throw an E_CORE_ERROR upon startup:
|
||||
- allow_call_time_pass_reference
|
||||
- define_syslog_variables
|
||||
- highlight.bg
|
||||
- magic_quotes_gpc
|
||||
- magic_quotes_runtime
|
||||
- magic_quotes_sybase
|
||||
- register_globals
|
||||
- register_long_arrays
|
||||
- safe_mode
|
||||
- safe_mode_gid
|
||||
- safe_mode_include_dir
|
||||
- safe_mode_exec_dir
|
||||
- safe_mode_allowed_env_vars
|
||||
- safe_mode_protected_env_vars
|
||||
- session.bug_compat_42
|
||||
- session.bug_compat_warn
|
||||
- y2k_compliance
|
||||
- zend.ze1_compatibility_mode
|
||||
|
||||
- the following new php.ini directives were added:
|
||||
- max_input_vars - specifies how many GET/POST/COOKIE input
|
||||
variables may be accepted. The default value is 1000.
|
||||
|
||||
- E_ALL now includes E_STRICT.
|
||||
|
||||
- The recommended production value for error_reporting changed to E_ALL &
|
||||
~E_DEPRECATED & ~E_STRICT.
|
||||
|
||||
- Added new session support directives:
|
||||
session.upload_progress.enabled
|
||||
session.upload_progress.cleanup
|
||||
session.upload_progress.prefix
|
||||
session.upload_progress.name
|
||||
session.upload_progress.freq
|
||||
session.upload_progress.min_freq
|
||||
|
||||
- Added a zend.multibyte directive as a replacement of the PHP compile time
|
||||
configuration option --enable-zend-multibyte. Now the Zend Engine always
|
||||
contains code for multibyte support, which can be enabled or disabled at
|
||||
runtime. Note: It doesn't make a lot of sense to enable this option if
|
||||
ext/mbstring is not enabled, because most functionality is implemented by
|
||||
mbstrings callbacks.
|
||||
|
||||
- Added zend.script_encoding. This value will be used unless a
|
||||
"declare(encoding=...)" directive appears at the top of the script.
|
||||
|
||||
- Added zend.signal_check to check for replaced signal handlers on shutdown
|
||||
|
||||
- Added enable_post_data_reading, which is enabled by default. When it's
|
||||
disabled, the POST data is not read (or processed); the behavior is similar
|
||||
to that of other request methods with body, like PUT. This allows reading
|
||||
the raw POST data in multipart requests and reading/processing the POST data
|
||||
in a stream fashion (through php://input) without having it copied in memory
|
||||
multiple times.
|
||||
|
||||
- Added windows_show_crt_warning. This directive shows the CRT warnings when
|
||||
enabled. These warnings were displayed by default until now. It is disabled
|
||||
by default.
|
||||
|
||||
- Added cli.pager to set a pager for CLI interactive shell output.
|
||||
|
||||
- Added cli.prompt to configure the CLI interactive shell prompt.
|
||||
|
||||
- Added cli_server.color to enable the CLI web server to use ANSI color coding
|
||||
in terminal output.
|
||||
|
||||
========================================
|
||||
2. Changes to reserved words and classes
|
||||
========================================
|
||||
|
||||
- "callable", "insteadof" and "trait" are now reserved words.
|
||||
|
||||
=============================
|
||||
3. Changes to engine behavior
|
||||
=============================
|
||||
|
||||
- The __construct arguments of an extended abstract constructor must
|
||||
now match:
|
||||
|
||||
abstract class Base
|
||||
{
|
||||
abstract public function __construct();
|
||||
}
|
||||
class Foo extends Base
|
||||
{
|
||||
public function __construct($bar) {}
|
||||
}
|
||||
|
||||
This now emits a Fatal error due the incompatible declaration.
|
||||
|
||||
- In previous versions, superglobal names could be used for parameter
|
||||
names, thereby shadowing the corresponding superglobal. In PHP 5.4
|
||||
this now causes a fatal error such as "Cannot re-assign auto-global
|
||||
variable GLOBALS".
|
||||
|
||||
- Turning null, false or an empty string into an object by adding a
|
||||
property will now emit a warning instead of an E_STRICT error.
|
||||
|
||||
$test = null;
|
||||
$test->baz = 1;
|
||||
|
||||
To create a generic object you can use StdClass:
|
||||
|
||||
$test = new StdClass;
|
||||
$test->baz = 1;
|
||||
|
||||
- Converting an array to a string now will cause an E_NOTICE warning.
|
||||
|
||||
- Non-numeric string offsets, e.g. $a['foo'] where $a is a string, now
|
||||
return false on isset() and true on empty(), and produce warning if
|
||||
trying to use them. Offsets of types double, bool and null produce
|
||||
notice. Numeric strings ($a['2']) still work as before.
|
||||
|
||||
Note that offsets like '12.3' and '5 and a half' are considered
|
||||
non-numeric and produce warning, but are converted to 12 and 5
|
||||
respectively for backwards compatibility reasons.
|
||||
|
||||
- Long numeric strings that do not fit in integer or double (such as
|
||||
"92233720368547758070") are compared using string comparison if
|
||||
they could otherwise result in precision loss - since 5.4.4.
|
||||
|
||||
- Closures now support scopes and $this and can be rebound to
|
||||
objects using Closure::bind() and Closure::bindTo().
|
||||
|
||||
- <?= is now always available regardless of the short_open_tag
|
||||
setting.
|
||||
|
||||
- Parse error messages are changed to contain more information about
|
||||
the error.
|
||||
|
||||
- __clone and __destruct since 5.4.4 follow the same scoping rules as
|
||||
the rest of the methods (see bug #61782 for details).
|
||||
|
||||
================================
|
||||
4. Changes to existing functions
|
||||
================================
|
||||
|
||||
- array_combine now returns array() instead of FALSE when two empty arrays are
|
||||
provided as parameters.
|
||||
|
||||
- dns_get_record() has an extra parameter which allows requesting DNS records
|
||||
by numeric type and makes the result include only the raw data of the
|
||||
response.
|
||||
|
||||
- call_user_func_array() no longer allows call-time pass by reference.
|
||||
|
||||
- the default character set for htmlspecialchars() and htmlentities() is
|
||||
now UTF-8. In previous versions it was ISO-8859-1. Note that changing
|
||||
your output charset via the php.ini default_charset directive does not
|
||||
affect htmlspecialchars/htmlentities unless you are passing "" (an
|
||||
empty string) as the encoding parameter to your htmlspecialchars/htmlentities
|
||||
calls.
|
||||
|
||||
- htmlentities() and htmlspecialchars() are stricter in the code units they
|
||||
accept for the asian encodings. For Big5-HKSCS, the octets 0x80 and 0xFF are
|
||||
rejected. For GB2312/EUC-CN, the octets 0x8E, 0x8F, 0xA0 and 0xFF are
|
||||
rejected. For SJIS, the octets 0x80, 0xA0, 0xFD, 0xFE and 0xFF are rejected,
|
||||
except maybe after a valid starting byte. For EUC-JP, the octets 0xA0 and
|
||||
0xFF are rejected.
|
||||
|
||||
- htmlentities() now emits an E_STRICT warning when used with asian characters,
|
||||
as in that case htmlentities has (and already had before this version) the
|
||||
same functionality as htmlspecialchars.
|
||||
|
||||
- htmlentities() no longer numerically encodes high characters for single-byte
|
||||
encodings (except when there's actually a corresponding named entity). This
|
||||
behavior was not documented and was inconsistent with that for "UTF-8".
|
||||
|
||||
- html_entity_decode() and htmlspecialchars_decode() behave more consistently,
|
||||
now decoding entities in malformed strings such as "&&" or "&#&".
|
||||
|
||||
- htmlentities(), htmlspecialchars(), html_entity_decode(), and
|
||||
htmlspecialchars_decode: Added the flags ENT_HTML401, ENT_XML1, ENT_XHTML,
|
||||
and ENT_HTML5. The behavior of these functions including, but not limited to,
|
||||
the characters that are encoded and the entities that are decoded depend on
|
||||
the document type that is specified by those flags.
|
||||
|
||||
- htmlentities() and htmlspecialchars() with !$double_encode do more strict
|
||||
checks on the validity of the entities. Numerical entities are checked for a
|
||||
valid range (0 to 0x10FFFF); if the flag ENT_DISALLOWED is given, the
|
||||
validity of such numerical entity in the target document type is also
|
||||
checked. Named entities are checked for necessary existence in the target
|
||||
document type instead of only checking whether they were constituted by
|
||||
alphanumeric characters.
|
||||
|
||||
- The flag ENT_DISALLOWED was added. In addition to the behavior described in
|
||||
the item before, it also makes htmlentities() and htmlspecialchars()
|
||||
substitute characters that appear literally in the argument string and which
|
||||
are not allowed in the target document type with U+FFFD (UTF-8) or �.
|
||||
|
||||
- The flag ENT_SUBSTITUTE was added. This flag makes invalid multibyte
|
||||
sequences be replaced by U+FFFD (UTF-8) or &#FFFD; by htmlspecialchars() and
|
||||
htmlentities(). It is an alternative to the default behavior, which just
|
||||
returns an empty string and to ENT_IGNORE, which is a security risk. The
|
||||
behavior follows the recommendations of Unicode Technical Report #36.
|
||||
|
||||
- htmlspecialchars_decode() and html_entity_decode() now decode ' if the
|
||||
document type is ENT_XML1, ENT_XHTML, or ENT_HTML5.
|
||||
|
||||
- Charset detection with $charset == '' no longer turns to mbstring's
|
||||
internal encoding defined through mb_internal_encoding(). Only the encoding
|
||||
defined through the php.ini setting mbstring.internal_encoding is considered.
|
||||
|
||||
- number_format() no longer truncates multibyte decimal points and thousand
|
||||
separators to the first byte.
|
||||
|
||||
- The third parameter ($matches) to preg_match_all() is now optional. If
|
||||
omitted, the function will simply return the number of times the pattern was
|
||||
matched in the subject and will have no other side effects.
|
||||
|
||||
- The second argument of scandir() now accepts SCANDIR_SORT_NONE (2) as a
|
||||
possible value. This value results in scandir() performing no sorting: on
|
||||
local filesystems, this allows files to be returned in native filesystem
|
||||
order.
|
||||
|
||||
- stream_select() now preserves the keys of the passed array, be they numeric or
|
||||
strings. This breaks code that iterated the resulting stream array using a
|
||||
numeric index, but makes easier to identify which of the passed streams are
|
||||
present in the result.
|
||||
|
||||
- stream_set_write_buffer() no longer disables the read buffer of a plain
|
||||
stream when 0 is given as the second argument.
|
||||
|
||||
- stream_set_write_buffer() no longer changes the chunk size in socket streams.
|
||||
|
||||
- fclose() closes streams with resource refcount > 1; it doesn't merely
|
||||
decrement the resource refcount.
|
||||
|
||||
- socket_set_options() and socket_get_options() now support multicast options.
|
||||
|
||||
- The raw data parameter in openssl_encrypt() and openssl_decrypt() is now an
|
||||
options integer rather than a boolean. A value of true produces the same
|
||||
behavior.
|
||||
|
||||
- Write operations within XSLT (for example with the extension sax:output) are
|
||||
disabled by default. You can define what is forbidden with the method
|
||||
XsltProcess::setSecurityPrefs($options).
|
||||
|
||||
- Added AES support to OpenSSL.
|
||||
|
||||
- openssl_csr_new() expects the textual data to be in UTF-8.
|
||||
|
||||
- Added no-padding option to openssl_encrypt() and openssl_decrypt().
|
||||
|
||||
- Added a "no_ticket" SSL context option to disable the SessionTicket TLS
|
||||
extension.
|
||||
|
||||
- Added new json_encode() options: JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES,
|
||||
JSON_NUMERIC_CHECK, JSON_BIGINT_AS_STRING, JSON_UNESCAPED_UNICODE.
|
||||
|
||||
- Added Tokyo Cabinet and Berkley DB 5 support to DBA extension.
|
||||
|
||||
- Added support for CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE
|
||||
to cURL.
|
||||
|
||||
- Added optional argument to debug_backtrace() and debug_print_backtrace()
|
||||
to limit the amount of stack frames returned.
|
||||
|
||||
- Fixed crypt_blowfish handling of 8-bit characters. crypt() in Blowfish mode
|
||||
now supports hashes marked $2a$, $2x$, $2y$ and $2z$.
|
||||
|
||||
- mbstring now supports following encodings: Shift_JIS/UTF-8 Emoji,
|
||||
JIS X0213:2004 (Shift_JIS-2004, EUC-JP-2004, ISO-2022-JP-2004),
|
||||
MacJapanese (Shift_JIS), gb18030.
|
||||
|
||||
- Added encode and decode in hex format to mb_encode_numericentity() and
|
||||
mb_decode_numericentity().
|
||||
|
||||
- Added support for SORT_NATURAL and SORT_FLAG_CASE in array sort functions:
|
||||
sort(), rsort(), ksort(), krsort(), asort(), arsort() and array_multisort().
|
||||
|
||||
- is_a() and is_subclass_of() now have third boolean parameter, which specifies
|
||||
if the first argument can be a string class name. Default if false for is_a
|
||||
and true for is_subclass_of() for BC reasons.
|
||||
|
||||
- ob_start() will now treat a chunk size of 1 as meaning 1 byte, rather than
|
||||
the previous special case behavior of treating it as 4096 bytes.
|
||||
|
||||
- idn_to_ascii() and idn_to_utf8() now take two extra parameters, one indicating
|
||||
the variant (IDNA 2003 or UTS #46) and another, passed by reference, to return
|
||||
details about the operation in case UTS #46 is chosen.
|
||||
|
||||
- gzencode() used with FORCE_DEFLATE now generates RFC1950 compliant data.
|
||||
|
||||
- ob_start() no longer starts multiple output buffers when passed
|
||||
array("callback1", "callback2", "callback3", ...).
|
||||
|
||||
- Since 5.4.4, "php://fd" stream syntax is available only in CLI build.
|
||||
|
||||
- Since 5.4.5, resourcebundle_create() accepts null for the first two arguments.
|
||||
|
||||
- Since 5.4.6, SimpleXMLElement::getDocNamespaces() has and extra parameter which
|
||||
allows for toggling if the list of namespaces starts from the document root
|
||||
or from the node you call the method on
|
||||
|
||||
- Since 5.4.7, ctor is always called when new user stream wrapper object is created.
|
||||
Before, it was called only when stream_open was called.
|
||||
|
||||
==============================
|
||||
5. Changes to existing classes
|
||||
==============================
|
||||
|
||||
- Classes that implement stream wrappers can define a method called
|
||||
stream_truncate that will respond to truncation, e.g. through ftruncate.
|
||||
Strictly speaking, this is an addition to the user-space stream wrapper
|
||||
template, not a change to an actual class.
|
||||
|
||||
- Classes that implement stream wrappers can define a method called
|
||||
stream_metadata that will be called on touch(), chmod(), chgrp(), chown().
|
||||
|
||||
- Arrays cast from SimpleXMLElement now always contain all nodes instead of
|
||||
just the first matching node.
|
||||
|
||||
- All SimpleXMLElement children are now always printed when using var_dump(),
|
||||
var_export(), and print_r().
|
||||
|
||||
- Added iterator support in MySQLi. mysqli_result implements Traversable.
|
||||
|
||||
==============================
|
||||
6. Changes to existing methods
|
||||
==============================
|
||||
|
||||
- DateTime::parseFromFormat() now has a "+" modifier to allow trailing text in
|
||||
the string to parse without throwing an error.
|
||||
|
||||
- Added the ability to pass options to DOMDocument::loadHTML().
|
||||
|
||||
- FilesystemIterator, GlobIterator and (Recursive)DirectoryIterator now use
|
||||
the default stream context.
|
||||
|
||||
- Since 5.4.5, the constructor of ResourceBundle accepts NULL for the first two
|
||||
arguments.
|
||||
|
||||
===========================
|
||||
7. Deprecated Functionality
|
||||
===========================
|
||||
|
||||
- The following functions are deprecated in PHP 5.4:
|
||||
- mcrypt_generic_end(): use mcrypt_generic_deinit() instead
|
||||
- mysql_list_dbs()
|
||||
|
||||
========================
|
||||
8. Removed Functionality
|
||||
========================
|
||||
|
||||
a. Removed features
|
||||
|
||||
The following features have been removed from PHP 5.4:
|
||||
|
||||
- Magic quotes
|
||||
- Register globals
|
||||
- Safe mode
|
||||
- Session extension bug compatibility mode
|
||||
- Y2K compliance mode
|
||||
|
||||
b. Removed functions
|
||||
|
||||
The following functions are no longer available in PHP 5.4:
|
||||
|
||||
- define_syslog_variables()
|
||||
- import_request_variables()
|
||||
- session_is_registered()
|
||||
- session_register()
|
||||
- session_unregister()
|
||||
- set_magic_quotes_runtime()
|
||||
- mysqli_bind_param() (alias of mysqli_stmt_bind_param())
|
||||
- mysqli_bind_result() (alias of mysqli_stmt_bind_result())
|
||||
- mysqli_client_encoding() (alias of mysqli_character_set_name())
|
||||
- mysqli_fetch() (alias of mysqli_stmt_fetch())
|
||||
- mysqli_param_count() (alias of mysqli_stmt_param_count())
|
||||
- mysqli_get_metadata() (alias of mysqli_stmt_result_metadata())
|
||||
- mysqli_send_long_data() (alias of mysqli_stmt_send_long_data())
|
||||
- mysqli::client_encoding() (alias of mysqli::character_set_name)
|
||||
- mysqli_stmt::stmt() (never worked/always throws, undocumented)
|
||||
|
||||
c. Removed syntax
|
||||
|
||||
- break $var;
|
||||
- continue $var;
|
||||
|
||||
d. Removed hash algorithms
|
||||
|
||||
- Salsa10 and Salsa20, which are actually stream ciphers
|
||||
|
||||
====================
|
||||
9. Extension Changes
|
||||
====================
|
||||
|
||||
a. Extensions no longer maintained
|
||||
|
||||
- ext/sqlite is no longer part of the base distribution and has been moved
|
||||
to PECL. Use sqlite3 or PDO_SQLITE instead.
|
||||
|
||||
b. Extensions with changed behavior
|
||||
|
||||
- The MySQL extensions (ext/mysql, mysqli and PDO_MYSQL) use mysqlnd
|
||||
as the default library now. It is still possible to use libmysql by
|
||||
specifying a path to the configure options.
|
||||
|
||||
- PDO_MYSQL: Support for linking with MySQL client libraries older
|
||||
than 4.1 is removed.
|
||||
|
||||
- The session extension now can hook into the file upload feature
|
||||
in order to provide upload progress information through session
|
||||
variables.
|
||||
|
||||
- SNMP extension
|
||||
- Functions in SNMP extension now returns FALSE on every error
|
||||
condition including SNMP-related (no such instance, end of MIB,
|
||||
etc). Thus, in patricular, breaks previous behavior of get/walk
|
||||
functions returning an empty string on SNMP-related errors.
|
||||
- Multi OID get/getnext/set queries are now supported.
|
||||
- New constants added for use in snmp_set_oid_output_format()
|
||||
function.
|
||||
- Function snmp_set_valueretrieval() changed it's behavior:
|
||||
SNMP_VALUE_OBJECT can be combined with one of
|
||||
SNMP_VALUE_PLAIN or SNMP_VALUE_LIBRARY resulting OID value
|
||||
changes. When no SNMP_VALUE_PLAIN or SNMP_VALUE_LIBRARY
|
||||
is supplied with SNMP_VALUE_OBJECT, SNMP_VALUE_LIBRARY is used.
|
||||
Prior to 5.4.0 when no SNMP_VALUE_PLAIN or SNMP_VALUE_LIBRARY
|
||||
was supplied with SNMP_VALUE_OBJECT, SNMP_VALUE_PLAIN was used.
|
||||
- Added feature-rich OO API (SNMP class)
|
||||
- Dropped UCD-SNMP compatibility code. Consider upgrading to
|
||||
net-snmp v5.3+. Net-SNMP v5.4+ is required for Windows version.
|
||||
- In sake of adding support for IPv6 DNS name resolution of
|
||||
remote SNMP agent (peer) is done by extension now, not by Net-SNMP
|
||||
library anymore.
|
||||
|
||||
- Date extension
|
||||
- Setting the timezone with the TZ environment variable is no longer
|
||||
supported, instead date.timezone and/or date_default_timezone_set()
|
||||
have to be used.
|
||||
- The extension will no longer guess the default timezone if none
|
||||
is set with date.timezone and/or date_default_timezone_set().
|
||||
Instead it will always fall back to "UTC".
|
||||
|
||||
- Hash extension
|
||||
- the output of the tiger hash family has been corrected, see
|
||||
https://bugs.php.net/61307
|
||||
|
||||
===========================
|
||||
10. Changes in SAPI support
|
||||
===========================
|
||||
|
||||
- A REQUEST_TIME_FLOAT value returns a floating point number indicating the
|
||||
time with microsecond precision. All SAPIs providing this value should be
|
||||
returning float and not time_t.
|
||||
|
||||
- apache_child_terminate(), getallheaders(), apache_request_headers()
|
||||
and apache_response_headers() are now supported on FastCGI.
|
||||
|
||||
- The interactive shell allows a shortcut #inisetting=value to change php.ini
|
||||
settings at run-time.
|
||||
|
||||
- The interactive shell now works with the shared readline extension.
|
||||
|
||||
- The interactive shell no longer terminates on fatal errors.
|
||||
|
||||
- A new PHP CLI command line option --rz <name> shows information about the
|
||||
named Zend extension.
|
||||
|
||||
===================
|
||||
11. Windows support
|
||||
===================
|
||||
|
||||
- is_link now works properly for symbolic links on Windows Vista
|
||||
or later. Earlier systems do not support symbolic links.
|
||||
|
||||
- As of PHP 5.4.5 and above the COM extension isn't compiled statically in PHP
|
||||
anymore but shared. It'll still be delivered with the standard PHP release but
|
||||
must be activated manually with the "extension = php_com_dotnet.dll" directive
|
||||
in php.ini.
|
||||
|
||||
- Apache 2.4 handler is supported as of PHP 5.4.9
|
||||
|
||||
==================
|
||||
12. New in PHP 5.4
|
||||
==================
|
||||
|
||||
a. New Features
|
||||
|
||||
- A built-in CLI web server for testing purposes is now available:
|
||||
$ php -S 127.0.0.1:8888
|
||||
|
||||
- File Upload Progress support is implemented in the Session extension.
|
||||
|
||||
b. Syntax additions
|
||||
|
||||
- Traits:
|
||||
trait HelloWorld {
|
||||
public function sayHello() {
|
||||
echo 'Hello World!';
|
||||
}
|
||||
}
|
||||
|
||||
class CanIGetHello {
|
||||
use HelloWorld;
|
||||
}
|
||||
|
||||
$hello = new CanIGetHello();
|
||||
$hello->sayHello();
|
||||
|
||||
- Function call result array access, e.g.:
|
||||
foo()[0]
|
||||
$foo->bar()[0]
|
||||
|
||||
- Callable typehint indicating argument must be callable:
|
||||
function foo(callable $do) {
|
||||
}
|
||||
foo("strcmp");
|
||||
foo(function() {});
|
||||
$o = new ArrayObject();
|
||||
foo(array($o, "count"));
|
||||
|
||||
- Short array syntax:
|
||||
$a = [1, 2, 3, 4];
|
||||
$a = ['one' => 1, 'two' => 2, 'three' => 3, 'four' => 4];
|
||||
$a = ['one' => 1, 2, 'three' => 3, 4];
|
||||
|
||||
- Binary number format:
|
||||
0b00100 0b010101
|
||||
|
||||
- Chained string array offsets now work.
|
||||
$a = "abc";
|
||||
echo $a[0][0];
|
||||
|
||||
- Anonymous functions now support using $this and class scope.
|
||||
Anonymous function can be declared as "static" to ignore the scope.
|
||||
|
||||
- Class::{expr}() syntax is now supported:
|
||||
class A {
|
||||
static function foo() {
|
||||
echo "Hello world!\n";
|
||||
}
|
||||
}
|
||||
$x = "f";
|
||||
$y = "o";
|
||||
A::{$x.$y.$y}();
|
||||
|
||||
- Class member access on instantiation:
|
||||
(new foo)->method()
|
||||
(new foo)->property
|
||||
(new foo)[0]
|
||||
|
||||
|
||||
c. New functions
|
||||
|
||||
- Core:
|
||||
- get_declared_traits()
|
||||
- getimagesizefromstring()
|
||||
- hex2bin()
|
||||
- header_register_callback()
|
||||
- http_response_code()
|
||||
- stream_set_chunk_size()
|
||||
- socket_import_stream()
|
||||
- trait_exists()
|
||||
|
||||
- Intl:
|
||||
- transliterator_create()
|
||||
- transliterator_create_from_rules()
|
||||
- transliterator_create_inverse()
|
||||
- transliterator_get_error_code()
|
||||
- transliterator_get_error_message()
|
||||
- transliterator_list_ids()
|
||||
- transliterator_transliterate()
|
||||
|
||||
- LDAP:
|
||||
- ldap_control_paged_result()
|
||||
- ldap_control_paged_result_response()
|
||||
|
||||
- libxml:
|
||||
- libxml_set_external_entity_loader()
|
||||
|
||||
- mysqli:
|
||||
- mysqli_error_list()
|
||||
- mysqli_stmt_error_list()
|
||||
|
||||
- pgsql
|
||||
- pg_escape_identifier() (5.4.4)
|
||||
- pg_escape_literal() (5.4.4)
|
||||
|
||||
- Session:
|
||||
- session_register_shutdown()
|
||||
- session_status()
|
||||
|
||||
- SPL
|
||||
- class_uses()
|
||||
|
||||
d. New global constants
|
||||
|
||||
- CURLOPT_MAX_RECV_SPEED_LARGE
|
||||
- CURLOPT_MAX_SEND_SPEED_LARGE
|
||||
- ENT_DISALLOWED
|
||||
- ENT_HTML401
|
||||
- ENT_HTML5
|
||||
- ENT_SUBSTITUTE
|
||||
- ENT_XHTML
|
||||
- ENT_XML1
|
||||
- IPPROTO_IP
|
||||
- IPPROTO_IPV6
|
||||
- IPV6_MULTICAST_HOPS
|
||||
- IPV6_MULTICAST_IF
|
||||
- IPV6_MULTICAST_LOOP
|
||||
- IP_MULTICAST_IF
|
||||
- IP_MULTICAST_LOOP
|
||||
- IP_MULTICAST_TTL
|
||||
- JSON_BIGINT_AS_STRING
|
||||
- JSON_OBJECT_AS_ARRAY
|
||||
- JSON_PRETTY_PRINT
|
||||
- JSON_UNESCAPED_SLASHES
|
||||
- JSON_UNESCAPED_UNICODE
|
||||
- LIBXML_HTML_NODEFDTD
|
||||
- LIBXML_HTML_NOIMPLIED
|
||||
- LIBXML_PEDANTIC
|
||||
- MCAST_JOIN_GROUP
|
||||
- MCAST_LEAVE_GROUP
|
||||
- MCAST_BLOCK_SOURCE
|
||||
- MCAST_UNBLOCK_SOURCE
|
||||
- MCAST_JOIN_SOURCE_GROUP
|
||||
- MCAST_LEAVE_SOURCE_GROUP
|
||||
- OPENSSL_CIPHER_AES_128_CBC
|
||||
- OPENSSL_CIPHER_AES_192_CBC
|
||||
- OPENSSL_CIPHER_AES_256_CBC
|
||||
- OPENSSL_RAW_DATA
|
||||
- OPENSSL_ZERO_PADDING
|
||||
- PHP_OUTPUT_HANDLER_CLEAN
|
||||
- PHP_OUTPUT_HANDLER_CLEANABLE
|
||||
- PHP_OUTPUT_HANDLER_DISABLED
|
||||
- PHP_OUTPUT_HANDLER_FINAL
|
||||
- PHP_OUTPUT_HANDLER_FLUSH
|
||||
- PHP_OUTPUT_HANDLER_FLUSHABLE
|
||||
- PHP_OUTPUT_HANDLER_REMOVABLE
|
||||
- PHP_OUTPUT_HANDLER_STARTED
|
||||
- PHP_OUTPUT_HANDLER_STDFLAGS
|
||||
- PHP_OUTPUT_HANDLER_WRITE
|
||||
- PHP_QUERY_RFC1738
|
||||
- PHP_QUERY_RFC3986
|
||||
- PHP_SESSION_ACTIVE
|
||||
- PHP_SESSION_DISABLED
|
||||
- PHP_SESSION_NONE
|
||||
- SCANDIR_SORT_ASCENDING
|
||||
- SCANDIR_SORT_DESCENDING
|
||||
- SCANDIR_SORT_NONE
|
||||
- SORT_FLAG_CASE
|
||||
- SORT_NATURAL
|
||||
- STREAM_META_ACCESS
|
||||
- STREAM_META_GROUP
|
||||
- STREAM_META_GROUP_NAME
|
||||
- STREAM_META_OWNER
|
||||
- STREAM_META_OWNER_NAME
|
||||
- STREAM_META_TOUCH
|
||||
- T_CALLABLE
|
||||
- T_INSTEADOF
|
||||
- T_TRAIT
|
||||
- T_TRAIT_C
|
||||
- ZLIB_ENCODING_DEFLATE
|
||||
- ZLIB_ENCODING_GZIP
|
||||
- ZLIB_ENCODING_RAW
|
||||
- U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR
|
||||
- IDNA_CHECK_BIDI
|
||||
- IDNA_CHECK_CONTEXTJ
|
||||
- IDNA_NONTRANSITIONAL_TO_ASCII
|
||||
- IDNA_NONTRANSITIONAL_TO_UNICODE
|
||||
- INTL_IDNA_VARIANT_2003
|
||||
- INTL_IDNA_VARIANT_UTS46
|
||||
- IDNA_ERROR_EMPTY_LABEL
|
||||
- IDNA_ERROR_LABEL_TOO_LONG
|
||||
- IDNA_ERROR_DOMAIN_NAME_TOO_LONG
|
||||
- IDNA_ERROR_LEADING_HYPHEN
|
||||
- IDNA_ERROR_TRAILING_HYPHEN
|
||||
- IDNA_ERROR_HYPHEN_3_4
|
||||
- IDNA_ERROR_LEADING_COMBINING_MARK
|
||||
- IDNA_ERROR_DISALLOWED
|
||||
- IDNA_ERROR_PUNYCODE
|
||||
- IDNA_ERROR_LABEL_HAS_DOT
|
||||
- IDNA_ERROR_INVALID_ACE_LABEL
|
||||
- IDNA_ERROR_BIDI
|
||||
- IDNA_ERROR_CONTEXTJ
|
||||
|
||||
e. New classes
|
||||
|
||||
- Reflection:
|
||||
- ReflectionZendExtension
|
||||
|
||||
- Intl:
|
||||
- Transliterator
|
||||
- Spoofchecker
|
||||
|
||||
- JSON:
|
||||
- JsonSerializable
|
||||
|
||||
- Session:
|
||||
- SessionHandler
|
||||
|
||||
- SNMP:
|
||||
- SNMP
|
||||
|
||||
- SPL:
|
||||
- CallbackFilterIterator
|
||||
- RecursiveCallbackFilterIterator
|
||||
|
||||
f. New methods
|
||||
|
||||
- Closure:
|
||||
- Closure::bind()
|
||||
- Closure::bindTo()
|
||||
|
||||
- Reflection:
|
||||
- ReflectionClass::getTraitAliases()
|
||||
- ReflectionClass::getTraitNames()
|
||||
- ReflectionClass::getTraits()
|
||||
- ReflectionClass::isCloneable()
|
||||
- ReflectionClass::isTrait()
|
||||
- ReflectionClass::newInstanceWithoutConstructor()
|
||||
- ReflectionExtension::isPersistent()
|
||||
- ReflectionExtension::isTemporary()
|
||||
- ReflectionFunction::getClosure()
|
||||
- ReflectionFunction::getClosureScopeClass()
|
||||
- ReflectionFunction::getClosureThis()
|
||||
- ReflectionFunctionAbstract::getClosureScopeClass()
|
||||
- ReflectionFunctionAbstract::getClosureThis()
|
||||
- ReflectionMethod::getClosure()
|
||||
- ReflectionMethod::getClosureScopeClass()
|
||||
- ReflectionMethod::getClosureThis()
|
||||
- ReflectionObject::getTraitAliases()
|
||||
- ReflectionObject::getTraitNames()
|
||||
- ReflectionObject::getTraits()
|
||||
- ReflectionObject::isCloneable()
|
||||
- ReflectionObject::isTrait()
|
||||
- ReflectionObject::newInstanceWithoutConstructor()
|
||||
- ReflectionParameter::canBePassedByValue()
|
||||
- ReflectionParameter::isCallable()
|
||||
|
||||
- PDO_DBLIB:
|
||||
- PDO::newRowset()
|
||||
|
||||
- SPL:
|
||||
- DirectoryIterator::getExtension()
|
||||
- RegexIterator::getRegex()
|
||||
- SplDoublyLinkedList::serialize()
|
||||
- SplDoublyLinkedList::unserialize()
|
||||
- SplFileInfo::getExtension()
|
||||
- SplFileObject::fputcsv()
|
||||
- SplObjectStorage::getHash()
|
||||
- SplQueue::serialize
|
||||
- SplQueue::unserialize
|
||||
- SplStack::serialize
|
||||
- SplStack::unserialize
|
||||
- SplTempFileObject::fputcsv
|
||||
|
||||
- XSLT:
|
||||
- XsltProcessor::setSecurityPrefs()
|
||||
- XsltProcessor::getSecurityPrefs()
|
||||
|
||||
- Zlib:
|
||||
- zlib_decode()
|
||||
- zlib_encode()
|
||||
|
||||
g. New Hash algorithms
|
||||
|
||||
- fnv132
|
||||
- fnv164
|
||||
- joaat
|
||||
@@ -1,207 +0,0 @@
|
||||
$Id$
|
||||
|
||||
UPGRADE NOTES - PHP X.Y
|
||||
|
||||
1. Internal API changes
|
||||
a. virtual_file_ex
|
||||
b. stat/lstat support
|
||||
c. readlink support
|
||||
d. layout of some core ZE structures (zend_op_array, zend_class_entry, ...)
|
||||
e. Zend\zend_fast_cache.h has been removed
|
||||
f. streams that enclose private streams
|
||||
g. leak_variable
|
||||
h. API Signature changes
|
||||
i. new TSRM function expand_filepath_with_mode
|
||||
|
||||
2. Build system changes
|
||||
a. Unix build system changes
|
||||
b. Windows build system changes
|
||||
|
||||
|
||||
========================
|
||||
1. Internal API changes
|
||||
========================
|
||||
|
||||
a. virtual_file_ex
|
||||
|
||||
virtual_file_ex takes now a TSRM context as last parameter:
|
||||
CWD_API int virtual_file_ex(cwd_state *state, const char *path,
|
||||
verify_path_func verify_path, int use_realpath TSRLS_DC);
|
||||
|
||||
|
||||
b. stat/lstat support
|
||||
|
||||
lstat is now available on all platforms. On unix-like platform
|
||||
php_sys_lstat is an alias to lstat (when avaible). On Windows it is now
|
||||
available using php_sys_lstat. php_sys_stat and php_sys_lstat usage is recommended
|
||||
instead of calling lstat directly, to ensure portability.
|
||||
|
||||
|
||||
c. readlink support
|
||||
|
||||
readlink is now available on all platforms. On unix-like platform
|
||||
php_sys_readlink is an alias to readlink (when avaible). On Windows it is now
|
||||
available using php_sys_readlink. php_sys_readlink usage is recommended
|
||||
instead of calling readlink directly, to ensure portability.
|
||||
|
||||
|
||||
d. layout of some core ZE structures (zend_op_array, zend_class_entry, ...)
|
||||
|
||||
. zend_function.pass_rest_by_reference is replaced by
|
||||
ZEND_ACC_PASS_REST_BY_REFERENCE in zend_function.fn_flags
|
||||
. zend_function.return_reference is replaced by ZEND_ACC_RETURN_REFERENCE
|
||||
in zend_function.fn_flags
|
||||
. zend_arg_info.required_num_args removed. it was needed only for internal
|
||||
functions. Now the first arg_info for internal function (which has special
|
||||
meaning) is represented by zend_internal_function_info structure.
|
||||
. zend_op_array.size, size_var, size_literal, current_brk_cont,
|
||||
backpatch_count moved into CG(context), because they are used only during
|
||||
compilation.
|
||||
. zend_op_array.start_op is moved into EG(start_op), because it's used
|
||||
only for 'interactive' execution of single top-level op-array.
|
||||
. zend_op_array.done_pass_two is replaced by ZEND_ACC_DONE_PASS_TWO in
|
||||
zend_op_array.fn_flags.
|
||||
. op_array.vars array is trimmed (reallocated) during pass_two.
|
||||
. zend_class_entry.constants_updated is replaced by
|
||||
ZEND_ACC_CONSTANTS_UPDATED in zend_class_entry.ce_flags
|
||||
. the size of zend_class_entry is reduced by sharing the same memory space
|
||||
by different information for internal and user classes.
|
||||
See zend_class_inttry.info union.
|
||||
|
||||
|
||||
e. Zend\zend_fast_cache.h
|
||||
|
||||
It should not have been used anymore since php5, but now this header has
|
||||
been removed. The following macros are not available anymore:
|
||||
|
||||
ZEND_FAST_ALLOC(p, type, fc_type)
|
||||
ZEND_FAST_FREE(p, fc_type)
|
||||
ZEND_FAST_ALLOC_REL(p, type, fc_type)
|
||||
ZEND_FAST_FREE_REL(p, fc_type)
|
||||
|
||||
Use emalloc, emalloc_rel, efree or efree_rel instead.
|
||||
|
||||
|
||||
f. Streams that enclose private streams
|
||||
|
||||
Some streams, like the temp:// stream, may enclose private streams. If the
|
||||
outer stream leaks due to a programming error or is not exposed through a
|
||||
zval (and therefore is not deleted when all the zvals are gone), it will
|
||||
be destroyed on shutdown.
|
||||
The problem is that the outer usually wants itself to close the inner stream,
|
||||
so that it may do any other shutdown action that requires the inner stream to
|
||||
be live (e.g. commit data to it). If the outer stream is exposed through a
|
||||
zval and the inner one isn't, this is not a problem because the outer stream
|
||||
will be freed when the zval is destroyed, which happens before the resources
|
||||
are destroyed on shutdown.
|
||||
On resource list shutdown, the cleanup happens in reverse order of resource
|
||||
creation, so if the inner stream was created in the opener of the outer stream,
|
||||
it will be destroyed first.
|
||||
The following functions were added to the streams API to force a predictable
|
||||
destruction order:
|
||||
|
||||
PHPAPI php_stream *php_stream_encloses(php_stream *enclosing, php_stream *enclosed);
|
||||
#define php_stream_free_enclosed(stream_enclosed, close_options)
|
||||
PHPAPI int _php_stream_free_enclosed(php_stream *stream_enclosed, int close_options TSRMLS_DC);
|
||||
|
||||
Additionally, the following member was added to php_stream:
|
||||
|
||||
struct _php_stream *enclosing_stream;
|
||||
|
||||
and the following macro was added:
|
||||
|
||||
#define PHP_STREAM_FREE_IGNORE_ENCLOSING 32
|
||||
|
||||
The function php_stream_encloses declares the first stream encloses the second.
|
||||
This has the effect that, when the inner stream is closed from a resource
|
||||
destructor it will abort and try to free its enclosing stream instead.
|
||||
To prevent this from happening when the inner stream is freed from the outer
|
||||
stream, the macro php_stream_free_enclosed should be used instead of
|
||||
php_stream_free/php_stream_close/php_stream_pclose, or the flag
|
||||
PHP_STREAM_FREE_IGNORE_ENCLOSING should be directly passed to php_stream_free.
|
||||
The outer stream cannot abstain, in its close callback, from closing the inner
|
||||
stream or clear the enclosing_stream pointer in its enclosed stream by calling
|
||||
php_stream_encloses with the 2nd argument NULL. If this is not done, there will
|
||||
be problems, so observe this requirement when using php_stream_encloses.
|
||||
|
||||
|
||||
g. leak_variable
|
||||
|
||||
The function leak_variable(variable [, leak_data]) was added. It is only
|
||||
available on debug builds. It increments the refcount of a zval or, if the
|
||||
second argument is true and the variable is either an object or a resource
|
||||
it increments the refcounts of those objects instead.
|
||||
|
||||
|
||||
h. API Signature changes
|
||||
|
||||
. zend_list_insert
|
||||
ZEND_API int zend_list_insert(void *ptr, int type TSRMLS_DC);
|
||||
call: zend_list_insert(a, SOMETYPE TSRMLS_CC);
|
||||
NB: If zend_list_insert is used to register a resource,
|
||||
ZEND_REGISTER_RESOURCE could be used instead.
|
||||
|
||||
. php_le_stream_context(TSRMLS_C)
|
||||
PHPAPI php_stream_context *php_stream_context_alloc(TSRMLS_D)
|
||||
call: context = php_stream_context_alloc(TSRMLS_C);
|
||||
|
||||
. php_stream_context_alloc
|
||||
PHPAPI php_stream_context *php_stream_context_alloc(TSRMLS_D);
|
||||
call: context = php_stream_context_alloc(TSRMLS_C);
|
||||
|
||||
. sapi_get_request_time(TSRMLS_D);
|
||||
SAPI_API double sapi_get_request_time(TSRMLS_D);
|
||||
|
||||
. sapi_register_default_post_reader
|
||||
SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D) TSRMLS_DC);
|
||||
|
||||
. sapi_register_treat_data
|
||||
SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC) TSRMLS_DC);
|
||||
|
||||
. sapi_register_input_filter
|
||||
SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC), unsigned int (*input_filter_init)(TSRMLS_D) TSRMLS_DC);
|
||||
|
||||
. tsrm_win32_access
|
||||
TSRM_API int tsrm_win32_access(const char *pathname, int mode TSRMLS_DC);
|
||||
|
||||
. popen_ex (win32)
|
||||
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env TSRMLS_DC);
|
||||
|
||||
. php_get_current_user
|
||||
PHPAPI php_get_current_user(TSRMLS_D)
|
||||
Call: char *user = php_get_current_user(TSRMLS_C);
|
||||
|
||||
. php_idate
|
||||
PHPAPI php_idate(char format, time_t ts, int localtime TSRMLS_DC)
|
||||
Call: int ret = php_idate(format, ts, localtime TSRMLS_CC)
|
||||
|
||||
. php_escape_html_entities
|
||||
(size_t parameters were ints, previous "quote_style" (now flags) has expanded meaning)
|
||||
PHPAPI char *php_escape_html_entities(unsigned char *old, size_t oldlen, size_t *newlen, int all, int flags, char *hint_charset TSRMLS_DC);
|
||||
|
||||
. php_escape_html_entities_ex
|
||||
PHPAPI char *php_escape_html_entities_ex(unsigned char *old, size_t oldlen, size_t *newlen, int all, int flags, char *hint_charset, zend_bool double_encode TSRMLS_DC);
|
||||
|
||||
. php_unescape_html_entities
|
||||
PHPAPI char *php_unescape_html_entities(unsigned char *old, size_t oldlen, size_t *newlen, int all, int flags, char *hint_charset TSRMLS_DC);
|
||||
|
||||
i.
|
||||
PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len, int realpath_mode TSRMLS_DC);
|
||||
expand_filepath_with_mode lets define how realpath will behave, using one of the existing mode: CWD_EXPAND , CWD_FILEPATH or CWD_REALPATH.
|
||||
|
||||
========================
|
||||
2. Build system changes
|
||||
========================
|
||||
|
||||
a. Unix build system changes
|
||||
|
||||
- Changes in SAPI module build:
|
||||
. When adding new binary SAPI (executable, like CLI/CGI/FPM) use CLI config.m4 and Makefile.frag files as templates and replace CLI/cli with your SAPI name.
|
||||
|
||||
- New macros:
|
||||
. PHP_INIT_DTRACE(providerdesc, header-file, sources [, module])
|
||||
|
||||
|
||||
b. Windows build system changes
|
||||
-
|
||||
|
||||
+14385
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,186 @@
|
||||
// $Header$
|
||||
|
||||
// FlexLexer.h -- define interfaces for lexical analyzer classes generated
|
||||
// by flex
|
||||
|
||||
// Copyright (c) 1993 The Regents of the University of California.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This code is derived from software contributed to Berkeley by
|
||||
// Kent Williams and Tom Epperly.
|
||||
//
|
||||
// Redistribution and use in source and binary forms with or without
|
||||
// modification are permitted provided that: (1) source distributions retain
|
||||
// this entire copyright notice and comment, and (2) distributions including
|
||||
// binaries display the following acknowledgement: ``This product includes
|
||||
// software developed by the University of California, Berkeley and its
|
||||
// contributors'' in the documentation or other materials provided with the
|
||||
// distribution and in all advertising materials mentioning features or use
|
||||
// of this software. Neither the name of the University nor the names of
|
||||
// its contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
|
||||
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
// This file defines FlexLexer, an abstract class which specifies the
|
||||
// external interface provided to flex C++ lexer objects, and yyFlexLexer,
|
||||
// which defines a particular lexer class.
|
||||
//
|
||||
// If you want to create multiple lexer classes, you use the -P flag
|
||||
// to rename each yyFlexLexer to some other xxFlexLexer. You then
|
||||
// include <FlexLexer.h> in your other sources once per lexer class:
|
||||
//
|
||||
// #undef yyFlexLexer
|
||||
// #define yyFlexLexer xxFlexLexer
|
||||
// #include <FlexLexer.h>
|
||||
//
|
||||
// #undef yyFlexLexer
|
||||
// #define yyFlexLexer zzFlexLexer
|
||||
// #include <FlexLexer.h>
|
||||
// ...
|
||||
|
||||
#ifndef FLEXLEXER_H
|
||||
// Never included before - need to define base class.
|
||||
#define FLEXLEXER_H
|
||||
#include <iostream.h>
|
||||
|
||||
extern "C++" {
|
||||
|
||||
struct yy_buffer_state;
|
||||
typedef int yy_state_type;
|
||||
|
||||
class FlexLexer {
|
||||
public:
|
||||
virtual ~FlexLexer() { }
|
||||
|
||||
const char* YYText() { return yytext; }
|
||||
int YYLeng() { return yyleng; }
|
||||
|
||||
virtual void
|
||||
yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
|
||||
virtual struct yy_buffer_state*
|
||||
yy_create_buffer( istream* s, int size ) = 0;
|
||||
virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
|
||||
virtual void yyrestart( istream* s ) = 0;
|
||||
|
||||
virtual int yylex() = 0;
|
||||
|
||||
// Call yylex with new input/output sources.
|
||||
int yylex( istream* new_in, ostream* new_out = 0 )
|
||||
{
|
||||
switch_streams( new_in, new_out );
|
||||
return yylex();
|
||||
}
|
||||
|
||||
// Switch to new input/output streams. A nil stream pointer
|
||||
// indicates "keep the current one".
|
||||
virtual void switch_streams( istream* new_in = 0,
|
||||
ostream* new_out = 0 ) = 0;
|
||||
|
||||
int lineno() const { return yylineno; }
|
||||
|
||||
int debug() const { return yy_flex_debug; }
|
||||
void set_debug( int flag ) { yy_flex_debug = flag; }
|
||||
|
||||
protected:
|
||||
char* yytext;
|
||||
int yyleng;
|
||||
int yylineno; // only maintained if you use %option yylineno
|
||||
int yy_flex_debug; // only has effect with -d or "%option debug"
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
|
||||
// Either this is the first time through (yyFlexLexerOnce not defined),
|
||||
// or this is a repeated include to define a different flavor of
|
||||
// yyFlexLexer, as discussed in the flex man page.
|
||||
#define yyFlexLexerOnce
|
||||
|
||||
class yyFlexLexer : public FlexLexer {
|
||||
public:
|
||||
// arg_yyin and arg_yyout default to the cin and cout, but we
|
||||
// only make that assignment when initializing in yylex().
|
||||
yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 );
|
||||
|
||||
virtual ~yyFlexLexer();
|
||||
|
||||
void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
|
||||
struct yy_buffer_state* yy_create_buffer( istream* s, int size );
|
||||
void yy_delete_buffer( struct yy_buffer_state* b );
|
||||
void yyrestart( istream* s );
|
||||
|
||||
virtual int yylex();
|
||||
virtual void switch_streams( istream* new_in, ostream* new_out );
|
||||
|
||||
protected:
|
||||
virtual int LexerInput( char* buf, int max_size );
|
||||
virtual void LexerOutput( const char* buf, int size );
|
||||
virtual void LexerError( const char* msg );
|
||||
|
||||
void yyunput( int c, char* buf_ptr );
|
||||
int yyinput();
|
||||
|
||||
void yy_load_buffer_state();
|
||||
void yy_init_buffer( struct yy_buffer_state* b, istream* s );
|
||||
void yy_flush_buffer( struct yy_buffer_state* b );
|
||||
|
||||
int yy_start_stack_ptr;
|
||||
int yy_start_stack_depth;
|
||||
int* yy_start_stack;
|
||||
|
||||
void yy_push_state( int new_state );
|
||||
void yy_pop_state();
|
||||
int yy_top_state();
|
||||
|
||||
yy_state_type yy_get_previous_state();
|
||||
yy_state_type yy_try_NUL_trans( yy_state_type current_state );
|
||||
int yy_get_next_buffer();
|
||||
|
||||
istream* yyin; // input source for default LexerInput
|
||||
ostream* yyout; // output sink for default LexerOutput
|
||||
|
||||
struct yy_buffer_state* yy_current_buffer;
|
||||
|
||||
// yy_hold_char holds the character lost when yytext is formed.
|
||||
char yy_hold_char;
|
||||
|
||||
// Number of characters read into yy_ch_buf.
|
||||
int yy_n_chars;
|
||||
|
||||
// Points to current character in buffer.
|
||||
char* yy_c_buf_p;
|
||||
|
||||
int yy_init; // whether we need to initialize
|
||||
int yy_start; // start state number
|
||||
|
||||
// Flag which is used to allow yywrap()'s to do buffer switches
|
||||
// instead of setting up a fresh yyin. A bit of a hack ...
|
||||
int yy_did_buffer_switch_on_eof;
|
||||
|
||||
// The following are not always needed, but may be depending
|
||||
// on use of certain flex features (like REJECT or yymore()).
|
||||
|
||||
yy_state_type yy_last_accepting_state;
|
||||
char* yy_last_accepting_cpos;
|
||||
|
||||
yy_state_type* yy_state_buf;
|
||||
yy_state_type* yy_state_ptr;
|
||||
|
||||
char* yy_full_match;
|
||||
int* yy_full_state;
|
||||
int yy_full_lp;
|
||||
|
||||
int yy_lp;
|
||||
int yy_looking_for_trail_begin;
|
||||
|
||||
int yy_more_flag;
|
||||
int yy_more_len;
|
||||
int yy_more_offset;
|
||||
int yy_prev_more_offset;
|
||||
};
|
||||
|
||||
#endif
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
--------------------------------------------------------------------
|
||||
The Zend Engine License, Version 2.00
|
||||
Copyright (c) 1999-2006 Zend Technologies Ltd. All rights reserved.
|
||||
Copyright (c) 1999-2003 Zend Technologies Ltd. All rights reserved.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
+4
-6
@@ -14,10 +14,8 @@ libZend_la_SOURCES=\
|
||||
zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
|
||||
zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
|
||||
zend_ini.c zend_qsort.c zend_objects.c zend_object_handlers.c \
|
||||
zend_objects_API.c zend_ts_hash.c zend_stream.c \
|
||||
zend_default_classes.c \
|
||||
zend_iterators.c zend_interfaces.c zend_exceptions.c \
|
||||
zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c
|
||||
zend_objects_API.c zend_ts_hash.c zend_stream.c zend_mm.c \
|
||||
zend_default_classes.c zend_reflection_api.c
|
||||
|
||||
libZend_la_LDFLAGS =
|
||||
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
|
||||
@@ -31,7 +29,7 @@ zend_ini_scanner.lo: zend_ini_parser.h
|
||||
# Language parser/scanner rules
|
||||
|
||||
zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
|
||||
$(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt $(srcdir)/zend_language_scanner_defs.h -o$@ $(srcdir)/zend_language_scanner.l
|
||||
$(LEX) -Pzend -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_language_scanner.l
|
||||
|
||||
zend_language_parser.h: zend_language_parser.c
|
||||
zend_language_parser.c: $(srcdir)/zend_language_parser.y
|
||||
@@ -43,7 +41,7 @@ zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
|
||||
$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o zend_ini_parser.c
|
||||
|
||||
zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
|
||||
$(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt $(srcdir)/zend_ini_scanner_defs.h -o$@ $(srcdir)/zend_ini_scanner.l
|
||||
$(LEX) -Pini_ -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_ini_scanner.l
|
||||
|
||||
zend_ini_parser.h: zend_ini_parser.c
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Zend/zend_execute.lo: $(srcdir)/zend_vm_execute.h $(srcdir)/zend_vm_opcodes.h
|
||||
+1
-1
@@ -51,7 +51,7 @@ write_property is used to directly write object's property by
|
||||
name. This handler is used to assign property variables or to change them
|
||||
in operations like += or ++ (unless get_property_zval_ptr is also set).
|
||||
|
||||
get_property_zval_ptr is used to obtain pointer to modifiable zval for
|
||||
get_property_zval_ptr is used to obtain pointer to modifyable zval for
|
||||
operations like += or ++. This should be used only if your object model
|
||||
stores properties as real zval's that can be modified from outside.
|
||||
Otherwise this handler should be NULL and the engine will use
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
Zend Memory Manager
|
||||
===================
|
||||
|
||||
General:
|
||||
--------
|
||||
|
||||
The goal of the new memory manager (available since PHP 5.2) is to reduce memory
|
||||
allocation overhead and speedup memory management.
|
||||
|
||||
The new manager's "configure" has no "--disable-zend-memory-manager" option,
|
||||
but it has "--enable-malloc-mm" instead. It is enabled by default in DEBUG
|
||||
build and disabled by default in RELEASE build. When enabled it allows selecting
|
||||
between malloc and emalloc at runtime so you can use internal and external memory
|
||||
debuggers without recompilation.
|
||||
|
||||
Debugging:
|
||||
----------
|
||||
|
||||
Normal:
|
||||
|
||||
$ sapi/cli/php -r 'leak();'
|
||||
|
||||
Zend MM disabled:
|
||||
|
||||
$ USE_ZEND_ALLOC=0 valgrind --leak-check=full sapi/cli/php -r 'leak();'
|
||||
|
||||
Shared extensions:
|
||||
------------------
|
||||
|
||||
Since PHP 5.3.11 it is possible to prevent shared extensions from unloading so
|
||||
that valgrind can correctly track the memory leaks in shared extensions. For
|
||||
this there is the ZEND_DONT_UNLOAD_MODULES environment variable. If set, then
|
||||
DL_UNLOAD() is skipped during the shutdown of shared extensions.
|
||||
|
||||
|
||||
Tweaking:
|
||||
---------
|
||||
|
||||
The Zend MM can be tweaked using ZEND_MM_MEM_TYPE and ZEND_MM_SEG_SIZE environment
|
||||
variables. Default values are "malloc" and "256K". Dependent on target system you
|
||||
can also use "mmap_anon", "mmap_zero" and "win32" storage managers.
|
||||
|
||||
$ ZEND_MM_MEM_TYPE=mmap_anon ZEND_MM_SEG_SIZE=1M sapi/cli/php ..etc.
|
||||
@@ -1,108 +0,0 @@
|
||||
ZEND_VM
|
||||
=======
|
||||
|
||||
ZEND_VM architecture allows specializing opcode handlers according to op_type
|
||||
fields and using different execution methods (call threading, switch threading
|
||||
and direct threading). As a result ZE2 got more than 20% speedup on raw PHP
|
||||
code execution (with specialized executor and direct threading execution
|
||||
method). As in most PHP applications raw execution speed isn't the limiting
|
||||
factor but system calls and database callls are, your mileage with this patch
|
||||
will vary.
|
||||
|
||||
Most parts of the old zend_execute.c go into zend_vm_def.h. Here you can
|
||||
find opcode handlers and helpers. The typical opcode handler template looks
|
||||
like this:
|
||||
|
||||
ZEND_VM_HANDLER(<OPCODE-NUMBER>, <OPCODE>, <OP1_TYPES>, <OP2_TYPES>)
|
||||
{
|
||||
<HANDLER'S CODE>
|
||||
}
|
||||
|
||||
<OPCODE-NUMBER> is a opcode number (0, 1, ...)
|
||||
<OPCODE> is an opcode name (ZEN_NOP, ZEND_ADD, :)
|
||||
<OP1_TYPES> & <OP2_TYPES> are masks for allowed operand op_types. Specializer
|
||||
will generate code only for defined combination of types. You can use any
|
||||
combination of the following op_types UNUSED, CONST, VAR, TMP and CV also
|
||||
you can use ANY mask to disable specialization according operand's op_type.
|
||||
<HANDLER'S CODE> is a handler's code itself. For most handlers it stills the
|
||||
same as in old zend_execute.c, but now it uses macros to access opcode operands
|
||||
and some internal executor data.
|
||||
|
||||
You can see the conformity of new macros to old code in the following list:
|
||||
|
||||
EXECUTE_DATA
|
||||
execute_data
|
||||
ZEND_VM_DISPATCH_TO_HANDLER(<OP>)
|
||||
return <OP>_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
|
||||
ZEND_VM_DISPATCH_TO_HELPER(<NAME>)
|
||||
return <NAME>(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
|
||||
ZEND_VM_DISPATCH_TO_HELPER_EX(<NAME>,<PARAM>,<VAL>)
|
||||
return <NAME>(<VAL>, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
|
||||
ZEND_VM_CONTINUE()
|
||||
return 0
|
||||
ZEND_VM_NEXT_OPCODE()
|
||||
NEXT_OPCODE()
|
||||
ZEND_VM_SET_OPCODE(<TARGET>
|
||||
SET_OPCODE(<TARGET>
|
||||
ZEND_VM_INC_OPCODE()
|
||||
INC_OPCOD()
|
||||
ZEND_VM_RETURN_FROM_EXECUTE_LOOP()
|
||||
RETURN_FROM_EXECUTE_LOOP()
|
||||
ZEND_VM_C_LABEL(<LABEL>):
|
||||
<LABEL>:
|
||||
ZEND_VM_C_GOTO(<LABEL>)
|
||||
goto <LABEL>
|
||||
OP<X>_TYPE
|
||||
opline->op<X>.op_type
|
||||
GET_OP<X>_ZVAL_PTR(<TYPE>)
|
||||
get_zval_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
|
||||
GET_OP<X>_ZVAL_PTR_PTR(<TYPE>)
|
||||
get_zval_ptr_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
|
||||
GET_OP<X>_OBJ_ZVAL_PTR(<TYPE>)
|
||||
get_obj_zval_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
|
||||
GET_OP<X>_OBJ_ZVAL_PTR_PTR(<TYPE>)
|
||||
get_obj_zval_ptr_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
|
||||
IS_OP<X>_TMP_FREE()
|
||||
IS_TMP_FREE(free_op<X>)
|
||||
FREE_OP<X>()
|
||||
FREE_OP(free_op<X>)
|
||||
FREE_OP<X>_IF_VAR()
|
||||
FREE_VAR(free_op<X>)
|
||||
FREE_OP<X>_VAR_PTR()
|
||||
FREE_VAR_PTR(free_op<X>)
|
||||
|
||||
|
||||
Executor's helpers can be defined without parameters or with one parameter.
|
||||
This is done with the following constructs:
|
||||
|
||||
ZEND_VM_HELPER(<HELPER-NAME>, <OP1_TYPES>, <OP2_TYPES>)
|
||||
{
|
||||
<HELPER'S CODE>
|
||||
}
|
||||
|
||||
ZEND_VM_HELPER_EX(<HELPER-NAME>, <OP1_TYPES>, <OP2_TYPES>, <PARAM_SPEC>)
|
||||
{
|
||||
<HELPER'S CODE>
|
||||
}
|
||||
|
||||
Executor's code is generated by PHP script zend_vm_gen.php it uses zend_vm_def.h
|
||||
and zend_vm_execute.skl as input and produces zend_vm_opcodes.h and
|
||||
zend_vm_execute.h. The first file is a list of opcode definitions. It is
|
||||
included from zend_compile.h. The second one is an executor code itself. It is
|
||||
included from zend_execute.c.
|
||||
|
||||
zend_vm_gen.php can produce different kind of executors. You can select
|
||||
different opcode threading model using --with-vm-kind=CALL|SWITCH|GOTO. You can
|
||||
disable opcode specialization using --without-specializer. You can include or
|
||||
exclude old executor together with specialized one using --without-old-executor.
|
||||
At last you can debug executor using original zend_vm_def.h or generated file
|
||||
zend_vm_execute.h. Debugging with original file requires --with-lines
|
||||
option. By default ZE2 uses the following command to generate executor:
|
||||
|
||||
$ php zend_vm_gen.php --with-vm-kind=CALL
|
||||
|
||||
Zend Engine II currently includes two executors during the build process, one
|
||||
is the specialized version and the other is the old one non-specialized with
|
||||
function handlers. By default Zend Engine II uses the specialized one but you
|
||||
can switch to the old executor at runtime by calling zend_vm_use_old_executor().
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
Title: Zend 2.0 Namespaces
|
||||
Version: $Id$
|
||||
Status: declined
|
||||
Version: $Revision$
|
||||
Status: draft
|
||||
Maintainer: Stig S. Bakken <ssb@php.net>
|
||||
Created: 2001-09-08
|
||||
Modified: 2001-09-08
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
Title: Loose type requirements for functions
|
||||
Version: $Id$
|
||||
Version: $Revision$
|
||||
Status: draft
|
||||
Maintainer: Brian Moon <brianm@dealnews.com>
|
||||
Created: 2001-09-17
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
Title: Delegation
|
||||
(a/k/a. Object-Based Inheritance)
|
||||
Version: $Revision$
|
||||
Status: draft
|
||||
Maintainer: Sebastian Bergmann <sb@sebastian-bergmann.de>
|
||||
|
||||
|
||||
Dynamic Delegation
|
||||
|
||||
Syntax / Example
|
||||
|
||||
<?php
|
||||
class aDelegatee {
|
||||
function doSomething() {
|
||||
echo 'hubu';
|
||||
}
|
||||
}
|
||||
|
||||
class anotherDelegatee {
|
||||
function doSomething() {
|
||||
echo 'tubu';
|
||||
}
|
||||
}
|
||||
|
||||
class Foo {
|
||||
delegatee $bar;
|
||||
|
||||
function setDelegatee($delegatee) {
|
||||
$this->delegatee = $delegatee;
|
||||
}
|
||||
}
|
||||
|
||||
$foo = new Foo;
|
||||
|
||||
$foo->setDelegatee(new aDelegatee);
|
||||
$foo->doSomething(); /* prints "hubu" */
|
||||
|
||||
$foo->setDelegatee(new anotherDelegatee);
|
||||
$foo->doSomething(); /* prints "tubu" */
|
||||
?>
|
||||
|
||||
Semantics / Synopsis
|
||||
|
||||
The "Foo" class may use all methods available in "$bar" as if they
|
||||
where locally defined or inherited from a superclass. The essential
|
||||
difference is that by assigning another object to "$bar" it is
|
||||
possible to dynamically switch between different implementations for
|
||||
these methods.
|
||||
|
||||
|
||||
Fixed Delegation
|
||||
|
||||
Syntax / Example
|
||||
|
||||
<?php
|
||||
class aDelegatee {
|
||||
function doSomething() {
|
||||
echo 'hubu';
|
||||
}
|
||||
}
|
||||
|
||||
class Foo {
|
||||
final delegatee $bar = new aDelegatee;
|
||||
}
|
||||
|
||||
$foo = new Foo;
|
||||
|
||||
$foo->doSomething(); /* prints "hubu" */
|
||||
?>
|
||||
|
||||
Semantics / Synopsis
|
||||
|
||||
The "Foo" class may use all methods available in "$bar" as if they
|
||||
where locally defined or inherited from a superclass. The difference
|
||||
to the dynamic delegation is that once the delegatee object is set,
|
||||
it cannot be changed.
|
||||
|
||||
|
||||
Default Delegation
|
||||
|
||||
Syntax / Example
|
||||
|
||||
<?php
|
||||
class Foo {
|
||||
function __delegate($name, $parameters = array()) {
|
||||
echo $name;
|
||||
}
|
||||
}
|
||||
|
||||
$foo = new Foo;
|
||||
$foo->bar(); /* prints "bar" */
|
||||
?>
|
||||
|
||||
Semantics / Synopsis
|
||||
|
||||
If a class has a __delegate() method, it is called whenever a
|
||||
method on an object of this class is called that is
|
||||
|
||||
* Not defined in the class.
|
||||
|
||||
* Not provided by a delegatee object.
|
||||
|
||||
The __delegate() method is called with the name and parameters
|
||||
of the method call.
|
||||
|
||||
This supersedes / obsoletes similar functionality introduced in
|
||||
Zend Engine 1 by ext/overload.
|
||||
+72
-485
@@ -19,43 +19,11 @@ Changes in the Zend Engine 2.0
|
||||
the box or after a very small amount of modifications would be
|
||||
high.
|
||||
|
||||
* $this
|
||||
|
||||
Unlike in Zend Engine 1 the pseudo variable $this cannot be
|
||||
exchanged in Zend Engine 2. You can of course modify or work with
|
||||
an object by using $this but you cannot replace $this with another
|
||||
object to change the original object.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class Foo {
|
||||
function replace($other)
|
||||
{
|
||||
$this = $other;
|
||||
}
|
||||
}
|
||||
|
||||
$object = new Foo;
|
||||
$object->prop = 'Hello';
|
||||
|
||||
$other = new Foo;
|
||||
$other->prop = 'Bye';
|
||||
|
||||
$object->replace($other);
|
||||
|
||||
print $object->prop; // still shows 'Hello'
|
||||
|
||||
?>
|
||||
|
||||
Zend Engine 2.0 will issue a compile error, if an assignment
|
||||
to $this is found.
|
||||
|
||||
* Private and Protected Members.
|
||||
|
||||
The Zend Engine 2.0 introduces private and protected member
|
||||
variables. Note that for performance reasons no error message is
|
||||
emitted in case of an illegal access to a private or protectecd
|
||||
The Zend Engine 2.0 introduces private and protected member
|
||||
variables. Note that for performance reasons no error message is
|
||||
emitted in case of an illegal access to a private or protectecd
|
||||
member variable.
|
||||
|
||||
Example:
|
||||
@@ -75,7 +43,7 @@ Changes in the Zend Engine 2.0
|
||||
|
||||
class MyClass2 extends MyClass {
|
||||
protected $Foo;
|
||||
|
||||
|
||||
function printHello() {
|
||||
MyClass::printHello(); /* Should print */
|
||||
print "MyClass2::printHello() " . $this->Hello; /* Shouldn't print out anything */
|
||||
@@ -96,9 +64,9 @@ Changes in the Zend Engine 2.0
|
||||
print $obj->Foo; /* Shouldn't print out anything */
|
||||
$obj->printHello();
|
||||
?>
|
||||
|
||||
Protected member variables can be accessed in classes extending the
|
||||
class they are declared in, whereas private member variables can
|
||||
|
||||
Protected member variables can be accessed in classes extending the
|
||||
class they are declared in, whereas private member variables can
|
||||
only be accessed by the class they belong to.
|
||||
|
||||
* Private and protected methods.
|
||||
@@ -130,14 +98,14 @@ Changes in the Zend Engine 2.0
|
||||
$o->aPublicMethod();
|
||||
?>
|
||||
|
||||
Old code that has no user-defined classes or functions named
|
||||
Old code that has no user-defined classes or functions named
|
||||
'public', 'protected' or 'private' should run without modifications.
|
||||
|
||||
* Abstract Classes and Methods.
|
||||
|
||||
The Zend Engine 2.0 introduces abstract classes and methods. An
|
||||
abstract method only declares the method's signature and does not
|
||||
provide an implementation. A class that contains abstract methods
|
||||
The Zend Engine 2.0 introduces abstract classes and methods. An
|
||||
abstract method only declares the method's signature and does not
|
||||
provide an implementation. A class that contains abstract methods
|
||||
needs to be declared abstract.
|
||||
|
||||
Example:
|
||||
@@ -157,10 +125,9 @@ Changes in the Zend Engine 2.0
|
||||
$o->test();
|
||||
?>
|
||||
|
||||
Classes that do not have abstract methods can be declared abstract
|
||||
to prevent them from being instantiated.
|
||||
Abstract classes cannot be instantiated.
|
||||
|
||||
Old code that has no user-defined classes or functions named
|
||||
Old code that has no user-defined classes or functions named
|
||||
'abstract' should run without modifications.
|
||||
|
||||
* Interfaces.
|
||||
@@ -171,58 +138,24 @@ Changes in the Zend Engine 2.0
|
||||
Example:
|
||||
|
||||
<?php
|
||||
interface Printable {
|
||||
public function dump();
|
||||
interface Throwable {
|
||||
public function getMessage();
|
||||
}
|
||||
|
||||
class PrintableExample implements Printable {
|
||||
public function dump() {
|
||||
class Exception implements Throwable {
|
||||
public function getMessage() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
Old code that has no user-defined classes or functions named
|
||||
Old code that has no user-defined classes or functions named
|
||||
'interface' or 'implements' should run without modifications.
|
||||
|
||||
An interface may extend one or more base interfaces (but not
|
||||
implement them). Neither a class nor an interface can inherit
|
||||
methods of the same name from different root interfaces.
|
||||
|
||||
Interfaces may contain abstract static methods.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
interface Printable {
|
||||
function dump();
|
||||
}
|
||||
|
||||
interface Streamable extends Printable {
|
||||
function writeToStream();
|
||||
static function readFromStream();
|
||||
}
|
||||
|
||||
class PrintableExample implements Streamable {
|
||||
public function dump() {
|
||||
// ...
|
||||
}
|
||||
function writeToStream() {
|
||||
// ...
|
||||
}
|
||||
static function readFromStream() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
A class that does not implement all interface methods must be
|
||||
declared as an abstract class.
|
||||
|
||||
* Class Type Hints.
|
||||
|
||||
While remaining loosely typed the Zend Engine 2.0 introduces the
|
||||
ability to use class type hints to declare the expected class of
|
||||
While remaining loosely typed the Zend Engine 2.0 introduces the
|
||||
ability to use class type hints to declare the expected class of
|
||||
objects that are passed as parameters to a method.
|
||||
|
||||
Example:
|
||||
@@ -272,10 +205,11 @@ Changes in the Zend Engine 2.0
|
||||
|
||||
This syntax only applies to objects/classes, not built-in types.
|
||||
|
||||
* Final methods and classes.
|
||||
* final.
|
||||
|
||||
The Zend Engine 2.0 introduces the "final" keyword to declare
|
||||
final methods. Those cannot be overridden by sub-classes.
|
||||
final members and methods. Those cannot be overridden by
|
||||
sub-classes.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -287,24 +221,7 @@ Changes in the Zend Engine 2.0
|
||||
}
|
||||
?>
|
||||
|
||||
It is furthermore possible to make a class final. Doing this
|
||||
prevents a class from being specialized (it cannot be inherited
|
||||
by another class). There's no need to declare the methods of
|
||||
a final class themselves as final.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
final class Foo {
|
||||
// class definition
|
||||
}
|
||||
// the next line is impossible
|
||||
// class Bork extends Foo {}
|
||||
?>
|
||||
|
||||
Properties cannot be final. See per-class constants below.
|
||||
|
||||
Old code that has no user-defined classes or functions named
|
||||
Old code that has no user-defined classes or functions named
|
||||
'final' should run without modifications.
|
||||
|
||||
* Object Cloning.
|
||||
@@ -325,12 +242,13 @@ Changes in the Zend Engine 2.0
|
||||
replicate the parent object you want to create a new instance of
|
||||
this other object so that the replica has its own separate copy.
|
||||
|
||||
An object copy is created by using the clone operator.
|
||||
An object copy is created by calling the object's __clone()
|
||||
method.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
$copy_of_object = clone $object;
|
||||
$copy_of_object = $object->__clone();
|
||||
?>
|
||||
|
||||
When the developer asks to create a new copy of an object, the
|
||||
@@ -339,40 +257,40 @@ Changes in the Zend Engine 2.0
|
||||
all of the object's properties. If a __clone() method is
|
||||
defined, then it will be responsible to set the necessary
|
||||
properties in the created object. For convenience, the engine
|
||||
ensures, that the clone will be initialized with all of the
|
||||
properties from the source object, so that developers can start
|
||||
with a by-value replica of the source object, and only override
|
||||
properties that need to be changed.
|
||||
will supply a function that imports all of the properties from
|
||||
the source object, so that they can start with a by-value
|
||||
replica of the source object, and only override properties that
|
||||
need to be changed. [The function hasn't been implemented yet]
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class MyCloneable {
|
||||
static $id = 0;
|
||||
static $id = 0;
|
||||
|
||||
function MyCloneable() {
|
||||
$this->id = self::$id++;
|
||||
}
|
||||
function MyCloneable() {
|
||||
$this->id = self::$id++;
|
||||
}
|
||||
|
||||
function __clone() {
|
||||
$this->address = 'New York';
|
||||
$this->id = self::$id++;
|
||||
}
|
||||
function __clone() {
|
||||
$this->name = $that->name;
|
||||
$this->address = 'New York';
|
||||
$this->id = self::$id++;
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new MyCloneable();
|
||||
|
||||
$obj->name = 'Hello';
|
||||
$obj->name = 'Hello';
|
||||
$obj->address = 'Tel-Aviv';
|
||||
|
||||
$obj_clone = clone $obj;
|
||||
print $obj->id . "\n";
|
||||
|
||||
$obj = $obj->__clone();
|
||||
|
||||
print $obj->id . "\n";
|
||||
print $obj->name . "\n";
|
||||
print $obj->address . "\n";
|
||||
|
||||
print $obj_clone->id . "\n";
|
||||
print $obj_clone->name . "\n";
|
||||
print $obj_clone->address . "\n";
|
||||
?>
|
||||
|
||||
* Unified Constructors.
|
||||
@@ -474,27 +392,24 @@ Changes in the Zend Engine 2.0
|
||||
echo 'Foo::constant = ' . Foo::constant . "\n";
|
||||
?>
|
||||
|
||||
Old code that has no user-defined classes or functions
|
||||
The Zend Engine 2.0 allows for expressions within constants:
|
||||
|
||||
<?php
|
||||
class Bar {
|
||||
const a = 1<<0;
|
||||
const b = 1<<1;
|
||||
const c = a | b;
|
||||
}
|
||||
?>
|
||||
|
||||
Old code that has no user-defined classes or functions
|
||||
named 'const' will run without modifications.
|
||||
|
||||
* Exceptions.
|
||||
|
||||
The Zend Engine 1.0 had no exception handling. The Zend Engine 2.0
|
||||
introduces a exception model similar to that of other programming
|
||||
languages. But there is no catch all and no finally clause.
|
||||
|
||||
Old code that has no user-defined classes or functions 'catch',
|
||||
'throw' and 'try' will run without modifications.
|
||||
|
||||
Exceptions can be rethrown in catch blocks. Also it is possible to
|
||||
have multiple catch blocks. In that case the caught exception is
|
||||
compared with the classtype of each catch block from top to bottom
|
||||
and the first block that has a 'instanceof' match gets executed.
|
||||
When the catch block finishes execution continues at the end of
|
||||
the last catch block. If no catch block has a 'instanceof' match
|
||||
then the next try/catch block is searched until no more try/catch
|
||||
blocks are available. In that case the exception is an uncaught
|
||||
exception and the program terminates with showing the exception.
|
||||
languages.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -522,106 +437,14 @@ Changes in the Zend Engine 2.0
|
||||
try {
|
||||
throw new MyExceptionFoo('Hello');
|
||||
}
|
||||
|
||||
catch (MyException $exception) {
|
||||
$exception->Display();
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
echo $exception;
|
||||
}
|
||||
?>
|
||||
|
||||
Even though the above example shows that it is possible to define
|
||||
exception classes that don't inherit from Exception it is best to
|
||||
do so. This is because the internal Exception class can gather a
|
||||
lot of information otherwise not available. The PHP code emulation
|
||||
code would look something like shown below. The comments show the
|
||||
meaning of each property. As the code shows it is possible to read
|
||||
any available information by using the getter methods. But since
|
||||
some of the methods are used internally they are marked final. All
|
||||
in all the class is very restrictive because it must be ensured
|
||||
that anything used internally always works as expected.
|
||||
|
||||
Emulating class Exception:
|
||||
|
||||
<?php
|
||||
class Exception {
|
||||
function __construct(/*string*/ $message=NULL, /*int*/ $code=0) {
|
||||
if (func_num_args()) {
|
||||
$this->message = $message;
|
||||
}
|
||||
$this->code = $code;
|
||||
$this->file = __FILE__; // of throw clause
|
||||
$this->line = __LINE__; // of throw clause
|
||||
$this->trace = debug_backtrace();
|
||||
$this->string = StringFormat($this);
|
||||
}
|
||||
|
||||
protected $message = 'Unknown exception'; // exception message
|
||||
protected $code = 0; // user defined exception code
|
||||
protected $file; // source filename of exception
|
||||
protected $line; // source line of exception
|
||||
|
||||
private $trace; // backtrace of exception
|
||||
private $string; // internal only!!
|
||||
|
||||
final function getMessage() {
|
||||
return $this->message;
|
||||
}
|
||||
final function getCode() {
|
||||
return $this->code;
|
||||
}
|
||||
final function getFile() {
|
||||
return $this->file;
|
||||
}
|
||||
final function getTrace() {
|
||||
return $this->trace;
|
||||
}
|
||||
final function getTraceAsString() {
|
||||
return self::TraceFormat($this);
|
||||
}
|
||||
function _toString() {
|
||||
return $this->string;
|
||||
}
|
||||
static private function StringFormat(Exception $exception) {
|
||||
// ... a function not available in PHP scripts
|
||||
// that returns all relevant information as a string
|
||||
}
|
||||
static private function TraceFormat(Exception $exception) {
|
||||
// ... a function not available in PHP scripts
|
||||
// that returns the backtrace as a string
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
If you derive your exception classes from this Exception base class
|
||||
your exceptions will be nicely shown in the builtin handler for
|
||||
uncaught exceptions.
|
||||
|
||||
Note: The method getMessage() is a final read only access method to
|
||||
the private proeprty message that is set in the constructor. If you
|
||||
feel a need to overwrite the exception display then overload method
|
||||
__toString() in your derived class or implement your own extneral
|
||||
exception display function to accomplish your desired formatting.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
function display_exception(Exception $ex)
|
||||
{
|
||||
echo 'Exception: ' . $ex->getMessage() . 'with backtrace: <pre>';
|
||||
echo $ex->getTrace();
|
||||
echo '</pre>';
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// your code here
|
||||
}
|
||||
catch (Exception $ex)
|
||||
{
|
||||
display_exeption($ex);
|
||||
}
|
||||
?>
|
||||
Old code that has no user-defined classes or functions 'catch',
|
||||
'throw' and 'try' will run without modifications.
|
||||
|
||||
* Dereferencing objects returned from functions.
|
||||
|
||||
@@ -651,21 +474,17 @@ Changes in the Zend Engine 2.0
|
||||
ShapeFactoryMethod('Square')->draw();
|
||||
?>
|
||||
|
||||
* Member variables of classes can now be initialized.
|
||||
* Static member variables of static classes can now be
|
||||
initialized.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class foo {
|
||||
static $my_static = 5;
|
||||
public $my_prop = 'bla';
|
||||
}
|
||||
|
||||
print foo::$my_static;
|
||||
|
||||
$obj = foo;
|
||||
|
||||
print $obj->my_prop;
|
||||
?>
|
||||
|
||||
* Static Methods.
|
||||
@@ -688,22 +507,14 @@ Changes in the Zend Engine 2.0
|
||||
The pseudo variable $this is not available inside a method that
|
||||
has been declared static.
|
||||
|
||||
* instanceof.
|
||||
New support for an instanceof operator which checks if an object
|
||||
is of a certain class or interface type.
|
||||
* instanceof (TBD)
|
||||
|
||||
Example:
|
||||
* Static function variables.
|
||||
|
||||
<?php
|
||||
|
||||
class Foo {
|
||||
}
|
||||
|
||||
$obj = new Foo();
|
||||
if ($obj instanceof Foo) {
|
||||
print "Yay!\n";
|
||||
}
|
||||
?>
|
||||
Statics are now treated at compile-time which allows developers
|
||||
to assign variables to statics by reference. This change also
|
||||
greatly improves their performance but means that indirect
|
||||
references to statics will not work anymore.
|
||||
|
||||
* Parameters that are passed by reference to a function
|
||||
may now have default values.
|
||||
@@ -720,11 +531,10 @@ Changes in the Zend Engine 2.0
|
||||
|
||||
* __autoload().
|
||||
|
||||
The __autoload() interceptor function will be automatically called
|
||||
when an undeclared class is to be instantiated. The name of that
|
||||
class will be passed to the __autoload() interceptor function as its
|
||||
only argument. __autoload() must succeed in loading the class. If it
|
||||
doesn't then an E_ERROR is emitted.
|
||||
The __autoload() interceptor function will be automatically called
|
||||
when an undeclared class is to be instantiated. The name of that
|
||||
class will be passed to the __autoload() interceptor function as its
|
||||
only argument.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -796,229 +606,6 @@ Changes in the Zend Engine 2.0
|
||||
var_dump($a);
|
||||
?>
|
||||
|
||||
* Iteration
|
||||
|
||||
Objects may be iterated in an overloaded way when used with
|
||||
foreach. The default behavior is to iterate over all properties
|
||||
with respect to property visibility.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class Foo {
|
||||
var $x = 1;
|
||||
var $y = 2;
|
||||
}
|
||||
|
||||
$obj = new Foo;
|
||||
|
||||
foreach ($obj as $prp_name => $prop_value) {
|
||||
// using the property
|
||||
}
|
||||
?>
|
||||
|
||||
Each class whose instances can be iterated with foreach should
|
||||
implement the empty interface 'Traversable'. Hence any object
|
||||
that says it implements 'Traversable' can be used with foreach.
|
||||
|
||||
The interfaces 'IteratorAggregate' and 'Iterator' allow to specify
|
||||
how class objects are iterated in PHP code. The first of them simply
|
||||
has a method 'getIterator' which must return an object that either
|
||||
implements the interface 'Iterator' or is instantiated from an
|
||||
internal class that can be iterated.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class ObjectIterator implements Iterator {
|
||||
|
||||
private $obj;
|
||||
private $num;
|
||||
|
||||
function __construct($obj) {
|
||||
$this->obj = $obj;
|
||||
}
|
||||
function rewind() {
|
||||
$this->num = 0;
|
||||
}
|
||||
function valid() {
|
||||
return $this->num < $this->obj->max;
|
||||
}
|
||||
function key() {
|
||||
return $this->num;
|
||||
}
|
||||
function current() {
|
||||
switch($this->num) {
|
||||
case 0: return "1st";
|
||||
case 1: return "2nd";
|
||||
case 2: return "3rd";
|
||||
default: return $this->num."th";
|
||||
}
|
||||
}
|
||||
function next() {
|
||||
$this->num++;
|
||||
}
|
||||
}
|
||||
|
||||
class Object implements IteratorAggregate {
|
||||
|
||||
public $max = 3;
|
||||
|
||||
function getIterator() {
|
||||
return new ObjectIterator($this);
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new Object;
|
||||
|
||||
// this foreach ...
|
||||
foreach($obj as $key => $val) {
|
||||
echo "$key = $val\n";
|
||||
}
|
||||
|
||||
// matches the following 7 lines with the for directive.
|
||||
$it = $obj->getIterator();
|
||||
for($it->rewind(); $it->valid(); $it->next()) {
|
||||
$key = $it->key();
|
||||
$val = $it->current();
|
||||
echo "$key = $val\n";
|
||||
}
|
||||
unset($it);
|
||||
?>
|
||||
|
||||
The matching for directive is very intersting here since it shows
|
||||
the use of all abstract methods declared in the interfaces Iterator
|
||||
and IteratorAggregate respectively.
|
||||
|
||||
* Array overloading
|
||||
|
||||
Objects can be used with Array notation when they implement the
|
||||
interface ArrayAccess. You cannot use such objects in standard
|
||||
array functions, however you have full control over the array
|
||||
notation. This allows lazy initialization or read only array.
|
||||
|
||||
Note that setting [] results in a call to offsetSet() with
|
||||
index being NULL. That means that as with standard arrays you
|
||||
cannot store NULL keys.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class ArrayClass implements ArrayAccess {
|
||||
public $a = array();
|
||||
|
||||
function offsetExists($index) {
|
||||
return array_key_exists($index, $this->a);
|
||||
}
|
||||
function offsetGet($index) {
|
||||
return $this->a[$index];
|
||||
}
|
||||
function offsetSet($index, $newval) {
|
||||
return $this->a[$index] = $newval;
|
||||
}
|
||||
function offsetUnset($index) {
|
||||
unset($this->a[$index]);
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new ArrayClass;
|
||||
|
||||
$obj[0] = 'bla'; // calls offsetSet(0,'bla')
|
||||
$obj[] = 42; // calls offsetSet(NULL, 42)
|
||||
$x = $obj[0]; // calls offsetGet(0)
|
||||
$b = isset($obj[0]); // calls offsetExists(0)
|
||||
unset($obj[0]); // calls offsetUnset(0)
|
||||
?>
|
||||
|
||||
|
||||
* __METHOD__
|
||||
|
||||
The pseudo constant __METHOD__ shows the current class and method
|
||||
when used inside a method and the function when used outside of a
|
||||
class.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class Foo {
|
||||
function Show() {
|
||||
echo __FILE__ . '(' . __LINE__ . ')' . __METHOD__;
|
||||
}
|
||||
}
|
||||
function Test() {
|
||||
echo __FILE__ . '(' . __LINE__ . ')' . __METHOD__;
|
||||
}
|
||||
?>
|
||||
|
||||
* __toString()
|
||||
|
||||
The magic method __toString() allows to overload the object to
|
||||
string conversion. This conversion is only done automatically for
|
||||
the printing functions (echo, print) but not for other functions
|
||||
that expect strings. Also the function __toString is not used in
|
||||
places where objects are not allowed but strings are like array
|
||||
indices. Note that specialized objects may be converted to a string
|
||||
in any place but without calling __toString().
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class Foo {
|
||||
function __toString() {
|
||||
return "What ever";
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new Foo;
|
||||
|
||||
$str = (string) $obj; // call __toString()
|
||||
|
||||
echo $obj; // call __toString()
|
||||
|
||||
$ar = array();
|
||||
$ar[(string)$obj]; // this works
|
||||
$ar[$obj]; // this is not allowed
|
||||
?>
|
||||
|
||||
* Reflection API
|
||||
|
||||
PHP 5 comes with a complete Reflection API that adds the ability to
|
||||
reverse-engineer classes, interfaces, functions and methods as well
|
||||
as extensions.
|
||||
|
||||
The Reflection API also offers ways of getting doc comments for
|
||||
functions, classes and methods.
|
||||
|
||||
Nearly all aspects of object oriented code can be reflected by
|
||||
using the Reflection API which is documented separately:
|
||||
http://sitten-polizei.de/php/reflection_api/docs/language.reflection.html
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class Foo {
|
||||
public $prop;
|
||||
function Func($name) {
|
||||
echo "Hello $name";
|
||||
}
|
||||
}
|
||||
|
||||
ReflectionClass::export('Foo');
|
||||
ReflectionObject::export(new Foo);
|
||||
ReflectionMethod::export('Foo', 'func');
|
||||
ReflectionProperty::export('Foo', 'prop');
|
||||
ReflectionExtension::export('standard');
|
||||
?>
|
||||
|
||||
* New memory manager
|
||||
The Zend Engine has a new memory manager which allows it to run efficiently
|
||||
in multi-threaded environments as it doesn't need to use mutexes to lock
|
||||
and unlock during allocation/deallocation.
|
||||
|
||||
* Others
|
||||
Probably other changes which we forgot to list. This list will be kept up-to-date
|
||||
as much as possible.
|
||||
|
||||
|
||||
Changes in the Zend Engine 1.0
|
||||
|
||||
|
||||
+31
-43
@@ -7,20 +7,20 @@
|
||||
CFG=Zend - Win32 Release_inline
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Zend.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Zend.mak" CFG="Zend - Win32 Release_inline"
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE "Zend - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "Zend - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "Zend - Win32 Release_inline" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
@@ -95,7 +95,7 @@ LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
@@ -123,10 +123,6 @@ SOURCE=.\zend_builtin_functions.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_closures.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_compile.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -155,10 +151,6 @@ SOURCE=.\zend_extensions.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_float.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_hash.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -183,10 +175,6 @@ SOURCE=.\zend_ini_scanner.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_interfaces.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_parser.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -203,6 +191,10 @@ SOURCE=.\zend_llist.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_mm.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_object_handlers.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -231,6 +223,10 @@ SOURCE=.\zend_qsort.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_reflection_api.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_sprintf.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -243,14 +239,6 @@ SOURCE=.\zend_stream.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_string.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ts_hash.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -319,6 +307,10 @@ SOURCE=.\zend_extensions.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_fast_cache.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_globals.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -351,10 +343,6 @@ SOURCE=.\zend_ini_scanner.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_interfaces.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_istdiostream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -375,6 +363,10 @@ SOURCE=.\zend_llist.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_mm.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_modules.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -403,6 +395,10 @@ SOURCE=.\zend_qsort.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_reflection_api.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_stack.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -411,14 +407,6 @@ SOURCE=.\zend_stream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_string.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ts_hash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -453,7 +441,7 @@ BuildCmds= \
|
||||
|
||||
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -508,7 +496,7 @@ BuildCmds= \
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
@@ -537,7 +525,7 @@ InputPath=.\zend_ini_scanner.l
|
||||
|
||||
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -574,7 +562,7 @@ InputPath=".\zend_language_scanner.l"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
|
||||
+53
-238
@@ -4,33 +4,27 @@ dnl
|
||||
dnl This file contains Zend specific autoconf functions.
|
||||
dnl
|
||||
|
||||
AC_DEFUN([LIBZEND_CHECK_INT_TYPE],[
|
||||
AC_MSG_CHECKING(for $1)
|
||||
AC_TRY_COMPILE([
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#elif HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif],
|
||||
[if (($1 *) 0)
|
||||
return 0;
|
||||
if (sizeof ($1))
|
||||
return 0;
|
||||
],[
|
||||
AC_DEFINE_UNQUOTED([HAVE_]translit($1,a-z_-,A-Z__), 1,[Define if $1 type is present. ])
|
||||
AC_MSG_RESULT(yes)
|
||||
], AC_MSG_RESULT(no)
|
||||
)dnl
|
||||
AC_DEFUN(LIBZEND_BISON_CHECK,[
|
||||
|
||||
if test "$YACC" != "bison -y"; then
|
||||
AC_MSG_WARN(You will need bison if you want to regenerate the Zend parser.)
|
||||
else
|
||||
AC_MSG_CHECKING(bison version)
|
||||
set `bison --version| grep 'GNU Bison' | cut -d ' ' -f 4 | sed -e 's/\./ /'`
|
||||
if test "${1}" = "1" -a "${2}" -lt "28"; then
|
||||
AC_MSG_WARN(You will need bison 1.28 if you want to regenerate the Zend parser (found ${1}.${2}).)
|
||||
fi
|
||||
AC_MSG_RESULT(${1}.${2} (ok))
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBZEND_BASIC_CHECKS],[
|
||||
AC_DEFUN(LIBZEND_BASIC_CHECKS,[
|
||||
|
||||
AC_REQUIRE([AC_PROG_YACC])
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AC_PROG_CC_C_O])
|
||||
AC_REQUIRE([AC_PROG_LEX])
|
||||
AC_REQUIRE([AC_HEADER_STDC])
|
||||
|
||||
LIBZEND_BISON_CHECK
|
||||
@@ -48,8 +42,6 @@ if test "$ac_cv_prog_gcc" = "yes" -a "`uname -s`" = "Rhapsody"; then
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS(
|
||||
inttypes.h \
|
||||
stdint.h \
|
||||
limits.h \
|
||||
malloc.h \
|
||||
string.h \
|
||||
@@ -60,17 +52,18 @@ sys/time.h \
|
||||
signal.h \
|
||||
unix.h \
|
||||
stdlib.h \
|
||||
mach-o/dyld.h \
|
||||
dlfcn.h)
|
||||
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SIGNAL
|
||||
|
||||
AC_DEFUN([LIBZEND_LIBDL_CHECKS],[
|
||||
AC_DEFUN(LIBZEND_LIBDL_CHECKS,[
|
||||
AC_CHECK_LIB(dl, dlopen, [LIBS="-ldl $LIBS"])
|
||||
AC_CHECK_FUNC(dlopen,[AC_DEFINE(HAVE_LIBDL, 1,[ ])])
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBZEND_DLSYM_CHECK],[
|
||||
AC_DEFUN(LIBZEND_DLSYM_CHECK,[
|
||||
dnl
|
||||
dnl Ugly hack to check if dlsym() requires a leading underscore in symbol name.
|
||||
dnl
|
||||
@@ -89,58 +82,20 @@ dnl This is required for QNX and may be some BSD derived systems
|
||||
AC_CHECK_TYPE( uint, unsigned int )
|
||||
AC_CHECK_TYPE( ulong, unsigned long )
|
||||
|
||||
dnl Check if int32_t and uint32_t are defined
|
||||
LIBZEND_CHECK_INT_TYPE(int32_t)
|
||||
LIBZEND_CHECK_INT_TYPE(uint32_t)
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_VPRINTF
|
||||
AC_FUNC_MEMCMP
|
||||
AC_FUNC_ALLOCA
|
||||
AC_CHECK_FUNCS(memcpy strdup getpid kill strtod strtol finite fpclass sigsetjmp)
|
||||
AC_CHECK_FUNCS(memcpy strdup getpid kill strtod strtol finite fpclass)
|
||||
AC_ZEND_BROKEN_SPRINTF
|
||||
|
||||
AC_CHECK_FUNCS(finite isfinite isinf isnan)
|
||||
|
||||
ZEND_FP_EXCEPT
|
||||
|
||||
ZEND_CHECK_FLOAT_PRECISION
|
||||
|
||||
dnl test whether double cast to long preserves least significant bits
|
||||
AC_MSG_CHECKING(whether double cast to long preserves least significant bits)
|
||||
|
||||
AC_TRY_RUN([
|
||||
#include <limits.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
if (sizeof(long) == 4) {
|
||||
double d = (double) LONG_MIN * LONG_MIN + 2e9;
|
||||
|
||||
if ((long) d == 2e9 && (long) -d == -2e9) {
|
||||
exit(0);
|
||||
}
|
||||
} else if (sizeof(long) == 8) {
|
||||
double correct = 18e18 - ((double) LONG_MIN * -2); /* Subtract ULONG_MAX + 1 */
|
||||
|
||||
if ((long) 18e18 == correct) { /* On 64-bit, only check between LONG_MAX and ULONG_MAX */
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
], [
|
||||
AC_DEFINE([ZEND_DVAL_TO_LVAL_CAST_OK], 1, [Define if double cast to long preserves least significant bits])
|
||||
AC_MSG_RESULT(yes)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBZEND_ENABLE_DEBUG],[
|
||||
AC_DEFUN(LIBZEND_ENABLE_DEBUG,[
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug Compile with debugging symbols],[
|
||||
@@ -151,18 +106,10 @@ AC_ARG_ENABLE(debug,
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBZEND_OTHER_CHECKS],[
|
||||
|
||||
AC_ARG_WITH(zend-vm,
|
||||
[ --with-zend-vm=TYPE Set virtual machine dispatch method. Type is
|
||||
one of "CALL", "SWITCH" or "GOTO" [TYPE=CALL]],[
|
||||
PHP_ZEND_VM=$withval
|
||||
],[
|
||||
PHP_ZEND_VM=CALL
|
||||
])
|
||||
AC_DEFUN(LIBZEND_OTHER_CHECKS,[
|
||||
|
||||
AC_ARG_ENABLE(maintainer-zts,
|
||||
[ --enable-maintainer-zts Enable thread safety - for code maintainers only!!],[
|
||||
[ --enable-maintainer-zts Enable thread safety - for code maintainers only],[
|
||||
ZEND_MAINTAINER_ZTS=$enableval
|
||||
],[
|
||||
ZEND_MAINTAINER_ZTS=no
|
||||
@@ -170,14 +117,25 @@ AC_ARG_ENABLE(maintainer-zts,
|
||||
|
||||
AC_ARG_ENABLE(inline-optimization,
|
||||
[ --disable-inline-optimization
|
||||
If building zend_execute.lo fails, try this switch],[
|
||||
If building zend_execute.lo fails, try this switch.],[
|
||||
ZEND_INLINE_OPTIMIZATION=$enableval
|
||||
],[
|
||||
ZEND_INLINE_OPTIMIZATION=yes
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([virtual machine dispatch method])
|
||||
AC_MSG_RESULT($PHP_ZEND_VM)
|
||||
AC_ARG_ENABLE(memory-limit,
|
||||
[ --enable-memory-limit Compile with memory limit support. ], [
|
||||
ZEND_MEMORY_LIMIT=$enableval
|
||||
],[
|
||||
ZEND_MEMORY_LIMIT=no
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(zend-multibyte,
|
||||
[ --enable-zend-multibyte Compile with zend multibyte support. ], [
|
||||
ZEND_MULTIBYTE=$enableval
|
||||
],[
|
||||
ZEND_MULTIBYTE=no
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING(whether to enable thread-safety)
|
||||
AC_MSG_RESULT($ZEND_MAINTAINER_ZTS)
|
||||
@@ -185,22 +143,15 @@ AC_MSG_RESULT($ZEND_MAINTAINER_ZTS)
|
||||
AC_MSG_CHECKING(whether to enable inline optimization for GCC)
|
||||
AC_MSG_RESULT($ZEND_INLINE_OPTIMIZATION)
|
||||
|
||||
AC_MSG_CHECKING(whether to enable a memory limit)
|
||||
AC_MSG_RESULT($ZEND_MEMORY_LIMIT)
|
||||
|
||||
AC_MSG_CHECKING(whether to enable Zend debugging)
|
||||
AC_MSG_RESULT($ZEND_DEBUG)
|
||||
|
||||
case $PHP_ZEND_VM in
|
||||
SWITCH)
|
||||
AC_DEFINE(ZEND_VM_KIND,ZEND_VM_KIND_SWITCH,[virtual machine dispatch method])
|
||||
;;
|
||||
GOTO)
|
||||
AC_DEFINE(ZEND_VM_KIND,ZEND_VM_KIND_GOTO,[virtual machine dispatch method])
|
||||
;;
|
||||
*)
|
||||
PHP_ZEND_VM=CALL
|
||||
AC_DEFINE(ZEND_VM_KIND,ZEND_VM_KIND_CALL,[virtual machine dispatch method])
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_MSG_CHECKING(whether to enable Zend multibyte)
|
||||
AC_MSG_RESULT($ZEND_MULTIBYTE)
|
||||
|
||||
if test "$ZEND_DEBUG" = "yes"; then
|
||||
AC_DEFINE(ZEND_DEBUG,1,[ ])
|
||||
echo " $CFLAGS" | grep ' -g' >/dev/null || DEBUG_CFLAGS="-g"
|
||||
@@ -222,6 +173,16 @@ if test "$ZEND_MAINTAINER_ZTS" = "yes"; then
|
||||
LIBZEND_CPLUSPLUS_CHECKS
|
||||
fi
|
||||
|
||||
if test "$ZEND_MEMORY_LIMIT" = "yes"; then
|
||||
AC_DEFINE(MEMORY_LIMIT, 1, [Memory limit])
|
||||
else
|
||||
AC_DEFINE(MEMORY_LIMIT, 0, [Memory limit])
|
||||
fi
|
||||
|
||||
if test "$ZEND_MULTIBYTE" = "yes"; then
|
||||
AC_DEFINE(ZEND_MULTIBYTE, 1, [ ])
|
||||
fi
|
||||
|
||||
changequote({,})
|
||||
if test -n "$GCC" && test "$ZEND_INLINE_OPTIMIZATION" != "yes"; then
|
||||
INLINE_CFLAGS=`echo $ac_n "$CFLAGS $ac_c" | sed s/-O[0-9s]*//`
|
||||
@@ -234,13 +195,6 @@ AC_C_INLINE
|
||||
|
||||
AC_SUBST(INLINE_CFLAGS)
|
||||
|
||||
AC_MSG_CHECKING(target system is Darwin)
|
||||
if echo "$target" | grep "darwin" > /dev/null; then
|
||||
AC_DEFINE([DARWIN], 1, [Define if the target system is darwin])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
dnl test and set the alignment define for ZEND_MM
|
||||
dnl this also does the logarithmic test for ZEND_MM.
|
||||
@@ -283,153 +237,14 @@ int main()
|
||||
LIBZEND_MM_ALIGN_LOG2=`cat conftest.zend | cut -d ' ' -f 2`
|
||||
AC_DEFINE_UNQUOTED(ZEND_MM_ALIGNMENT, $LIBZEND_MM_ALIGN, [ ])
|
||||
AC_DEFINE_UNQUOTED(ZEND_MM_ALIGNMENT_LOG2, $LIBZEND_MM_ALIGN_LOG2, [ ])
|
||||
], [], [
|
||||
dnl cross-compile needs something here
|
||||
LIBZEND_MM_ALIGN=8
|
||||
])
|
||||
|
||||
AC_MSG_RESULT(done)
|
||||
|
||||
dnl test for memory allocation using mmap(MAP_ANON)
|
||||
AC_MSG_CHECKING(for memory allocation using mmap(MAP_ANON))
|
||||
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef MAP_ANON
|
||||
# ifdef MAP_ANONYMOUS
|
||||
# define MAP_ANON MAP_ANONYMOUS
|
||||
# endif
|
||||
#endif
|
||||
#ifndef MREMAP_MAYMOVE
|
||||
# define MREMAP_MAYMOVE 0
|
||||
#endif
|
||||
#ifndef MAP_FAILED
|
||||
# define MAP_FAILED ((void*)-1)
|
||||
#endif
|
||||
|
||||
#define SEG_SIZE (256*1024)
|
||||
|
||||
int main()
|
||||
{
|
||||
void *seg = mmap(NULL, SEG_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
if (seg == MAP_FAILED) {
|
||||
return 1;
|
||||
}
|
||||
if (munmap(seg, SEG_SIZE) != 0) {
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
], [
|
||||
AC_DEFINE([HAVE_MEM_MMAP_ANON], 1, [Define if the target system has support for memory allocation using mmap(MAP_ANON)])
|
||||
AC_MSG_RESULT(yes)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
], [
|
||||
dnl cross-compile needs something here
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
dnl test for memory allocation using mmap("/dev/zero")
|
||||
AC_MSG_CHECKING(for memory allocation using mmap("/dev/zero"))
|
||||
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef MAP_ANON
|
||||
# ifdef MAP_ANONYMOUS
|
||||
# define MAP_ANON MAP_ANONYMOUS
|
||||
# endif
|
||||
#endif
|
||||
#ifndef MREMAP_MAYMOVE
|
||||
# define MREMAP_MAYMOVE 0
|
||||
#endif
|
||||
#ifndef MAP_FAILED
|
||||
# define MAP_FAILED ((void*)-1)
|
||||
#endif
|
||||
|
||||
#define SEG_SIZE (256*1024)
|
||||
|
||||
int main()
|
||||
{
|
||||
int fd;
|
||||
void *seg;
|
||||
|
||||
fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
return 1;
|
||||
}
|
||||
seg = mmap(NULL, SEG_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||
if (seg == MAP_FAILED) {
|
||||
return 2;
|
||||
}
|
||||
if (munmap(seg, SEG_SIZE) != 0) {
|
||||
return 3;
|
||||
}
|
||||
if (close(fd) != 0) {
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
], [
|
||||
AC_DEFINE([HAVE_MEM_MMAP_ZERO], 1, [Define if the target system has support for memory allocation using mmap("/dev/zero")])
|
||||
AC_MSG_RESULT(yes)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
], [
|
||||
dnl cross-compile needs something here
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
AC_CHECK_FUNCS(mremap)
|
||||
|
||||
|
||||
AC_ARG_ENABLE(zend-signals,
|
||||
[ --enable-zend-signals Use zend signal handling],[
|
||||
ZEND_SIGNALS=$enableval
|
||||
],[
|
||||
ZEND_SIGNALS=no
|
||||
])
|
||||
|
||||
AC_CHECK_FUNC(sigaction, [
|
||||
AC_DEFINE(HAVE_SIGACTION, 1, [Whether sigaction() is available])
|
||||
], [
|
||||
ZEND_SIGNALS=no
|
||||
])
|
||||
if test "$ZEND_SIGNALS" = "yes"; then
|
||||
AC_DEFINE(ZEND_SIGNALS, 1, [Use zend signal handling])
|
||||
CFLAGS="$CFLAGS -DZEND_SIGNALS"
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(whether to enable zend signal handling)
|
||||
AC_MSG_RESULT($ZEND_SIGNALS)
|
||||
AC_DEFUN(LIBZEND_CPLUSPLUS_CHECKS,[
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBZEND_CPLUSPLUS_CHECKS],[
|
||||
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING(whether /dev/urandom exists)
|
||||
if test -r "/dev/urandom" && test -c "/dev/urandom"; then
|
||||
AC_DEFINE([HAVE_DEV_URANDOM], 1, [Define if the target system has /dev/urandom device])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(whether /dev/arandom exists)
|
||||
if test -r "/dev/arandom" && test -c "/dev/arandom"; then
|
||||
AC_DEFINE([HAVE_DEV_ARANDOM], 1, [Define if the target system has /dev/arandom device])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
fi
|
||||
+20
-45
@@ -148,10 +148,6 @@ SOURCE=.\zend_builtin_functions.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_closures.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_compile.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -168,12 +164,7 @@ SOURCE=.\zend_dynamic_array.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_exceptions.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_execute.c
|
||||
# ADD CPP /I "..\TSRM"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -209,14 +200,6 @@ SOURCE=.\zend_ini_scanner.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_interfaces.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_iterators.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_parser.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -233,6 +216,10 @@ SOURCE=.\zend_llist.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_mm.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_object_handlers.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -261,6 +248,10 @@ SOURCE=.\zend_qsort.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_reflection_api.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_sprintf.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -273,14 +264,6 @@ SOURCE=.\zend_stream.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_string.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ts_hash.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -337,10 +320,6 @@ SOURCE=.\zend_errors.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_exceptions.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_execute.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -349,6 +328,10 @@ SOURCE=.\zend_extensions.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_fast_cache.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_globals.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -381,18 +364,10 @@ SOURCE=.\zend_ini_scanner.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_interfaces.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_istdiostream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_iterators.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_parser.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -409,6 +384,10 @@ SOURCE=.\zend_llist.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_mm.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_modules.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -437,6 +416,10 @@ SOURCE=.\zend_qsort.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_reflection_api.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_stack.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -445,14 +428,6 @@ SOURCE=.\zend_stream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_string.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ts_hash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998-2003 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.zend.com/license/2_00.txt. |
|
||||
| If you did not receive a copy of the Zend license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@zend.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#define ZEND_API
|
||||
#define ZEND_DLEXPORT
|
||||
#define ZEND_DLIMPORT
|
||||
|
||||
#ifndef NETWARE
|
||||
@TOP@
|
||||
#endif
|
||||
|
||||
#undef uint
|
||||
#undef ulong
|
||||
|
||||
/* Define if you want to enable memory limit support */
|
||||
#define MEMORY_LIMIT 0
|
||||
|
||||
#ifndef NETWARE
|
||||
@BOTTOM@
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IEEEFP_H
|
||||
# include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#if ZEND_BROKEN_SPRINTF
|
||||
int zend_sprintf(char *buffer, const char *format, ...);
|
||||
#else
|
||||
# define zend_sprintf sprintf
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifndef zend_isnan
|
||||
#ifdef HAVE_ISNAN
|
||||
#define zend_isnan(a) isnan(a)
|
||||
#elif defined(NAN)
|
||||
#define zend_isnan(a) (((a)==NAN)?1:0)
|
||||
#elif defined(HAVE_FPCLASS)
|
||||
#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN))
|
||||
#else
|
||||
#define zend_isnan(a) 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ISINF
|
||||
#define zend_isinf(a) isinf(a)
|
||||
#elif defined(INFINITY)
|
||||
/* Might not work, but is required by ISO C99 */
|
||||
#define zend_isinf(a) (((a)==INFINITY)?1:0)
|
||||
#elif defined(HAVE_FPCLASS)
|
||||
#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF))
|
||||
#else
|
||||
#define zend_isinf(a) 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FINITE
|
||||
#define zend_finite(a) finite(a)
|
||||
#elif defined(HAVE_ISFINITE) || defined(isfinite)
|
||||
#define zend_finite(a) isfinite(a)
|
||||
#elif defined(fpclassify)
|
||||
#define zend_finite(a) ((fpclassify((a))!=FP_INFINITE&&fpclassify((a))!=FP_NAN)?1:0)
|
||||
#else
|
||||
#define zend_finite(a) (zend_isnan(a) ? 0 : zend_isinf(a) ? 0 : 1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
+3
-177
@@ -2,40 +2,7 @@ dnl $Id$
|
||||
dnl
|
||||
dnl This file contains local autoconf functions.
|
||||
|
||||
AC_DEFUN([LIBZEND_BISON_CHECK],[
|
||||
# we only support certain bison versions
|
||||
bison_version_list="1.28 1.35 1.75 1.875 2.0 2.1 2.2 2.3 2.4 2.4.1 2.4.2 2.4.3 2.5 2.5.1 2.6 2.6.1 2.6.2"
|
||||
|
||||
# for standalone build of Zend Engine
|
||||
test -z "$SED" && SED=sed
|
||||
|
||||
bison_version=none
|
||||
if test "$YACC"; then
|
||||
AC_CACHE_CHECK([for bison version], php_cv_bison_version, [
|
||||
bison_version_vars=`bison --version 2> /dev/null | grep 'GNU Bison' | cut -d ' ' -f 4 | $SED -e 's/\./ /' | tr -d a-z`
|
||||
php_cv_bison_version=invalid
|
||||
if test -n "$bison_version_vars"; then
|
||||
set $bison_version_vars
|
||||
bison_version="${1}.${2}"
|
||||
for bison_check_version in $bison_version_list; do
|
||||
if test "$bison_version" = "$bison_check_version"; then
|
||||
php_cv_bison_version="$bison_check_version (ok)"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
fi
|
||||
case $php_cv_bison_version in
|
||||
""|invalid[)]
|
||||
bison_msg="bison versions supported for regeneration of the Zend/PHP parsers: $bison_version_list (found: $bison_version)."
|
||||
AC_MSG_WARN([$bison_msg])
|
||||
YACC="exit 0;"
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
||||
AC_DEFUN([ZEND_FP_EXCEPT],[
|
||||
AC_DEFUN(ZEND_FP_EXCEPT,[
|
||||
AC_CACHE_CHECK(whether fp_except is defined, ac_cv_type_fp_except,[
|
||||
AC_TRY_COMPILE([
|
||||
#include <floatingpoint.h>
|
||||
@@ -56,7 +23,7 @@ fp_except x = (fp_except) 0;
|
||||
dnl
|
||||
dnl Check for broken sprintf()
|
||||
dnl
|
||||
AC_DEFUN([AC_ZEND_BROKEN_SPRINTF],[
|
||||
AC_DEFUN(AC_ZEND_BROKEN_SPRINTF,[
|
||||
AC_CACHE_CHECK(whether sprintf is broken, ac_cv_broken_sprintf,[
|
||||
AC_TRY_RUN([main() {char buf[20];exit(sprintf(buf,"testing 123")!=11); }],[
|
||||
ac_cv_broken_sprintf=no
|
||||
@@ -74,148 +41,7 @@ AC_DEFUN([AC_ZEND_BROKEN_SPRINTF],[
|
||||
AC_DEFINE_UNQUOTED(ZEND_BROKEN_SPRINTF, $ac_result, [Whether sprintf is broken])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl AC_ZEND_C_BIGENDIAN
|
||||
dnl Replacement macro for AC_C_BIGENDIAN
|
||||
dnl
|
||||
AC_DEFUN([AC_ZEND_C_BIGENDIAN],
|
||||
[AC_CACHE_CHECK([whether byte ordering is bigendian], ac_cv_c_bigendian_php,
|
||||
[
|
||||
ac_cv_c_bigendian_php=unknown
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
int main(void)
|
||||
{
|
||||
short one = 1;
|
||||
char *cp = (char *)&one;
|
||||
|
||||
if (*cp == 0) {
|
||||
return(0);
|
||||
} else {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
], [ac_cv_c_bigendian_php=yes], [ac_cv_c_bigendian_php=no], [ac_cv_c_bigendian_php=unknown])
|
||||
])
|
||||
if test $ac_cv_c_bigendian_php = yes; then
|
||||
AC_DEFINE(WORDS_BIGENDIAN, [], [Define if processor uses big-endian word])
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([AM_SET_LIBTOOL_VARIABLE],[
|
||||
AC_DEFUN(AM_SET_LIBTOOL_VARIABLE,[
|
||||
LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
|
||||
])
|
||||
|
||||
dnl x87 floating point internal precision control checks
|
||||
dnl See: http://wiki.php.net/rfc/rounding
|
||||
AC_DEFUN([ZEND_CHECK_FLOAT_PRECISION],[
|
||||
AC_MSG_CHECKING([for usable _FPU_SETCW])
|
||||
AC_TRY_LINK([
|
||||
#include <fpu_control.h>
|
||||
],[
|
||||
fpu_control_t fpu_oldcw, fpu_cw;
|
||||
volatile double result;
|
||||
double a = 2877.0;
|
||||
volatile double b = 1000000.0;
|
||||
|
||||
_FPU_GETCW(fpu_oldcw);
|
||||
fpu_cw = (fpu_oldcw & ~_FPU_EXTENDED & ~_FPU_SINGLE) | _FPU_DOUBLE;
|
||||
_FPU_SETCW(fpu_cw);
|
||||
result = a / b;
|
||||
_FPU_SETCW(fpu_oldcw);
|
||||
], [ac_cfp_have__fpu_setcw=yes], [ac_cfp_have__fpu_setcw=no])
|
||||
if test "$ac_cfp_have__fpu_setcw" = "yes" ; then
|
||||
AC_DEFINE(HAVE__FPU_SETCW, 1, [whether _FPU_SETCW is present and usable])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for usable fpsetprec])
|
||||
AC_TRY_LINK([
|
||||
#include <machine/ieeefp.h>
|
||||
],[
|
||||
fp_prec_t fpu_oldprec;
|
||||
volatile double result;
|
||||
double a = 2877.0;
|
||||
volatile double b = 1000000.0;
|
||||
|
||||
fpu_oldprec = fpgetprec();
|
||||
fpsetprec(FP_PD);
|
||||
result = a / b;
|
||||
fpsetprec(fpu_oldprec);
|
||||
], [ac_cfp_have_fpsetprec=yes], [ac_cfp_have_fpsetprec=no])
|
||||
if test "$ac_cfp_have_fpsetprec" = "yes" ; then
|
||||
AC_DEFINE(HAVE_FPSETPREC, 1, [whether fpsetprec is present and usable])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for usable _controlfp])
|
||||
AC_TRY_LINK([
|
||||
#include <float.h>
|
||||
],[
|
||||
unsigned int fpu_oldcw;
|
||||
volatile double result;
|
||||
double a = 2877.0;
|
||||
volatile double b = 1000000.0;
|
||||
|
||||
fpu_oldcw = _controlfp(0, 0);
|
||||
_controlfp(_PC_53, _MCW_PC);
|
||||
result = a / b;
|
||||
_controlfp(fpu_oldcw, _MCW_PC);
|
||||
], [ac_cfp_have__controlfp=yes], [ac_cfp_have__controlfp=no])
|
||||
if test "$ac_cfp_have__controlfp" = "yes" ; then
|
||||
AC_DEFINE(HAVE__CONTROLFP, 1, [whether _controlfp is present usable])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for usable _controlfp_s])
|
||||
AC_TRY_LINK([
|
||||
#include <float.h>
|
||||
],[
|
||||
unsigned int fpu_oldcw, fpu_cw;
|
||||
volatile double result;
|
||||
double a = 2877.0;
|
||||
volatile double b = 1000000.0;
|
||||
|
||||
_controlfp_s(&fpu_cw, 0, 0);
|
||||
fpu_oldcw = fpu_cw;
|
||||
_controlfp_s(&fpu_cw, _PC_53, _MCW_PC);
|
||||
result = a / b;
|
||||
_controlfp_s(&fpu_cw, fpu_oldcw, _MCW_PC);
|
||||
], [ac_cfp_have__controlfp_s=yes], [ac_cfp_have__controlfp_s=no])
|
||||
if test "$ac_cfp_have__controlfp_s" = "yes" ; then
|
||||
AC_DEFINE(HAVE__CONTROLFP_S, 1, [whether _controlfp_s is present and usable])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether FPU control word can be manipulated by inline assembler])
|
||||
AC_TRY_LINK([
|
||||
/* nothing */
|
||||
],[
|
||||
unsigned int oldcw, cw;
|
||||
volatile double result;
|
||||
double a = 2877.0;
|
||||
volatile double b = 1000000.0;
|
||||
|
||||
__asm__ __volatile__ ("fnstcw %0" : "=m" (*&oldcw));
|
||||
cw = (oldcw & ~0x0 & ~0x300) | 0x200;
|
||||
__asm__ __volatile__ ("fldcw %0" : : "m" (*&cw));
|
||||
|
||||
result = a / b;
|
||||
|
||||
__asm__ __volatile__ ("fldcw %0" : : "m" (*&oldcw));
|
||||
], [ac_cfp_have_fpu_inline_asm_x86=yes], [ac_cfp_have_fpu_inline_asm_x86=no])
|
||||
if test "$ac_cfp_have_fpu_inline_asm_x86" = "yes" ; then
|
||||
AC_DEFINE(HAVE_FPU_INLINE_ASM_X86, 1, [whether FPU control word can be manipulated by inline assembler])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
])
|
||||
-422
@@ -1,422 +0,0 @@
|
||||
<?php
|
||||
if (function_exists("date_default_timezone_set")) {
|
||||
date_default_timezone_set("UTC");
|
||||
}
|
||||
|
||||
function simple() {
|
||||
$a = 0;
|
||||
for ($i = 0; $i < 1000000; $i++)
|
||||
$a++;
|
||||
|
||||
$thisisanotherlongname = 0;
|
||||
for ($thisisalongname = 0; $thisisalongname < 1000000; $thisisalongname++)
|
||||
$thisisanotherlongname++;
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function simplecall() {
|
||||
for ($i = 0; $i < 1000000; $i++)
|
||||
strlen("hallo");
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function hallo($a) {
|
||||
}
|
||||
|
||||
function simpleucall() {
|
||||
for ($i = 0; $i < 1000000; $i++)
|
||||
hallo("hallo");
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function simpleudcall() {
|
||||
for ($i = 0; $i < 1000000; $i++)
|
||||
hallo2("hallo");
|
||||
}
|
||||
|
||||
function hallo2($a) {
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function mandel() {
|
||||
$w1=50;
|
||||
$h1=150;
|
||||
$recen=-.45;
|
||||
$imcen=0.0;
|
||||
$r=0.7;
|
||||
$s=0; $rec=0; $imc=0; $re=0; $im=0; $re2=0; $im2=0;
|
||||
$x=0; $y=0; $w2=0; $h2=0; $color=0;
|
||||
$s=2*$r/$w1;
|
||||
$w2=40;
|
||||
$h2=12;
|
||||
for ($y=0 ; $y<=$w1; $y=$y+1) {
|
||||
$imc=$s*($y-$h2)+$imcen;
|
||||
for ($x=0 ; $x<=$h1; $x=$x+1) {
|
||||
$rec=$s*($x-$w2)+$recen;
|
||||
$re=$rec;
|
||||
$im=$imc;
|
||||
$color=1000;
|
||||
$re2=$re*$re;
|
||||
$im2=$im*$im;
|
||||
while( ((($re2+$im2)<1000000) && $color>0)) {
|
||||
$im=$re*$im*2+$imc;
|
||||
$re=$re2-$im2+$rec;
|
||||
$re2=$re*$re;
|
||||
$im2=$im*$im;
|
||||
$color=$color-1;
|
||||
}
|
||||
if ( $color==0 ) {
|
||||
print "_";
|
||||
} else {
|
||||
print "#";
|
||||
}
|
||||
}
|
||||
print "<br>";
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function mandel2() {
|
||||
$b = " .:,;!/>)|&IH%*#";
|
||||
//float r, i, z, Z, t, c, C;
|
||||
for ($y=30; printf("\n"), $C = $y*0.1 - 1.5, $y--;){
|
||||
for ($x=0; $c = $x*0.04 - 2, $z=0, $Z=0, $x++ < 75;){
|
||||
for ($r=$c, $i=$C, $k=0; $t = $z*$z - $Z*$Z + $r, $Z = 2*$z*$Z + $i, $z=$t, $k<5000; $k++)
|
||||
if ($z*$z + $Z*$Z > 500000) break;
|
||||
echo $b[$k%16];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function Ack($m, $n){
|
||||
if($m == 0) return $n+1;
|
||||
if($n == 0) return Ack($m-1, 1);
|
||||
return Ack($m - 1, Ack($m, ($n - 1)));
|
||||
}
|
||||
|
||||
function ackermann($n) {
|
||||
$r = Ack(3,$n);
|
||||
print "Ack(3,$n): $r\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function ary($n) {
|
||||
for ($i=0; $i<$n; $i++) {
|
||||
$X[$i] = $i;
|
||||
}
|
||||
for ($i=$n-1; $i>=0; $i--) {
|
||||
$Y[$i] = $X[$i];
|
||||
}
|
||||
$last = $n-1;
|
||||
print "$Y[$last]\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function ary2($n) {
|
||||
for ($i=0; $i<$n;) {
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
}
|
||||
for ($i=$n-1; $i>=0;) {
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
}
|
||||
$last = $n-1;
|
||||
print "$Y[$last]\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function ary3($n) {
|
||||
for ($i=0; $i<$n; $i++) {
|
||||
$X[$i] = $i + 1;
|
||||
$Y[$i] = 0;
|
||||
}
|
||||
for ($k=0; $k<1000; $k++) {
|
||||
for ($i=$n-1; $i>=0; $i--) {
|
||||
$Y[$i] += $X[$i];
|
||||
}
|
||||
}
|
||||
$last = $n-1;
|
||||
print "$Y[0] $Y[$last]\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function fibo_r($n){
|
||||
return(($n < 2) ? 1 : fibo_r($n - 2) + fibo_r($n - 1));
|
||||
}
|
||||
|
||||
function fibo($n) {
|
||||
$r = fibo_r($n);
|
||||
print "$r\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function hash1($n) {
|
||||
for ($i = 1; $i <= $n; $i++) {
|
||||
$X[dechex($i)] = $i;
|
||||
}
|
||||
$c = 0;
|
||||
for ($i = $n; $i > 0; $i--) {
|
||||
if ($X[dechex($i)]) { $c++; }
|
||||
}
|
||||
print "$c\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function hash2($n) {
|
||||
for ($i = 0; $i < $n; $i++) {
|
||||
$hash1["foo_$i"] = $i;
|
||||
$hash2["foo_$i"] = 0;
|
||||
}
|
||||
for ($i = $n; $i > 0; $i--) {
|
||||
foreach($hash1 as $key => $value) $hash2[$key] += $value;
|
||||
}
|
||||
$first = "foo_0";
|
||||
$last = "foo_".($n-1);
|
||||
print "$hash1[$first] $hash1[$last] $hash2[$first] $hash2[$last]\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function gen_random ($n) {
|
||||
global $LAST;
|
||||
return( ($n * ($LAST = ($LAST * IA + IC) % IM)) / IM );
|
||||
}
|
||||
|
||||
function heapsort_r($n, &$ra) {
|
||||
$l = ($n >> 1) + 1;
|
||||
$ir = $n;
|
||||
|
||||
while (1) {
|
||||
if ($l > 1) {
|
||||
$rra = $ra[--$l];
|
||||
} else {
|
||||
$rra = $ra[$ir];
|
||||
$ra[$ir] = $ra[1];
|
||||
if (--$ir == 1) {
|
||||
$ra[1] = $rra;
|
||||
return;
|
||||
}
|
||||
}
|
||||
$i = $l;
|
||||
$j = $l << 1;
|
||||
while ($j <= $ir) {
|
||||
if (($j < $ir) && ($ra[$j] < $ra[$j+1])) {
|
||||
$j++;
|
||||
}
|
||||
if ($rra < $ra[$j]) {
|
||||
$ra[$i] = $ra[$j];
|
||||
$j += ($i = $j);
|
||||
} else {
|
||||
$j = $ir + 1;
|
||||
}
|
||||
}
|
||||
$ra[$i] = $rra;
|
||||
}
|
||||
}
|
||||
|
||||
function heapsort($N) {
|
||||
global $LAST;
|
||||
|
||||
define("IM", 139968);
|
||||
define("IA", 3877);
|
||||
define("IC", 29573);
|
||||
|
||||
$LAST = 42;
|
||||
for ($i=1; $i<=$N; $i++) {
|
||||
$ary[$i] = gen_random(1);
|
||||
}
|
||||
heapsort_r($N, $ary);
|
||||
printf("%.10f\n", $ary[$N]);
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function mkmatrix ($rows, $cols) {
|
||||
$count = 1;
|
||||
$mx = array();
|
||||
for ($i=0; $i<$rows; $i++) {
|
||||
for ($j=0; $j<$cols; $j++) {
|
||||
$mx[$i][$j] = $count++;
|
||||
}
|
||||
}
|
||||
return($mx);
|
||||
}
|
||||
|
||||
function mmult ($rows, $cols, $m1, $m2) {
|
||||
$m3 = array();
|
||||
for ($i=0; $i<$rows; $i++) {
|
||||
for ($j=0; $j<$cols; $j++) {
|
||||
$x = 0;
|
||||
for ($k=0; $k<$cols; $k++) {
|
||||
$x += $m1[$i][$k] * $m2[$k][$j];
|
||||
}
|
||||
$m3[$i][$j] = $x;
|
||||
}
|
||||
}
|
||||
return($m3);
|
||||
}
|
||||
|
||||
function matrix($n) {
|
||||
$SIZE = 30;
|
||||
$m1 = mkmatrix($SIZE, $SIZE);
|
||||
$m2 = mkmatrix($SIZE, $SIZE);
|
||||
while ($n--) {
|
||||
$mm = mmult($SIZE, $SIZE, $m1, $m2);
|
||||
}
|
||||
print "{$mm[0][0]} {$mm[2][3]} {$mm[3][2]} {$mm[4][4]}\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function nestedloop($n) {
|
||||
$x = 0;
|
||||
for ($a=0; $a<$n; $a++)
|
||||
for ($b=0; $b<$n; $b++)
|
||||
for ($c=0; $c<$n; $c++)
|
||||
for ($d=0; $d<$n; $d++)
|
||||
for ($e=0; $e<$n; $e++)
|
||||
for ($f=0; $f<$n; $f++)
|
||||
$x++;
|
||||
print "$x\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function sieve($n) {
|
||||
$count = 0;
|
||||
while ($n-- > 0) {
|
||||
$count = 0;
|
||||
$flags = range (0,8192);
|
||||
for ($i=2; $i<8193; $i++) {
|
||||
if ($flags[$i] > 0) {
|
||||
for ($k=$i+$i; $k <= 8192; $k+=$i) {
|
||||
$flags[$k] = 0;
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
print "Count: $count\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function strcat($n) {
|
||||
$str = "";
|
||||
while ($n-- > 0) {
|
||||
$str .= "hello\n";
|
||||
}
|
||||
$len = strlen($str);
|
||||
print "$len\n";
|
||||
}
|
||||
|
||||
/*****/
|
||||
|
||||
function getmicrotime()
|
||||
{
|
||||
$t = gettimeofday();
|
||||
return ($t['sec'] + $t['usec'] / 1000000);
|
||||
}
|
||||
|
||||
function start_test()
|
||||
{
|
||||
ob_start();
|
||||
return getmicrotime();
|
||||
}
|
||||
|
||||
function end_test($start, $name)
|
||||
{
|
||||
global $total;
|
||||
$end = getmicrotime();
|
||||
ob_end_clean();
|
||||
$total += $end-$start;
|
||||
$num = number_format($end-$start,3);
|
||||
$pad = str_repeat(" ", 24-strlen($name)-strlen($num));
|
||||
|
||||
echo $name.$pad.$num."\n";
|
||||
ob_start();
|
||||
return getmicrotime();
|
||||
}
|
||||
|
||||
function total()
|
||||
{
|
||||
global $total;
|
||||
$pad = str_repeat("-", 24);
|
||||
echo $pad."\n";
|
||||
$num = number_format($total,3);
|
||||
$pad = str_repeat(" ", 24-strlen("Total")-strlen($num));
|
||||
echo "Total".$pad.$num."\n";
|
||||
}
|
||||
|
||||
$t0 = $t = start_test();
|
||||
simple();
|
||||
$t = end_test($t, "simple");
|
||||
simplecall();
|
||||
$t = end_test($t, "simplecall");
|
||||
simpleucall();
|
||||
$t = end_test($t, "simpleucall");
|
||||
simpleudcall();
|
||||
$t = end_test($t, "simpleudcall");
|
||||
mandel();
|
||||
$t = end_test($t, "mandel");
|
||||
mandel2();
|
||||
$t = end_test($t, "mandel2");
|
||||
ackermann(7);
|
||||
$t = end_test($t, "ackermann(7)");
|
||||
ary(50000);
|
||||
$t = end_test($t, "ary(50000)");
|
||||
ary2(50000);
|
||||
$t = end_test($t, "ary2(50000)");
|
||||
ary3(2000);
|
||||
$t = end_test($t, "ary3(2000)");
|
||||
fibo(30);
|
||||
$t = end_test($t, "fibo(30)");
|
||||
hash1(50000);
|
||||
$t = end_test($t, "hash1(50000)");
|
||||
hash2(500);
|
||||
$t = end_test($t, "hash2(500)");
|
||||
heapsort(20000);
|
||||
$t = end_test($t, "heapsort(20000)");
|
||||
matrix(20);
|
||||
$t = end_test($t, "matrix(20)");
|
||||
nestedloop(12);
|
||||
$t = end_test($t, "nestedloop(12)");
|
||||
sieve(30);
|
||||
$t = end_test($t, "sieve(30)");
|
||||
strcat(200000);
|
||||
$t = end_test($t, "strcat(200000)");
|
||||
total($t0, "Total");
|
||||
?>
|
||||
+1
-1
@@ -33,7 +33,7 @@ $(makefile_in_files): $(makefile_am_files)
|
||||
aclocal.m4: configure.in acinclude.m4
|
||||
aclocal
|
||||
|
||||
$(config_h_in): configure.in
|
||||
$(config_h_in): configure.in acconfig.h
|
||||
# explicitly remove target since autoheader does not seem to work
|
||||
# correctly otherwise (timestamps are not updated)
|
||||
@rm -f $@
|
||||
|
||||
+1
-103
@@ -7,115 +7,13 @@ AM_CONFIG_HEADER(zend_config.h)
|
||||
AM_SANITY_CHECK
|
||||
AM_MAINTAINER_MODE
|
||||
AC_PROG_CC
|
||||
AM_PROG_LEX
|
||||
AM_PROG_CC_STDC
|
||||
ZEND_VERSION=$VERSION
|
||||
AC_ZEND_C_BIGENDIAN
|
||||
|
||||
AH_TOP([
|
||||
#if defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define ZEND_API __attribute__ ((visibility("default")))
|
||||
# define ZEND_DLEXPORT __attribute__ ((visibility("default")))
|
||||
#else
|
||||
# define ZEND_API
|
||||
# define ZEND_DLEXPORT
|
||||
#endif
|
||||
|
||||
#define ZEND_DLIMPORT
|
||||
|
||||
#undef uint
|
||||
#undef ulong
|
||||
|
||||
/* Define if you want to enable memory limit support */
|
||||
#define MEMORY_LIMIT 0
|
||||
])
|
||||
|
||||
AH_BOTTOM([
|
||||
#ifndef ZEND_ACCONFIG_H_NO_C_PROTOS
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IEEEFP_H
|
||||
# include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#if ZEND_BROKEN_SPRINTF
|
||||
int zend_sprintf(char *buffer, const char *format, ...);
|
||||
#else
|
||||
# define zend_sprintf sprintf
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* To enable the is_nan, is_infinite and is_finite PHP functions */
|
||||
#ifdef NETWARE
|
||||
#define HAVE_ISNAN 1
|
||||
#define HAVE_ISINF 1
|
||||
#define HAVE_ISFINITE 1
|
||||
#endif
|
||||
|
||||
#ifndef zend_isnan
|
||||
#ifdef HAVE_ISNAN
|
||||
#define zend_isnan(a) isnan(a)
|
||||
#elif defined(HAVE_FPCLASS)
|
||||
#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN))
|
||||
#else
|
||||
#define zend_isnan(a) 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ISINF
|
||||
#define zend_isinf(a) isinf(a)
|
||||
#elif defined(INFINITY)
|
||||
/* Might not work, but is required by ISO C99 */
|
||||
#define zend_isinf(a) (((a)==INFINITY)?1:0)
|
||||
#elif defined(HAVE_FPCLASS)
|
||||
#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF))
|
||||
#else
|
||||
#define zend_isinf(a) 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FINITE
|
||||
#define zend_finite(a) finite(a)
|
||||
#elif defined(HAVE_ISFINITE) || defined(isfinite)
|
||||
#define zend_finite(a) isfinite(a)
|
||||
#elif defined(fpclassify)
|
||||
#define zend_finite(a) ((fpclassify((a))!=FP_INFINITE&&fpclassify((a))!=FP_NAN)?1:0)
|
||||
#else
|
||||
#define zend_finite(a) (zend_isnan(a) ? 0 : zend_isinf(a) ? 0 : 1)
|
||||
#endif
|
||||
|
||||
#endif /* ifndef ZEND_ACCONFIG_H_NO_C_PROTOS */
|
||||
|
||||
#ifdef NETWARE
|
||||
#ifdef USE_WINSOCK
|
||||
#/*This detection against winsock is of no use*/ undef HAVE_SOCKLEN_T
|
||||
#/*This detection against winsock is of no use*/ undef HAVE_SYS_SOCKET_H
|
||||
#endif
|
||||
#endif
|
||||
])
|
||||
|
||||
dnl We want this one before the checks, so the checks can modify CFLAGS.
|
||||
test -z "$CFLAGS" && auto_cflags=1
|
||||
|
||||
AC_CHECK_SIZEOF(long, 8)
|
||||
AC_CHECK_SIZEOF(int, 4)
|
||||
|
||||
sinclude(Zend.m4)
|
||||
|
||||
LIBZEND_BASIC_CHECKS
|
||||
|
||||
+1648
File diff suppressed because it is too large.
Load diff
-19
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.zend.com/license/2_00.txt. |
|
||||
| If you did not receive a copy of the Zend license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@zend.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -1,358 +0,0 @@
|
||||
<?php
|
||||
|
||||
function hallo() {
|
||||
}
|
||||
|
||||
function simpleucall($n) {
|
||||
for ($i = 0; $i < $n; $i++)
|
||||
hallo();
|
||||
}
|
||||
|
||||
function simpleudcall($n) {
|
||||
for ($i = 0; $i < $n; $i++)
|
||||
hallo2();
|
||||
}
|
||||
|
||||
function hallo2() {
|
||||
}
|
||||
|
||||
function simpleicall($n) {
|
||||
for ($i = 0; $i < $n; $i++)
|
||||
func_num_args();
|
||||
}
|
||||
|
||||
class Foo {
|
||||
static $a = 0;
|
||||
public $b = 0;
|
||||
const TEST = 0;
|
||||
|
||||
static function read_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = self::$a;
|
||||
}
|
||||
}
|
||||
|
||||
static function write_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
self::$a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static function isset_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = isset(self::$a);
|
||||
}
|
||||
}
|
||||
|
||||
static function empty_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = empty(self::$a);
|
||||
}
|
||||
}
|
||||
|
||||
static function f() {
|
||||
}
|
||||
|
||||
static function call_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
self::f();
|
||||
}
|
||||
}
|
||||
|
||||
function read_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $this->b;
|
||||
}
|
||||
}
|
||||
|
||||
function write_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$this->b = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function assign_add_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$this->b += 2;
|
||||
}
|
||||
}
|
||||
|
||||
function pre_inc_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
++$this->b;
|
||||
}
|
||||
}
|
||||
|
||||
function pre_dec_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
--$this->b;
|
||||
}
|
||||
}
|
||||
|
||||
function post_inc_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$this->b++;
|
||||
}
|
||||
}
|
||||
|
||||
function post_dec_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$this->b--;
|
||||
}
|
||||
}
|
||||
|
||||
function isset_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = isset($this->b);
|
||||
}
|
||||
}
|
||||
|
||||
function empty_prop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = empty($this->b);
|
||||
}
|
||||
}
|
||||
|
||||
function g() {
|
||||
}
|
||||
|
||||
function call($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$this->g();
|
||||
}
|
||||
}
|
||||
|
||||
function read_const($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $this::TEST;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function read_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = Foo::$a;
|
||||
}
|
||||
}
|
||||
|
||||
function write_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
Foo::$a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function isset_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = isset(Foo::$a);
|
||||
}
|
||||
}
|
||||
|
||||
function empty_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = empty(Foo::$a);
|
||||
}
|
||||
}
|
||||
|
||||
function call_static($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
Foo::f();
|
||||
}
|
||||
}
|
||||
|
||||
function create_object($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = new Foo();
|
||||
}
|
||||
}
|
||||
|
||||
define('TEST', null);
|
||||
|
||||
function read_const($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = TEST;
|
||||
}
|
||||
}
|
||||
|
||||
function read_auto_global($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $_GET;
|
||||
}
|
||||
}
|
||||
|
||||
$g_var = 0;
|
||||
|
||||
function read_global_var($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $GLOBALS['g_var'];
|
||||
}
|
||||
}
|
||||
|
||||
function read_hash($n) {
|
||||
$hash = array('test' => 0);
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $hash['test'];
|
||||
}
|
||||
}
|
||||
|
||||
function read_str_offset($n) {
|
||||
$str = "test";
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $str[1];
|
||||
}
|
||||
}
|
||||
|
||||
function issetor($n) {
|
||||
$val = array(0,1,2,3,4,5,6,7,8,9);
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $val ?: null;
|
||||
}
|
||||
}
|
||||
|
||||
function issetor2($n) {
|
||||
$f = false; $j = 0;
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $f ?: $j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
function ternary($n) {
|
||||
$val = array(0,1,2,3,4,5,6,7,8,9);
|
||||
$f = false;
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $f ? null : $val;
|
||||
}
|
||||
}
|
||||
|
||||
function ternary2($n) {
|
||||
$f = false; $j = 0;
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
$x = $f ? $f : $j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*****/
|
||||
|
||||
function empty_loop($n) {
|
||||
for ($i = 0; $i < $n; ++$i) {
|
||||
}
|
||||
}
|
||||
|
||||
function getmicrotime()
|
||||
{
|
||||
$t = gettimeofday();
|
||||
return ($t['sec'] + $t['usec'] / 1000000);
|
||||
}
|
||||
|
||||
function start_test()
|
||||
{
|
||||
ob_start();
|
||||
return getmicrotime();
|
||||
}
|
||||
|
||||
function end_test($start, $name, $overhead = null)
|
||||
{
|
||||
global $total;
|
||||
global $last_time;
|
||||
$end = getmicrotime();
|
||||
ob_end_clean();
|
||||
$last_time = $end-$start;
|
||||
$total += $last_time;
|
||||
$num = number_format($last_time,3);
|
||||
$pad = str_repeat(" ", 24-strlen($name)-strlen($num));
|
||||
if (is_null($overhead)) {
|
||||
echo $name.$pad.$num."\n";
|
||||
} else {
|
||||
$num2 = number_format($last_time - $overhead,3);
|
||||
echo $name.$pad.$num." ".$num2."\n";
|
||||
}
|
||||
ob_start();
|
||||
return getmicrotime();
|
||||
}
|
||||
|
||||
function total()
|
||||
{
|
||||
global $total;
|
||||
$pad = str_repeat("-", 24);
|
||||
echo $pad."\n";
|
||||
$num = number_format($total,3);
|
||||
$pad = str_repeat(" ", 24-strlen("Total")-strlen($num));
|
||||
echo "Total".$pad.$num."\n";
|
||||
}
|
||||
|
||||
const N = 5000000;
|
||||
|
||||
$t0 = $t = start_test();
|
||||
empty_loop(N);
|
||||
$t = end_test($t, 'empty_loop');
|
||||
$overhead = $last_time;
|
||||
simpleucall(N);
|
||||
$t = end_test($t, 'func()', $overhead);
|
||||
simpleudcall(N);
|
||||
$t = end_test($t, 'undef_func()', $overhead);
|
||||
simpleicall(N);
|
||||
$t = end_test($t, 'int_func()', $overhead);
|
||||
Foo::read_static(N);
|
||||
$t = end_test($t, '$x = self::$x', $overhead);
|
||||
Foo::write_static(N);
|
||||
$t = end_test($t, 'self::$x = 0', $overhead);
|
||||
Foo::isset_static(N);
|
||||
$t = end_test($t, 'isset(self::$x)', $overhead);
|
||||
Foo::empty_static(N);
|
||||
$t = end_test($t, 'empty(self::$x)', $overhead);
|
||||
read_static(N);
|
||||
$t = end_test($t, '$x = Foo::$x', $overhead);
|
||||
write_static(N);
|
||||
$t = end_test($t, 'Foo::$x = 0', $overhead);
|
||||
isset_static(N);
|
||||
$t = end_test($t, 'isset(Foo::$x)', $overhead);
|
||||
empty_static(N);
|
||||
$t = end_test($t, 'empty(Foo::$x)', $overhead);
|
||||
Foo::call_static(N);
|
||||
$t = end_test($t, 'self::f()', $overhead);
|
||||
call_static(N);
|
||||
$t = end_test($t, 'Foo::f()', $overhead);
|
||||
$x = new Foo();
|
||||
$x->read_prop(N);
|
||||
$t = end_test($t, '$x = $this->x', $overhead);
|
||||
$x->write_prop(N);
|
||||
$t = end_test($t, '$this->x = 0', $overhead);
|
||||
$x->assign_add_prop(N);
|
||||
$t = end_test($t, '$this->x += 2', $overhead);
|
||||
$x->pre_inc_prop(N);
|
||||
$t = end_test($t, '++$this->x', $overhead);
|
||||
$x->pre_dec_prop(N);
|
||||
$t = end_test($t, '--$this->x', $overhead);
|
||||
$x->post_inc_prop(N);
|
||||
$t = end_test($t, '$this->x++', $overhead);
|
||||
$x->post_dec_prop(N);
|
||||
$t = end_test($t, '$this->x--', $overhead);
|
||||
$x->isset_prop(N);
|
||||
$t = end_test($t, 'isset($this->x)', $overhead);
|
||||
$x->empty_prop(N);
|
||||
$t = end_test($t, 'empty($this->x)', $overhead);
|
||||
$x->call(N);
|
||||
$t = end_test($t, '$this->f()', $overhead);
|
||||
$x->read_const(N);
|
||||
$t = end_test($t, '$x = Foo::TEST', $overhead);
|
||||
create_object(N);
|
||||
$t = end_test($t, 'new Foo()', $overhead);
|
||||
read_const(N);
|
||||
$t = end_test($t, '$x = TEST', $overhead);
|
||||
read_auto_global(N);
|
||||
$t = end_test($t, '$x = $_GET', $overhead);
|
||||
read_global_var(N);
|
||||
$t = end_test($t, '$x = $GLOBALS[\'v\']', $overhead);
|
||||
read_hash(N);
|
||||
$t = end_test($t, '$x = $hash[\'v\']', $overhead);
|
||||
read_str_offset(N);
|
||||
$t = end_test($t, '$x = $str[0]', $overhead);
|
||||
issetor(N);
|
||||
$t = end_test($t, '$x = $a ?: null', $overhead);
|
||||
issetor2(N);
|
||||
$t = end_test($t, '$x = $f ?: tmp', $overhead);
|
||||
ternary(N);
|
||||
$t = end_test($t, '$x = $f ? $f : $a', $overhead);
|
||||
ternary2(N);
|
||||
$t = end_test($t, '$x = $f ? $f : tmp', $overhead);
|
||||
total($t0, "Total");
|
||||
@@ -1,54 +0,0 @@
|
||||
--TEST--
|
||||
func_num_args() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function test1() {
|
||||
var_dump(func_num_args());
|
||||
}
|
||||
|
||||
function test2($a) {
|
||||
var_dump(func_num_args());
|
||||
}
|
||||
|
||||
function test3($a, $b) {
|
||||
var_dump(func_num_args());
|
||||
}
|
||||
|
||||
test1();
|
||||
test2(1);
|
||||
test2();
|
||||
test3(1,2);
|
||||
|
||||
call_user_func("test1");
|
||||
call_user_func("test3", 1);
|
||||
call_user_func("test3", 1, 2);
|
||||
|
||||
class test {
|
||||
static function test1($a) {
|
||||
var_dump(func_num_args());
|
||||
}
|
||||
}
|
||||
|
||||
test::test1(1);
|
||||
var_dump(func_num_args());
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
int(0)
|
||||
int(1)
|
||||
|
||||
Warning: Missing argument 1 for test2(), called in %s on line %d
|
||||
int(0)
|
||||
int(2)
|
||||
int(0)
|
||||
|
||||
Warning: Missing argument 2 for test3() in %s on line %d
|
||||
int(1)
|
||||
int(2)
|
||||
int(1)
|
||||
|
||||
Warning: func_num_args(): Called from the global scope - no function context in %s on line %d
|
||||
int(-1)
|
||||
Done
|
||||
@@ -1,108 +0,0 @@
|
||||
--TEST--
|
||||
func_get_arg() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function test1() {
|
||||
var_dump(func_get_arg(-10));
|
||||
var_dump(func_get_arg(0));
|
||||
var_dump(func_get_arg(1));
|
||||
}
|
||||
|
||||
function test2($a) {
|
||||
var_dump(func_get_arg(0));
|
||||
var_dump(func_get_arg(1));
|
||||
}
|
||||
|
||||
function test3($a, $b) {
|
||||
var_dump(func_get_arg(0));
|
||||
var_dump(func_get_arg(1));
|
||||
var_dump(func_get_arg(2));
|
||||
}
|
||||
|
||||
test1();
|
||||
test1(10);
|
||||
test2(1);
|
||||
test2();
|
||||
test3(1,2);
|
||||
|
||||
call_user_func("test1");
|
||||
call_user_func("test3", 1);
|
||||
call_user_func("test3", 1, 2);
|
||||
|
||||
class test {
|
||||
static function test1($a) {
|
||||
var_dump(func_get_arg(0));
|
||||
var_dump(func_get_arg(1));
|
||||
}
|
||||
}
|
||||
|
||||
test::test1(1);
|
||||
var_dump(func_get_arg(1));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: func_get_arg(): The argument number should be >= 0 in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: func_get_arg(): Argument 0 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: func_get_arg(): The argument number should be >= 0 in %s on line %d
|
||||
bool(false)
|
||||
int(10)
|
||||
|
||||
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
int(1)
|
||||
|
||||
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: Missing argument 1 for test2(), called in %s on line %d and defined in %s on line %d
|
||||
|
||||
Warning: func_get_arg(): Argument 0 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
int(1)
|
||||
int(2)
|
||||
|
||||
Warning: func_get_arg(): Argument 2 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: func_get_arg(): The argument number should be >= 0 in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: func_get_arg(): Argument 0 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: Missing argument 2 for test3() in %s on line %d
|
||||
int(1)
|
||||
|
||||
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: func_get_arg(): Argument 2 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
int(1)
|
||||
int(2)
|
||||
|
||||
Warning: func_get_arg(): Argument 2 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
int(1)
|
||||
|
||||
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: func_get_arg(): Called from the global scope - no function context in %s on line %d
|
||||
bool(false)
|
||||
Done
|
||||
@@ -1,81 +0,0 @@
|
||||
--TEST--
|
||||
func_get_args() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function test1() {
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
|
||||
function test2($a) {
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
|
||||
function test3($a, $b) {
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
|
||||
test1();
|
||||
test1(10);
|
||||
test2(1);
|
||||
test2();
|
||||
test3(1,2);
|
||||
|
||||
call_user_func("test1");
|
||||
call_user_func("test3", 1);
|
||||
call_user_func("test3", 1, 2);
|
||||
|
||||
class test {
|
||||
static function test1($a) {
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
}
|
||||
|
||||
test::test1(1);
|
||||
var_dump(func_get_args());
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(0) {
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(10)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
|
||||
Warning: Missing argument 1 for test2(), called in %s on line %d and defined in %s on line %d
|
||||
array(0) {
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[1]=>
|
||||
int(2)
|
||||
}
|
||||
array(0) {
|
||||
}
|
||||
|
||||
Warning: Missing argument 2 for test3() in %s on line %d
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[1]=>
|
||||
int(2)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
|
||||
Warning: func_get_args(): Called from the global scope - no function context in %s on line %d
|
||||
bool(false)
|
||||
Done
|
||||
@@ -1,25 +0,0 @@
|
||||
--TEST--
|
||||
strncmp() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(strncmp("", ""));
|
||||
var_dump(strncmp("", "", 100));
|
||||
var_dump(strncmp("aef", "dfsgbdf", -1));
|
||||
var_dump(strncmp("fghjkl", "qwer", 0));
|
||||
var_dump(strncmp("qwerty", "qwerty123", 6));
|
||||
var_dump(strncmp("qwerty", "qwerty123", 7));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: strncmp() expects exactly 3 parameters, 2 given in %s on line %d
|
||||
NULL
|
||||
int(0)
|
||||
|
||||
Warning: Length must be greater than or equal to 0 in %s on line %d
|
||||
bool(false)
|
||||
int(0)
|
||||
int(0)
|
||||
int(-1)
|
||||
Done
|
||||
@@ -1,27 +0,0 @@
|
||||
--TEST--
|
||||
strcasecmp() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(strcasecmp(""));
|
||||
var_dump(strcasecmp("", ""));
|
||||
var_dump(strcasecmp("aef", "dfsgbdf"));
|
||||
var_dump(strcasecmp("qwe", "qwer"));
|
||||
var_dump(strcasecmp("qwerty", "QweRty"));
|
||||
var_dump(strcasecmp("qwErtY", "qwerty"));
|
||||
var_dump(strcasecmp("q123", "Q123"));
|
||||
var_dump(strcasecmp("01", "01"));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: strcasecmp() expects exactly 2 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
int(0)
|
||||
int(-3)
|
||||
int(-1)
|
||||
int(0)
|
||||
int(0)
|
||||
int(0)
|
||||
int(0)
|
||||
Done
|
||||
@@ -1,31 +0,0 @@
|
||||
--TEST--
|
||||
strncasecmp() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(strncasecmp(""));
|
||||
var_dump(strncasecmp("", "", -1));
|
||||
var_dump(strncasecmp("aef", "dfsgbdf", 0));
|
||||
var_dump(strncasecmp("aef", "dfsgbdf", 10));
|
||||
var_dump(strncasecmp("qwe", "qwer", 3));
|
||||
var_dump(strncasecmp("qwerty", "QweRty", 6));
|
||||
var_dump(strncasecmp("qwErtY", "qwer", 7));
|
||||
var_dump(strncasecmp("q123", "Q123", 3));
|
||||
var_dump(strncasecmp("01", "01", 1000));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: strncasecmp() expects exactly 3 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: Length must be greater than or equal to 0 in %s on line %d
|
||||
bool(false)
|
||||
int(0)
|
||||
int(-3)
|
||||
int(0)
|
||||
int(0)
|
||||
int(2)
|
||||
int(0)
|
||||
int(0)
|
||||
Done
|
||||
@@ -1,63 +0,0 @@
|
||||
--TEST--
|
||||
each() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(each());
|
||||
$var = 1;
|
||||
var_dump(each($var));
|
||||
$var = "string";
|
||||
var_dump(each($var));
|
||||
$var = array(1,2,3);
|
||||
var_dump(each($var));
|
||||
$var = array("a"=>1,"b"=>2,"c"=>3);
|
||||
var_dump(each($var));
|
||||
|
||||
$a = array(1);
|
||||
$a [] =&$a[0];
|
||||
|
||||
var_dump(each($a));
|
||||
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: each() expects exactly 1 parameter, 0 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: Variable passed to each() is not an array or object in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: Variable passed to each() is not an array or object in %s on line %d
|
||||
NULL
|
||||
array(4) {
|
||||
[1]=>
|
||||
int(1)
|
||||
["value"]=>
|
||||
int(1)
|
||||
[0]=>
|
||||
int(0)
|
||||
["key"]=>
|
||||
int(0)
|
||||
}
|
||||
array(4) {
|
||||
[1]=>
|
||||
int(1)
|
||||
["value"]=>
|
||||
int(1)
|
||||
[0]=>
|
||||
string(1) "a"
|
||||
["key"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
array(4) {
|
||||
[1]=>
|
||||
int(1)
|
||||
["value"]=>
|
||||
int(1)
|
||||
[0]=>
|
||||
int(0)
|
||||
["key"]=>
|
||||
int(0)
|
||||
}
|
||||
Done
|
||||
@@ -1,53 +0,0 @@
|
||||
--TEST--
|
||||
define() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(define());
|
||||
var_dump(define("TRUE"));
|
||||
var_dump(define("TRUE", 1));
|
||||
var_dump(define("TRUE", 1, array(1)));
|
||||
|
||||
var_dump(define(array(1,2,3,4,5), 1));
|
||||
var_dump(define(" ", 1));
|
||||
var_dump(define("[[[", 2));
|
||||
var_dump(define("test const", 3));
|
||||
var_dump(define("test const", 3));
|
||||
var_dump(define("test", array(1)));
|
||||
var_dump(define("test1", new stdclass));
|
||||
|
||||
var_dump(constant(" "));
|
||||
var_dump(constant("[[["));
|
||||
var_dump(constant("test const"));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: define() expects at least 2 parameters, 0 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: define() expects at least 2 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
bool(true)
|
||||
|
||||
Warning: define() expects parameter 3 to be boolean, array given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: define() expects parameter 1 to be string, array given in %s on line %d
|
||||
NULL
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
|
||||
Notice: Constant test const already defined in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: Constants may only evaluate to scalar values in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: Constants may only evaluate to scalar values in %s on line %d
|
||||
bool(false)
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
||||
Done
|
||||
@@ -1,48 +0,0 @@
|
||||
--TEST--
|
||||
get_class() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class foo {
|
||||
function bar () {
|
||||
var_dump(get_class());
|
||||
}
|
||||
}
|
||||
|
||||
class foo2 extends foo {
|
||||
}
|
||||
|
||||
foo::bar();
|
||||
foo2::bar();
|
||||
|
||||
$f1 = new foo;
|
||||
$f2 = new foo2;
|
||||
|
||||
$f1->bar();
|
||||
$f2->bar();
|
||||
|
||||
var_dump(get_class());
|
||||
var_dump(get_class("qwerty"));
|
||||
|
||||
var_dump(get_class($f1));
|
||||
var_dump(get_class($f2));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Strict Standards: Non-static method foo::bar() should not be called statically in %s on line %d
|
||||
string(3) "foo"
|
||||
|
||||
Strict Standards: Non-static method foo::bar() should not be called statically in %s on line %d
|
||||
string(3) "foo"
|
||||
string(3) "foo"
|
||||
string(3) "foo"
|
||||
|
||||
Warning: get_class() called without object from outside a class in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: get_class() expects parameter 1 to be object, string given in %s on line %d
|
||||
bool(false)
|
||||
string(3) "foo"
|
||||
string(4) "foo2"
|
||||
Done
|
||||
@@ -1,59 +0,0 @@
|
||||
--TEST--
|
||||
get_parent_class() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
interface i {
|
||||
function test();
|
||||
}
|
||||
|
||||
class foo implements i {
|
||||
function test() {
|
||||
var_dump(get_parent_class());
|
||||
}
|
||||
}
|
||||
|
||||
class bar extends foo {
|
||||
function test_bar() {
|
||||
var_dump(get_parent_class());
|
||||
}
|
||||
}
|
||||
|
||||
$bar = new bar;
|
||||
$foo = new foo;
|
||||
|
||||
$foo->test();
|
||||
$bar->test();
|
||||
$bar->test_bar();
|
||||
|
||||
var_dump(get_parent_class($bar));
|
||||
var_dump(get_parent_class($foo));
|
||||
var_dump(get_parent_class("bar"));
|
||||
var_dump(get_parent_class("foo"));
|
||||
var_dump(get_parent_class("i"));
|
||||
|
||||
var_dump(get_parent_class(""));
|
||||
var_dump(get_parent_class("[[[["));
|
||||
var_dump(get_parent_class(" "));
|
||||
var_dump(get_parent_class(new stdclass));
|
||||
var_dump(get_parent_class(array()));
|
||||
var_dump(get_parent_class(1));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
bool(false)
|
||||
string(3) "foo"
|
||||
string(3) "foo"
|
||||
bool(false)
|
||||
string(3) "foo"
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
Done
|
||||
@@ -1,89 +0,0 @@
|
||||
--TEST--
|
||||
property_exists() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class foo {
|
||||
public $pp1 = 1;
|
||||
private $pp2 = 2;
|
||||
protected $pp3 = 3;
|
||||
|
||||
function bar() {
|
||||
var_dump(property_exists("foo","pp1"));
|
||||
var_dump(property_exists("foo","pp2"));
|
||||
var_dump(property_exists("foo","pp3"));
|
||||
}
|
||||
}
|
||||
|
||||
class bar extends foo {
|
||||
function test() {
|
||||
var_dump(property_exists("foo","pp1"));
|
||||
var_dump(property_exists("foo","pp2"));
|
||||
var_dump(property_exists("foo","pp3"));
|
||||
}
|
||||
}
|
||||
|
||||
var_dump(property_exists());
|
||||
var_dump(property_exists(""));
|
||||
var_dump(property_exists("foo","pp1"));
|
||||
var_dump(property_exists("foo","pp2"));
|
||||
var_dump(property_exists("foo","pp3"));
|
||||
var_dump(property_exists("foo","nonexistent"));
|
||||
var_dump(property_exists("fo","nonexistent"));
|
||||
var_dump(property_exists("foo",""));
|
||||
var_dump(property_exists("","test"));
|
||||
var_dump(property_exists("",""));
|
||||
|
||||
$foo = new foo;
|
||||
|
||||
var_dump(property_exists($foo,"pp1"));
|
||||
var_dump(property_exists($foo,"pp2"));
|
||||
var_dump(property_exists($foo,"pp3"));
|
||||
var_dump(property_exists($foo,"nonexistent"));
|
||||
var_dump(property_exists($foo,""));
|
||||
var_dump(property_exists(array(),"test"));
|
||||
var_dump(property_exists(1,"test"));
|
||||
var_dump(property_exists(true,"test"));
|
||||
|
||||
$foo->bar();
|
||||
|
||||
$bar = new bar;
|
||||
$bar->test();
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: property_exists() expects exactly 2 parameters, 0 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: property_exists() expects exactly 2 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(false)
|
||||
|
||||
Warning: First parameter must either be an object or the name of an existing class in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: First parameter must either be an object or the name of an existing class in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: First parameter must either be an object or the name of an existing class in %s on line %d
|
||||
NULL
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
Done
|
||||
@@ -1,34 +0,0 @@
|
||||
--TEST--
|
||||
class_exists() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class foo {
|
||||
}
|
||||
|
||||
var_dump(class_exists());
|
||||
var_dump(class_exists("qwerty"));
|
||||
var_dump(class_exists(""));
|
||||
var_dump(class_exists(array()));
|
||||
var_dump(class_exists("test", false));
|
||||
var_dump(class_exists("foo", false));
|
||||
var_dump(class_exists("foo"));
|
||||
var_dump(class_exists("stdClass", false));
|
||||
var_dump(class_exists("stdClass"));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: class_exists() expects at least 1 parameter, 0 given in %s on line %d
|
||||
NULL
|
||||
bool(false)
|
||||
bool(false)
|
||||
|
||||
Warning: class_exists() expects parameter 1 to be string, array given in %s on line %d
|
||||
NULL
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
Done
|
||||
@@ -1,34 +0,0 @@
|
||||
--TEST--
|
||||
interface_exists() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
interface foo {
|
||||
}
|
||||
|
||||
var_dump(interface_exists());
|
||||
var_dump(interface_exists("qwerty"));
|
||||
var_dump(interface_exists(""));
|
||||
var_dump(interface_exists(array()));
|
||||
var_dump(interface_exists("test", false));
|
||||
var_dump(interface_exists("foo", false));
|
||||
var_dump(interface_exists("foo"));
|
||||
var_dump(interface_exists("stdClass", false));
|
||||
var_dump(interface_exists("stdClass"));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: interface_exists() expects at least 1 parameter, 0 given in %s on line %d
|
||||
NULL
|
||||
bool(false)
|
||||
bool(false)
|
||||
|
||||
Warning: interface_exists() expects parameter 1 to be string, array given in %s on line %d
|
||||
NULL
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(false)
|
||||
Done
|
||||
@@ -1,3 +0,0 @@
|
||||
<?php
|
||||
/* dummy file for 014.phpt */
|
||||
?>
|
||||
@@ -1,52 +0,0 @@
|
||||
--TEST--
|
||||
get_included_files() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(get_included_files());
|
||||
|
||||
include(dirname(__FILE__)."/014.inc");
|
||||
var_dump(get_included_files());
|
||||
|
||||
var_dump(get_included_files(1,1));
|
||||
|
||||
include_once(dirname(__FILE__)."/014.inc");
|
||||
var_dump(get_included_files());
|
||||
|
||||
var_dump(get_included_files(1));
|
||||
|
||||
include(dirname(__FILE__)."/014.inc");
|
||||
var_dump(get_included_files());
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(%d) "%s"
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(%d) "%s"
|
||||
[1]=>
|
||||
string(%d) "%s"
|
||||
}
|
||||
|
||||
Warning: get_included_files() expects exactly 0 parameters, 2 given in %s on line %d
|
||||
NULL
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(%d) "%s"
|
||||
[1]=>
|
||||
string(%d) "%s"
|
||||
}
|
||||
|
||||
Warning: get_included_files() expects exactly 0 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(%d) "%s"
|
||||
[1]=>
|
||||
string(%d) "%s"
|
||||
}
|
||||
Done
|
||||
@@ -1,37 +0,0 @@
|
||||
--TEST--
|
||||
trigger_error() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(trigger_error());
|
||||
var_dump(trigger_error("error"));
|
||||
var_dump(trigger_error(array()));
|
||||
var_dump(trigger_error("error", -1));
|
||||
var_dump(trigger_error("error", 0));
|
||||
var_dump(trigger_error("error", E_USER_WARNING));
|
||||
var_dump(trigger_error("error", E_USER_DEPRECATED));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: trigger_error() expects at least 1 parameter, 0 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Notice: error in %s on line %d
|
||||
bool(true)
|
||||
|
||||
Warning: trigger_error() expects parameter 1 to be string, array given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: Invalid error type specified in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: Invalid error type specified in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: error in %s on line %d
|
||||
bool(true)
|
||||
|
||||
Deprecated: error in %s on line %d
|
||||
bool(true)
|
||||
Done
|
||||
@@ -1,12 +0,0 @@
|
||||
--TEST--
|
||||
isset() with object properties when operating on non-object
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$foo = NULL;
|
||||
isset($foo->bar->bar);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
||||
@@ -1,86 +0,0 @@
|
||||
--TEST--
|
||||
builtin functions tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(get_resource_type());
|
||||
var_dump(get_resource_type(""));
|
||||
$fp = fopen(__FILE__, "r");
|
||||
var_dump(get_resource_type($fp));
|
||||
fclose($fp);
|
||||
var_dump(get_resource_type($fp));
|
||||
|
||||
var_dump(gettype(get_loaded_extensions()));
|
||||
var_dump(count(get_loaded_extensions()));
|
||||
var_dump(gettype(get_loaded_extensions(true)));
|
||||
var_dump(count(get_loaded_extensions(true)));
|
||||
var_dump(get_loaded_extensions(true, true));
|
||||
|
||||
define("USER_CONSTANT", "test");
|
||||
|
||||
var_dump(get_defined_constants(true, true));
|
||||
var_dump(gettype(get_defined_constants(true)));
|
||||
var_dump(gettype(get_defined_constants()));
|
||||
var_dump(count(get_defined_constants()));
|
||||
|
||||
function test () {
|
||||
}
|
||||
|
||||
var_dump(get_defined_functions(true));
|
||||
var_dump(gettype(get_defined_functions()));
|
||||
var_dump(count(get_defined_functions()));
|
||||
|
||||
var_dump(get_declared_interfaces(true));
|
||||
var_dump(gettype(get_declared_interfaces()));
|
||||
var_dump(count(get_declared_interfaces()));
|
||||
|
||||
var_dump(get_extension_funcs());
|
||||
var_dump(get_extension_funcs(true));
|
||||
var_dump(gettype(get_extension_funcs("standard")));
|
||||
var_dump(count(get_extension_funcs("standard")));
|
||||
var_dump(gettype(get_extension_funcs("zend")));
|
||||
var_dump(count(get_extension_funcs("zend")));
|
||||
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: get_resource_type() expects exactly 1 parameter, 0 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: get_resource_type() expects parameter 1 to be resource, string given in %s on line %d
|
||||
NULL
|
||||
string(6) "stream"
|
||||
string(7) "Unknown"
|
||||
string(5) "array"
|
||||
int(%d)
|
||||
string(5) "array"
|
||||
int(%d)
|
||||
|
||||
Warning: get_loaded_extensions() expects at most 1 parameter, 2 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: get_defined_constants() expects at most 1 parameter, 2 given in %s on line %d
|
||||
NULL
|
||||
string(5) "array"
|
||||
string(5) "array"
|
||||
int(%d)
|
||||
|
||||
Warning: get_defined_functions() expects exactly 0 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
string(5) "array"
|
||||
int(%d)
|
||||
|
||||
Warning: get_declared_interfaces() expects exactly 0 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
string(5) "array"
|
||||
int(%d)
|
||||
|
||||
Warning: get_extension_funcs() expects exactly 1 parameter, 0 given in %s on line %d
|
||||
NULL
|
||||
bool(false)
|
||||
string(5) "array"
|
||||
int(%d)
|
||||
string(5) "array"
|
||||
int(%d)
|
||||
Done
|
||||
@@ -1,34 +0,0 @@
|
||||
--TEST--
|
||||
constant() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(constant());
|
||||
var_dump(constant("", ""));
|
||||
var_dump(constant(""));
|
||||
|
||||
var_dump(constant(array()));
|
||||
|
||||
define("TEST_CONST", 1);
|
||||
var_dump(constant("TEST_CONST"));
|
||||
|
||||
define("TEST_CONST2", "test");
|
||||
var_dump(constant("TEST_CONST2"));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: constant() expects exactly 1 parameter, 0 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: constant() expects exactly 1 parameter, 2 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: constant(): Couldn't find constant in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: constant() expects parameter 1 to be string, array given in %s on line %d
|
||||
NULL
|
||||
int(1)
|
||||
string(4) "test"
|
||||
Done
|
||||
-1333
File diff suppressed because it is too large.
Load diff
Loaded 100 of 15730 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user