Compare commits

..
1 Commits
Author SHA1 Message Date
SVN Migration 2ccef75a19 This commit was manufactured by cvs2svn to create tag 'dev'. 2002-08-06 16:36:06 +00:00
21138 changed files with 439883 additions and 4032463 deletions

No files matched your search

-51
View File
@@ -1,51 +0,0 @@
version: "{branch}.build.{build}"
image: Visual Studio 2017
branches:
except:
- PHP-5.6
- PHP-7.0
clone_depth: 64
cache:
- c:\build-cache
environment:
PHP_BUILD_CACHE_BASE_DIR: c:\build-cache
PHP_BUILD_OBJ_DIR: c:\obj
PHP_BUILD_CACHE_SDK_DIR: c:\build-cache\sdk
PHP_BUILD_SDK_BRANCH: php-sdk-2.2.0
PHP_BUILD_CRT: vc15
# ext and env setup for tests
#MYSQL_TEST_PASSWD: Password12!
#MYSQL_TEST_USER: root
#PDO_MYSQL_TEST_DSN: "pgsql:host=127.0.0.1 port=5432 dbname=test user=root password=Password12!"
#PDO_MYSQL_TEST_USER: root
#PDO_MYSQL_TEST_PASS: Password12!
#PGSQL_TEST_CONNSTR: "host=127.0.0.1 dbname=test port=5432 user=postgres password=Password12!"
#PDO_PGSQL_TEST_DSN: "pgsql:host=127.0.0.1 port=5432 dbname=test user=postgres password=Password12!"
#build permutations
matrix:
- THREAD_SAFE: 0
OPCACHE: 0
- THREAD_SAFE: 1
OPCACHE: 1
INTRINSICS: AVX
services:
# the setup scripts have to be touched, once some other db version is used
- mysql
- postgresql101
- mssql2017
platform:
- x64
# - x86
build_script:
- appveyor\build.bat
test_script:
- appveyor\test.bat
-34
View File
@@ -1,34 +0,0 @@
# https://editorconfig.org/
root = true
[*]
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
charset = utf-8
tab_width = 4
[{*.{awk,bat,c,cpp,d,h,l,mk,re,skl,w32,y},Makefile*}]
indent_size = 4
indent_style = tab
[*.{dtd,html,inc,php,phpt,rng,wsdl,xml,xsd,xsl}]
indent_size = 4
indent_style = space
[*.{ac,m4,sh,yml}]
indent_size = 2
indent_style = space
[*.md]
indent_style = space
max_line_length = 80
[COMMIT_EDITMSG]
indent_size = 4
indent_style = space
max_line_length = 80
[*.patch]
trim_trailing_whitespace = false
-647
View File
@@ -1,647 +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])
set $eg_ptr = $eg
else
set $eg = executor_globals
set $cg = compiler_globals
set $eg_ptr = (zend_executor_globals*) &executor_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
if $argc == 0
____executor_globals
set $cv_ex_ptr = $eg.current_execute_data
else
set $cv_ex_ptr = (zend_execute_data *)$arg0
end
set $cv_count = $cv_ex_ptr.func.op_array.last_var
set $cv = $cv_ex_ptr.func.op_array.vars
set $cv_idx = 0
set $callFrameSize = (sizeof(zend_execute_data) + sizeof(zval) - 1) / sizeof(zval)
printf "Compiled variables count: %d\n\n", $cv_count
while $cv_idx < $cv_count
printf "[%d] '%s'\n", $cv_idx, $cv[$cv_idx].val
set $zvalue = ((zval *) $cv_ex_ptr) + $callFrameSize + $cv_idx
printzv $zvalue
set $cv_idx = $cv_idx + 1
end
end
document print_cvs
Prints the compiled variables and their values.
If a zend_execute_data pointer is set this will print the compiled
variables of that scope. If no parameter is used it will use
current_execute_data for scope.
usage: print_cvs [zend_execute_data *]
end
define dump_bt
set $ex = $arg0
while $ex
printf "[%p] ", $ex
set $func = $ex->func
if $func
if $ex->This->value.obj
if $func->common.scope
printf "%s->", $func->common.scope->name->val
else
printf "%s->", $ex->This->value.obj->ce.name->val
end
else
if $func->common.scope
printf "%s::", $func->common.scope->name->val
end
end
if $func->common.function_name
printf "%s(", $func->common.function_name->val
else
printf "(main"
end
set $callFrameSize = (sizeof(zend_execute_data) + sizeof(zval) - 1) / sizeof(zval)
set $count = $ex->This.u2.num_args
set $arg = 0
while $arg < $count
if $arg > 0
printf ", "
end
set $zvalue = (zval *) $ex + $callFrameSize + $arg
set $type = $zvalue->u1.v.type
if $type == 1
printf "NULL"
end
if $type == 2
printf "false"
end
if $type == 3
printf "true"
end
if $type == 4
printf "%ld", $zvalue->value.lval
end
if $type == 5
printf "%f", $zvalue->value.dval
end
if $type == 6
____print_str $zvalue->value.str->val $zvalue->value.str->len
end
if $type == 7
printf "array(%d)[%p]", $zvalue->value.arr->nNumOfElements, $zvalue
end
if $type == 8
printf "object[%p]", $zvalue
end
if $type == 9
printf "resource(#%d)", $zvalue->value.lval
end
if $type == 10
printf "reference"
end
if $type > 10
printf "unknown type %d", $type
end
set $arg = $arg + 1
end
printf ") "
else
printf "??? "
end
if $func != 0
if $func->type == 2
printf "%s:%d ", $func->op_array.filename->val, $ex->opline->lineno
else
printf "[internal function]"
end
end
set $ex = $ex->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->u1.v.type
# 15 == IS_INDIRECT
if $type > 5 && $type != 15
printf "(refcount=%d) ", $zvalue->value.counted->gc.refcount
end
if $type == 0
printf "UNDEF"
end
if $type == 1
printf "NULL"
end
if $type == 2
printf "bool: false"
end
if $type == 3
printf "bool: true"
end
if $type == 4
printf "long: %ld", $zvalue->value.lval
end
if $type == 5
printf "double: %f", $zvalue->value.dval
end
if $type == 6
printf "string: %s", $zvalue->value.str->val
end
if $type == 7
printf "array: "
if ! $arg1
set $ind = $ind + 1
____print_ht $zvalue->value.arr 1
set $ind = $ind - 1
set $i = $ind
while $i > 0
printf " "
set $i = $i - 1
end
end
set $type = 0
end
if $type == 8
printf "object"
____executor_globals
set $handle = $zvalue->value.obj.handle
set $handlers = $zvalue->value.obj.handlers
set $zobj = $zvalue->value.obj
set $cname = $zobj->ce->name->val
printf "(%s) #%d", $cname, $handle
if ! $arg1
if $handlers->get_properties == &zend_std_get_properties
if $zobj->properties
set $ht = $zobj->properties
else
set $ht = &$zobj->ce->properties_info
end
printf "\nProperties "
if $ht
set $ind = $ind + 1
____print_ht $ht 1
set $ind = $ind - 1
set $i = $ind
while $i > 0
printf " "
set $i = $i - 1
end
else
echo "not found"
end
end
end
set $type = 0
end
if $type == 9
printf "resource: #%d", $zvalue->value.res->handle
end
if $type == 10
printf "reference: "
____printzv &$zvalue->value.ref->val $arg1
end
if $type == 11
printf "const: %s", $zvalue->value.str->val
end
if $type == 12
printf "CONSTANT_AST"
end
if $type == 13
printf "_BOOL"
end
if $type == 14
printf "CALLABLE"
end
if $type == 15
printf "indirect: "
____printzv $zvalue->value.zv $arg1
end
if $type == 17
printf "pointer: %p", $zvalue->value.ptr
end
if $type == 18
printf "ITERABLE"
end
if $type == 19
printf "VOID"
end
if $type == 20
printf "_ERROR"
end
if $type == 16 || $type > 20
printf "unknown type %d", $type
end
printf "\n"
end
define ____printzv
____executor_globals
set $zvalue = $arg0
printf "[%p] ", $zvalue
set $zcontents = (zval*) $zvalue
if $arg1
____printzv_contents $zcontents $arg1
else
____printzv_contents $zcontents 0
end
end
define print_global_vars
____executor_globals
set $symtable = ((HashTable *)&($eg_ptr->symbol_table))
print_ht $symtable
end
document print_global_vars
Prints the global variables
end
define print_const_table
set $ind = 1
printf "[%p] {\n", $arg0
____print_ht $arg0 4
printf "}\n"
end
document print_const_table
Dumps elements of Constants HashTable
Example: print_const_table executor_globals.zend_constants
end
define ____print_ht
set $ht = (HashTable*)$arg0
set $n = $ind
while $n > 0
printf " "
set $n = $n - 1
end
if $ht->u.v.flags & 4
printf "Packed"
else
printf "Hash"
end
printf "(%d)[%p]: {\n", $ht->nNumOfElements, $ht
set $num = $ht->nNumUsed
set $i = 0
set $ind = $ind + 1
while $i < $num
set $p = (Bucket*)($ht->arData + $i)
set $n = $ind
if $p->val.u1.v.type > 0
while $n > 0
printf " "
set $n = $n - 1
end
printf "[%d] ", $i
if $p->key
printf "%s => ", $p->key->val
else
printf "%d => ", $p->h
end
if $arg1 == 0
printf "%p\n", (zval *)&$p->val
end
if $arg1 == 1
set $zval = (zval *)&$p->val
____printzv $zval 1
end
if $arg1 == 2
printf "%s\n", (char*)$p->val.value.ptr
end
if $arg1 == 3
set $func = (zend_function*)$p->val.value.ptr
printf "\"%s\"\n", $func->common.function_name->val
end
if $arg1 == 4
set $const = (zend_constant *)$p->val.value.ptr
____printzv $const 1
end
end
set $i = $i + 1
end
set $ind = $ind - 1
printf "}\n"
end
define print_ht
set $ind = 0
____print_ht $arg0 1
end
document print_ht
dumps elements of HashTable made of zval
end
define print_htptr
set $ind = 0
____print_ht $arg0 0
end
document print_htptr
dumps elements of HashTable made of pointers
end
define print_htstr
set $ind = 0
____print_ht $arg0 2
end
document print_htstr
dumps elements of HashTable made of strings
end
define print_ft
set $ind = 0
____print_ht $arg0 3
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->val
if $ce->parent != 0
printf " extends %s", $ce->parent->name->val
end
if $ce->num_interfaces != 0
printf " implements"
set $tmp = 0
while $tmp < $ce->num_interfaces
printf " %s", $ce->interfaces[$tmp]->name->val
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->val
if $ce->num_interfaces != 0
set $ce = $ce->interfaces[0]
printf " extends %s", $ce->name->val
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 = (zend_property_info *)$arg0
set $initial_offset = ((uint32_t)(zend_uintptr_t)(&((zend_object*)0)->properties_table[(0)]))
set $ptr_to_val = (zval*)((char*)$pi->ce->default_properties_table + $pi->offset - $initial_offset)
printf "[%p] {\n", $pi
printf " offset = %p\n", $pi->offset
printf " ce = [%p] %s\n", $pi->ce, $pi->ce->name->val
printf " flags = 0x%x (", $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_EARLY_BINDING"
else
if $pi->flags & 0x20000
printf "ZEND_ACC_SHADOW"
end
end
end
end
end
printf ")\n"
printf " name = "
print_zstr $pi->name
printf " default value: "
printzv $ptr_to_val
printf "}\n"
end
document print_pi
Takes a pointer to an object's property and prints the property information
usage: print_pi <ptr>
end
define ____print_str
set $tmp = 0
set $str = $arg0
if $argc > 2
set $maxlen = $arg2
else
set $maxlen = 256
end
printf "\""
while $tmp < $arg1 && $tmp < $maxlen
if $str[$tmp] > 31 && $str[$tmp] < 127
printf "%c", $str[$tmp]
else
printf "\\%o", $str[$tmp]
end
set $tmp = $tmp + 1
end
if $tmp != $arg1
printf "..."
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 print_zstr
set $zstr = (zend_string *)$arg0
if $argc == 2
set $maxlen = $arg1
else
set $maxlen = $zstr->len
end
printf "string(%d) ", $zstr->len
____print_str $zstr->val $zstr->len $maxlen
printf "\n"
end
document print_zstr
print the length and contents of a zend string
usage: print_zstr <ptr> [max length]
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 lookup_root
set $found = 0
if gc_globals->roots
set $current = gc_globals->roots->next
printf "looking ref %p in roots\n", $arg0
while $current != &gc_globals->roots
if $current->ref == $arg0
set $found = $current
break
end
set $current = $current->next
end
if $found != 0
printf "found root %p\n", $found
else
printf "not found\n"
end
end
end
document lookup_root
lookup a refcounted in root
usage: lookup_root [ptr].
end
-159
View File
@@ -1,159 +0,0 @@
ext/mysqlnd/mysqlnd.h ident
ext/ext_skel.php ident
ext/phar/phar/pharcommand.inc 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
run-tests.php ident
NEWS merge=NEWS
UPGRADING merge=NEWS
UPGRADING.INTERNALS merge=NEWS
/ext/bz2/tests/with_strings.phpt -crlf
/ext/dom/tests/bug40836.phpt -crlf
/ext/dom/tests/domelement.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/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
-210
View File
@@ -1,210 +0,0 @@
# General ignores
*~
.#*
*.
*.slo
*.mk
*.mem
*.gcda
*.gcno
*.la
*.lo
*.loT
*.o
*.a
*.ncb
*.opt
*.plg
*swp
*.patch
*.tgz
*.tar.gz
*.tar.bz2
*.tar.xz
*.tar.gz.asc
*.tar.bz2.asc
*.tar.xz.asc
.FBCIndex
.FBCLockFolder
.libs
phpt.*
core
dynlib.m4
Makefile
Makefile.fragments
Makefile.objects
_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.status
config.sub
config_vars.mk
configuration-parser.c
configuration-parser.h
configuration-parser.output
configuration-scanner.c
configure
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
php7.spec
php_lcov.info
php_test_results_*.txt
php_version.h
results.txt
shlibtool
stamp-h
test.php3
tmp-php.ini
stamp-h.in
scan_makefile_in.awk
main/php_config.h
main/php_config.h.in
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/apache2handler/libphp7.module
sapi/cgi/php-cgi
sapi/cgi/php-cgi.1
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
sapi/fpm/php-fpm.8
sapi/fpm/php-fpm.service
sapi/fpm/status.html
sapi/fpm/www.conf
sapi/phpdbg/phpdbg_parser.c
sapi/phpdbg/phpdbg_parser.h
sapi/phpdbg/phpdbg
sapi/phpdbg/phpdbg.1
sapi/phpdbg/build
sapi/phpdbg/*.output
scripts/php-config
scripts/phpize
scripts/man1/*.1
TSRM/tsrm_config.h
win32/*.suo
win32/*.aps
win32/*.positions
win32/ext
win32/phpts.def
win32/wsyslog.h
Zend/zend_config.h
Zend/zend_dtrace_gen.h
Zend/zend_dtrace_gen.hbak
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
# Extension specific ignores
ext/*/configure.ac
ext/*/ltmain.sh
ext/*/libs.mk
ext/*/build
ext/*/scan_makefile_in.awk
ext/*/Makefile.global
ext/*/acinclude.m4
ext/*/config.sub
ext/date/lib/timelib_config.h
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/iconv/php_iconv_broken_ignore.h
ext/iconv/php_iconv_aliased_libiconv.h
ext/mbstring/oniguruma/oniguruma.h
ext/oci8/tests/*.vglog
ext/pdo/conftest*
ext/pdo_firebird/conftest*
ext/pdo_mysql/conftest*
ext/pdo_oci/conftest*
ext/pdo_odbc/tests/*.mdb
ext/pdo_pgsql/conftest*
ext/pdo_sqlite/conftest*
ext/pdo_sqlite/sqlite3.h
ext/phar/phar.phar
ext/phar/phar.1
ext/phar/phar.phar.1
ext/phar/phar.php
ext/reflection/xml
ext/reflection/html
ext/reflection/spl.chm
ext/spl/examples/.htaccess
ext/spl/examples/*.phps
ext/sqlite3/tests/phpsql*
# ------------------------------------------------------------------------------ Windows
# Generated by `/buildconf.bat`
/configure.bat
/configure.js
# Generated by `/configure.(bat|js)` (architecture dependend)
/config.nice.bat
/Debug/
/Debug_TS/
/Release/
/Release_TS/
/x64/
# ------------------------------------------------------------------------------ Tests
# Generated by `/run-tests.php` upon failure
**/tests/**/*.diff
**/tests/**/*.out*
**/tests/**/*.php
**/tests/**/*.exp
**/tests/**/*.log
**/tests/**/*.sh
# Used by some test cases.
**/tests/**/*.db
**/tests/**/*.txt
**/tests/**/*.tmp
# Special cases to invert previous ignore rules
!ext/fileinfo/libmagic.patch
!ext/mbstring/oniguruma.patch
!ext/pcre/pcre2lib/config.h
-74
View File
@@ -1,74 +0,0 @@
git:
quiet: true
dist: trusty
language: c
sudo: required
addons:
apt:
packages:
- locales
- language-pack-de
- re2c
- libgmp-dev
- libicu-dev
- libtidy-dev
- libenchant-dev
- libaspell-dev
- libpspell-dev
- librecode-dev
- libsasl2-dev
- libxpm-dev
- libt1-dev
- libzip-dev
notifications:
email:
on_failure: change
irc:
template:
- "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message} - Change view : %{compare_url} - Build details : %{build_url}"
channels:
- "irc.efnet.org#php.pecl"
on_success: change
on_failure: always
cache:
apt: true
ccache: true
env:
global:
- MYSQL_TEST_HOST=127.0.0.1
- MYSQL_TEST_USER=travis
- PDO_MYSQL_TEST_DSN="mysql:host=127.0.0.1;dbname=test"
- PDO_MYSQL_TEST_USER=travis
- PDO_MYSQL_TEST_PASS=
- PDO_MYSQL_TEST_HOST=127.0.0.1
- REPORT_EXIT_STATUS=1
matrix:
- ENABLE_MAINTAINER_ZTS=0 ENABLE_DEBUG=0
- ENABLE_MAINTAINER_ZTS=1 ENABLE_DEBUG=1
before_script:
- ccache --version
- ccache --zero-stats
- export USE_CCACHE=1
# Enable IPv6
- sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6'
# Compile PHP
- ./travis/compile.sh
# Setup Extensions
- . ./travis/ext/mysql/setup.sh
- . ./travis/ext/mysqli/setup.sh
- . ./travis/ext/pdo_mysql/setup.sh
- . ./travis/ext/pgsql/setup.sh
- . ./travis/ext/pdo_pgsql/setup.sh
# Run PHPs run-tests.php
script:
- ./sapi/cli/php run-tests.php -P -d extension=`pwd`/modules/zend_test.so $(if [ $ENABLE_DEBUG == 0 ]; then echo "-d opcache.enable_cli=1 -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --show-slow 1000 --set-timeout 120
- sapi/cli/php -d extension_dir=`pwd`/modules -r 'dl("zend_test");'
after_success:
- ccache --show-stats
+99 -188
View File
@@ -1,118 +1,110 @@
========================
PHP Coding Standards
========================
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 the version 4 releases, many sections have been recoded to use
these rules.
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 fully
follow it, but new features are going in that general direction. 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
1. Functions that are given pointers to resources should not free them
For instance, ``function int mail(char *to, char *from)`` should NOT free
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
- 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
[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
[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 such
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,
[5] Use php_error() to report any errors/warnings during code execution.
Use descriptive error messages, and try to avoid using identical
error strings for different stages of an error. For example,
if in order to obtain a URL you have to parse the URL, connect,
and retreive the text, assuming something can go wrong at each
of these stages, don't report an error "Unable to get URL"
on all of them, but instead, write something like "Unable
to parse URL", "Unable to connect to URL server" and "Unable
to fetch URL text", respectively.
[6] 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] Use ZEND_* macros instead of PHP_* macros. Use of PHP_* macros is not
recommended. Since most of the PHP_* macros are ZEND_* macro aliases, using
the PHP_* macros makes browsing the source code with a tag search harder.
7. When commenting out code using a #if statement, do NOT use 0 only. Instead
use "<git username here>_0". For example, #if FOO_0, where FOO is your
git user foo. This allows easier tracking of why code was commented out,
especially in bundled libraries.
[8] Use assert(). assert.h is included in php.h if it is available. Not only
does good assertion catch bugs, but it also helps with code readability.
- Do not use assert for error handling. Use assert only for the
condition that must be always true.
- Do not use assignments in assert conditions. If you assign inside an
assert condition, you risk an elusive bug that would be very difficult
to spot in a debug build, due to the side effect of the assignment.
Function calls in assert conditions may also cause this problem, if
they modify one of their arguments or global variables.
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.
User Functions/Methods Naming Conventions
Naming Conventions
------------------
1. Function names for user-level functions should be enclosed with in
[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::
readability of the function name itself.
Good:
'str_word_count'
'array_key_exists'
'mcrypt_enc_self_test'
'mysql_list_fields'
Ok:
'date_interval_create_from_date_string'
(could be 'date_intvl_create_from_date_str'?)
'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'?)
(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
[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_*``::
of parent_*.
A family of 'foo' functions, for example:
Good:
'foo_select_bar'
'foo_insert_baz'
@@ -123,91 +115,23 @@ User Functions/Methods Naming Conventions
'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
[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
[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
[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. Class names should be descriptive nouns in PascalCase and as short as
possible. Each word in the class name should start with a capital letter,
without underscore delimiters. The class name should be prefixed with the
name of the "parent set" (e.g. the name of the extension) if no namespaces
are used. Abbreviations and acronyms as well as initialisms should be
avoided wherever possible, unless they are much more widely used than the
long form (e.g. HTTP or URL). Abbreviations start with a capital letter
followed by lowercase letters, whereas acronyms and initialisms are written
according to their standard notation. Usage of acronyms and initialisms is
not allowed if they are not widely adopted and recognized as such.
Good:
'Curl'
'CurlResponse'
'HTTPStatusCode'
'URL'
'BTreeMap' (B-tree Map)
'Id' (Identifier)
'ID' (Identity Document)
'Char' (Character)
'Intl' (Internationalization)
'Radar' (Radio Detecting and Ranging)
Bad:
'curl'
'curl_response'
'HttpStatusCode'
'Url'
'BtreeMap'
'ID' (Identifier)
'CHAR'
'INTL'
'RADAR' (Radio Detecting and Ranging)
Internal Function Naming Conventions
----------------------
1. Functions that are part of the external API should be named
'php_modulename_function()' to avoid symbol collision. They should be in
lowercase, with words underscore delimited. Exposed API must be defined
in 'php_modulename.h'.
PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS);
Unexposed module function should be static and should not be defined in
'php_modulename.h'.
static int php_session_destroy()
2. Main module source file must be named 'modulename.c'.
3. Header file that is used by other sources must be named 'php_modulename.h'.
Syntax and indentation
----------------------
1. Never use C++ style comments (i.e. // comment). Always use C-style
[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
@@ -216,63 +140,55 @@ Syntax and indentation
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
[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.
syntax.
Indentstyle: http://www.catb.org/~esr/jargon/html/I/indent-style.html
(see also http://www.tuxedo.org/~esr/jargon/html/entry/indent-style.html)
[3] Be generous with whitespace and braces. Always prefer:
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;
}
if (foo) {
bar;
}
to:
to:
if(foo)bar;
if(foo)bar;
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.
4. When indenting, use the tab character. A tab is expected to represent
[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::
function does. It would look like this:
/* {{{ proto int abs(int number)
Returns the absolute value of the number */
PHP_FUNCTION(abs)
{
...
}
/* }}} */
/* {{{ 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
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
@@ -280,10 +196,10 @@ 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::
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 */
/* {{{ 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.
@@ -297,13 +213,9 @@ 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 Git comments.
In general new features should go to PECL or experimental branches until
there are specific reasons for directly adding it to the core distribution.
information:
Any authoring information (known bugs, future directions of the module).
Ongoing status notes which may not be appropriate for CVS comments.
Aliases & Legacy Documentation
-----------------------------------
@@ -317,6 +229,5 @@ 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 the
README in the PHP documentation repository for more information on
documentation.
as the code can be reasonably be kept as part of the codebase. See
/phpdoc/README for more information on documentation.
-78
View File
@@ -1,78 +0,0 @@
# Contributing to PHP
Anybody who programs in PHP can be a contributing member of the community that
develops and deploys it; the task of deploying PHP, documentation and
associated websites is a never ending one. With every release, or release
candidate comes a wave of work, which takes a lot of organization and
co-ordination.
## Pull requests
PHP welcomes pull requests to [add tests](#writing-tests), fix bugs and to
implement RFCs. Please be sure to include tests as appropriate!
If you are fixing a bug, then please submit your PR against the lowest actively
supported branch of PHP that the bug affects (only green branches on
[the supported version page](http://php.net/supported-versions.php) are supported).
For example, at the time of writing in early-2018, the lowest supported version is
PHP 7.1, which corresponds to the `PHP-7.1` branch in Git. Please also make sure you
add a link to the PR in the bug on [the bug tracker](https://bugs.php.net/).
Pull requests implementing RFCs should be submitted against `master`.
Pull requests should *never* be submitted against `PHP-x.y.z` branches, as
these are only used for release management.
If your pull request exhibits conflicts with the base branch, please resolve them
by using `git rebase` instead of `git merge`.
## Filing bugs
Bugs can be filed on the [PHP bug tracker](https://bugs.php.net/). If this is
the first time you've filed a bug, we suggest reading the
[guide to reporting a bug](https://bugs.php.net/how-to-report.php).
Where possible, please include a self-contained reproduction case!
## Feature requests
Feature requests are generally submitted in the form of
[Requests for Comment](https://wiki.php.net/rfc/howto), ideally accompanied by
[pull requests](#pull-requests). You can find the extremely large list of RFCs
that have been previously considered on the
[PHP Wiki](https://wiki.php.net/rfc).
You may want to read
[The Mysterious PHP RFC Process](https://blogs.oracle.com/opal/entry/the_mysterious_php_rfc_process)
for additional notes on the best way to approach submitting an RFC.
## Writing tests
We love getting new tests! PHP is a huge project and improving code coverage is
a huge win for every PHP user.
[Our QA site includes a page detailing how to write test cases.](http://qa.php.net/write-test.php)
Please note that the section on submitting pull requests is outdated: in
addition to the process listed there, you can also
[submit pull requests](#pull-requests).
## Writing documentation
There are two ways to contribute to the PHP manual. You can edit the manual and
send patches anonymously via [the online editor](https://edit.php.net/), or you
can check the XML source out from Subversion and edit that and build it
[per the instructions on the documentation site](http://doc.php.net/tutorial/).
Patches created that way should be sent to the
[documentation mailing list](mailto:phpdoc@lists.php.net).
## Getting help
If you are having trouble contributing to PHP, or just want to talk to a human
about what you're working on, you can contact us via the
[internals mailing list](mailto:internals@lists.php.net), or the
[documentation mailing list](mailto:phpdoc@lists.php.net) for documentation
issues.
Although not a formal channel, you can also find a number of core developers on
the #php.pecl channel on [EFnet](http://www.efnet.org/). Similarly, many
documentation writers can be found on #php.doc.
+1 -2
View File
@@ -1,3 +1,2 @@
For the list of people who've put work into PHP, please see
https://www.php.net/credits.php
http://www.php.net/credits.php
+17796
View File
File diff suppressed because it is too large. Load diff
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+273 -311
View File
@@ -3,6 +3,7 @@
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.
@@ -26,40 +27,61 @@ Status legend
== Server APIs ==
-------------------------------------------------------------------------------
EXTENSION: apache2handler
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>, Ilia Alshanetsky <iliaa@php.net>
EXTENSION: aolserver
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: apache
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: apache2
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>
MAINTENANCE: Maintained
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: cgi
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: cli
MAINTENANCE: Marcus Börger <helly@php.net>, Edin Kadribasic <edink@php.net>
STATUS: Working
SINCE: 4.3.0
EXTENSION: fhttpd
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: embed
PRIMARY MAINTAINER: Edin Kadribasic <edink@php.net>
EXTENSION: isapi
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: nsapi
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: phttpd
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: pi3web
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: roxen
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: servlet
PRIMARY MAINTAINER: Sam Ruby <rubys@us.ibm.com>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: fpm
PRIMARY MAINTAINER: Jakub Zelenka <bukka@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3.3
EXTENSION: thttpd
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: litespeed
PRIMARY MAINTAINER: George Wang <gwang@php.net>
EXTENSION: webjames
PRIMARY MAINTAINER: Alex Waugh <alex@alexwaugh.com>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
-------------------------------------------------------------------------------
EXTENSION: phpdbg
MAINTENANCE: Joe Watkins <krakjoe@php.net>, Bob Weinand <bwoebi@php.net>
STATUS: 5.6
STATUS: Experimental
-------------------------------------------------------------------------------
@@ -67,256 +89,181 @@ STATUS: 5.6
-------------------------------------------------------------------------------
EXTENSION: dba
PRIMARY MAINTAINER: Marcus Börger <helly@php.net> (2002 - 2007)
Christopher Jones <sixd@php.net> (2008 - 2013)
Pierre-Alain Joye <pajoye@php.net> (2011 - 2011)
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
MAINTENANCE: Maintained
STATUS: Working
COMMENT: DBM abstraction for db2, db3, db4, dbm, ndbm, gdbm, ini
-------------------------------------------------------------------------------
EXTENSION: dbase
PRIMARY MAINTAINER: Jim Winstead <jimw@php.net>
MAINTENANCE: Odd Fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: dbx
PRIMARY MAINTAINER: Marc Boeren <M.Boeren@guidance.nl>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.6
COMMENT: DB abstraction for odbc, mysql, pgsql, mssql, fbsql and more, see documentation
-------------------------------------------------------------------------------
EXTENSION: filepro
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: hyperwave
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: informix
PRIMARY MAINTAINER: Danny Heijl <Danny.Heijl@cevi.be>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: ingres_ii
PRIMARY MAINTAINER: David Hénot <henot@php.net>
MAINTENANCE: Maintained
STATUS: Experimental
SINCE: 4.0.2
-------------------------------------------------------------------------------
EXTENSION: interbase
PRIMARY MAINTAINER: Ard Biesheuvel <ard@ard.nu> (2003 - 2005)
MAINTENANCE: Odd fixes
PRIMARY MAINTAINER: Jouni Ahto <jouni.ahto@exdec.fi>
MAINTENANCE: Odd Fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: mysqli
PRIMARY MAINTAINER: Georg Richter <georg@php.net> (2003 - 2006)
Andrey Hristov <andrey@php.net> (2003 - 2016)
Johannes Schlüter <johannes@php.net> (2008 - 2014)
Ulf Wendel <uw@php.net> (2007 - 2013)
EXTENSION: msql
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: msession
PRIMARY MAINTAINER Mark L. Woodward mlwmohawk@mohawksoft.com
MAINTENANCE: Maintained
STATUS: Working/Experimental
COMMENT: Tested on Linux, should work on other UNIX platforms. Backend server code can compile under Windows.
-------------------------------------------------------------------------------
EXTENSION: mssql
PRIMARY MAINTAINER: Frank M. Kromann <fmk@swwwing.com>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.0
COMMENT: Tested on phpts and isapi versions
-------------------------------------------------------------------------------
EXTENSION: mysqlnd
PRIMARY MAINTAINER: Andrey Hristov <andrey@php.net> (2007 - 2017)
Johannes Schlüter <johannes@php.net> (2008 - 2018)
Ulf Wendel <uw@php.net> (2009 - 2011)
MAINTENANCE: Maintained
EXTENSION: mysql
MAINTENANCE: Unknown
STATUS: Working
SINCE: 5.3
-------------------------------------------------------------------------------
EXTENSION: oci8
PRIMARY MAINTAINER: Christopher Jones <sixd@php.net> (2007 - 2017)
Antony Dovgal <tony2001@php.net> (2003 - 2009)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: odbc
PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net> (2000 - 2004)
MAINTENANCE: Maintained
STATUS: Working
COMMENT: Working
-------------------------------------------------------------------------------
EXTENSION: pdo
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net> (2004 - 2011)
Wez Furlong <wez@php.net> (2004 - 2006)
MAINTENANCE: Odd fixes
STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
EXTENSION: pdo_dblib
PRIMARY MAINTAINER: Adam Baratz <adambaratz@php.net> (2016 - 2017)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
EXTENSION: pdo_firebird
PRIMARY MAINTAINER: Lars Westermann <lwe@php.net> (2007 - 2007)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
EXTENSION: pdo_mysql
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net> (2004 - 2010)
Johannes Schlüter <johannes@php.net> (2008 - 2014)
Andrey Hristov <andrey@php.net> (2005 - 2015)
Ulf Wendel <uw@php.net> (2008 - 2012)
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: Christopher Jones <sixd@php.net> (2007 - 2017)
MAINTENANCE: Odd fixes
STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
EXTENSION: pdo_pgsql
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net> (2004 - 2011)
MAINTENANCE: Odd fixes
STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
EXTENSION: pdo_sqlite
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net> (2005 - 2011)
MAINTENANCE: Odd fixes
STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
EXTENSION: pgsql
PRIMARY MAINTAINER: Marcus Börger <helly@php.net> (2002 - 2007)
Yasuo Ohgaki <yohgaki@php.net> (2001 - 2015)
PRIMARY MAINTAINER: 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: sqlite3
PRIMARY MAINTAINER: Scott MacVicar <scottmac@php.net> (2008 - 2011)
MAINTENANCE: Maintained
EXTENSION: sybase
MAINTENANCE: Unknown
STATUS: Not Working
-------------------------------------------------------------------------------
EXTENSION: sybase_ct
MAINTENANCE: Unknown
STATUS: Working
SINCE: 5.3
COMMENT: Integrates SQLite 3 embeddable SQL database engine.
-------------------------------------------------------------------------------
== XML extensions ==
-------------------------------------------------------------------------------
EXTENSION: dom
PRIMARY MAINTAINER: Christian Stocker <chregu@php.net> (2003 - 2011)
Rob Richards <rrichards@php.net> (2003 - 2012)
Marcus Börger <helly@php.net> (2003 - 2006)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.0
-------------------------------------------------------------------------------
EXTENSION: simplexml
PRIMARY MAINTAINER: Marcus Börger <helly@php.net> (2003 - 2008)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.0
-------------------------------------------------------------------------------
EXTENSION: soap
PRIMARY MAINTAINER: Dmitry Stogov <dmitry@php.net> (2004 - 2018)
EXTENSION: oci8
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: wddx
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net> (1999 - 2003)
MAINTENANCE: Orphaned
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: xml
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net> (1999 - 2002)
Rob Richards <rrichards@php.net> (2003 - 2013)
EXTENSION: odbc
PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net>
MAINTENANCE: Maintained
STATUS: Working
COMMENT: Working except for persistent connections
-------------------------------------------------------------------------------
EXTENSION: libxml
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net> (2003 - 2009)
Christian Stocker <chregu@php.net> (2004 - 2011)
EXTENSION: oracle
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.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: Unknown
MAINTENANCE: Orphaned
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: xmlwriter
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net> (2004 - 2010)
Christian Stocker <chregu@php.net> (2004 - 2004)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: xsl
PRIMARY MAINTAINER: Christian Stocker <chregu@php.net> (2003 - 2011)
Rob Richards <rrichards@php.net> (2003 - 2010)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.0
COMMENT: Using the new OCI8 driver is encouraged where possible.
-------------------------------------------------------------------------------
== Other extensions ==
-------------------------------------------------------------------------------
EXTENSION: bcmath
MAINTENANCE: Andi Gutmans <andi@php.net> (2000 - 2004)
EXTENSION: aspell
MAINTENANCE: Unknown
STATUS: Working
COMMENT: For aspell .27 and greater, check out the pspell extension
-------------------------------------------------------------------------------
EXTENSION: bcmath
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: bz2
PRIMARY MAINTAINER: Hartmut Holzgraefe <hholzgra@php.net> (2004 - 2004)
MAINTENANCE: Odd Fixes
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.3
-------------------------------------------------------------------------------
EXTENSION: calendar
PRIMARY MAINTAINER: Hartmut Holzgraefe <hholzgra@php.net> (2000 - 2004)
PRIMARY MAINTAINER: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Odd Fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: com_dotnet
PRIMARY MAINTAINER: Wez Furlong <wez@php.net> (2003 - 2005)
EXTENSION: com
PRIMARY MAINTAINER: Harald Radi <h.radi@nme.at>
MAINTENANCE: Maintained
STATUS: Windows
SINCE: 5.0
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: cpdf
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: crack
MAINTENANCE: Unknown
STATUS: Experimental
SINCE: 4.0.5
-------------------------------------------------------------------------------
EXTENSION: ctype
PRIMARY MAINTAINER: Hartmut Holzgraefe <hholzgra@php.net> (2000 - 2004)
PRIMARY MAINTAINER: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: curl
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net> (2000 - 2004)
Ilia Alshanetsky <iliaa@php.net> (2002 - 2011)
Pierrick Charron <pierrick@php.net> (2010 - 2016)
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.2
-------------------------------------------------------------------------------
EXTENSION: date
PRIMARY MAINTAINER: Derick Rethans <derick@php.net> (2005 - 2018)
EXTENSION: cybercash
PRIMARY MAINTAINER: Evan Klinger <evan715@sirius.com>
MAINTENANCE: Maintained
STATUS: Working
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: enchant
PRIMARY MAINTAINER: Unknown
EXTENSION: domxml
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: dotnet
PRIMARY MAINTAINER: Sam Ruby <rubys@us.ibm.com>
MAINTENANCE: Maintained
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: exif
PRIMARY MAINTAINER: Kalle Sommer Nielsen <kalle@php.net> (2010 - 2018)
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.2
-------------------------------------------------------------------------------
EXTENSION: fileinfo
PRIMARY MAINTAINER: Derick Rethans <derick@php.net> (2004 - 2008)
Anatol Belski <ab@php.net> (2012 - 2018)
EXTENSION: fdf
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
-------------------------------------------------------------------------------
EXTENSION: filter
PRIMARY MAINTAINER: Derick Rethans <derick@php.net> (2006 - 2006)
Pierre-Alain Joye <pajoye@php.net> (2006 - 2011)
Ilia Alshanetsky <iliaa@php.net> (2006 - 2011)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.2
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: ftp
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Odd fixes
STATUS: Working
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: gd
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net> (2002 - 2016)
Christoph M. Becker <cmb@php.net> (2015 - 2018)
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
@@ -325,187 +272,202 @@ MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: gmp
PRIMARY MAINTAINER: Stanislav Malyshev <stas@php.net> (2000 - 2018)
Antony Dovgal <tony2001@php.net> (2005 - 2010)
MAINTENANCE: Maintained
STATUS: Working
MAINTENANCE: Unknown
STATUS: Unknown
SINCE: 4.0.4
-------------------------------------------------------------------------------
EXTENSION: hash
PRIMARY MAINTAINER: Sara Golemon <pollita@php.net> (2005 - 2017)
Mike Wallner <mike@php.net> (2005 - 2013)
Anatol Belski <ab@php.net> (2014 - 2018)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.1.2
-------------------------------------------------------------------------------
EXTENSION: iconv
PRIMARY MAINTAINER: Moriyoshi Koizumi <moriyoshi@php.net> (2002 - 2010)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: intl
PRIMARY MAINTAINER: Stanislav Malyshev <stas@php.net> (2008 - 2018)
Anatol Belski <ab@php.net> (2017 - 2018)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
EXTENSION: icap
MAINTENANCE: Unknown
STATUS: Obsolete
-------------------------------------------------------------------------------
EXTENSION: imap
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org> (1999 - 2004)
Ilia Alshanetsky <iliaa@php.net> (2002 - 2010)
Pierre-Alain Joye <pajoye@php.net> (2008 - 2010)
MAINTENANCE: Maintained
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org>
MAINTENANCE: Odd Fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: json
PRIMARY MAINTAINER: Jakub Zelenka <bukka@php.net> (2014 - 2018)
EXTENSION: java
PRIMARY MAINTAINER: Sam Ruby <rubys@us.ibm.com>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.2
-------------------------------------------------------------------------------
EXTENSION: ldap
PRIMARY MAINTAINER: Stig Venaas <venaas@php.net> (2000 - 2002)
Douglas Goldstein <cardoe@php.net> (2007 - 2007)
Pierre-Alain Joye <pajoye@php.net> (2008 - 2010)
Côme Bernigaud <mcmic@php.net> (2015 - 2017)
PRIMARY MAINTAINER: Stig Venaas <venaas@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: mbstring
PRIMARY MAINTAINER: Rui Hirokawa <hirokawa@php.net> (2001 - 2013)
PRIMARY MAINTAINER: Rui Hirokawa <hirokawa@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: opcache
PRIMARY MAINTAINER: Dmitry Stogov <dmitry@php.net> (2013 - 2018)
Xinchen Hui <laruence@php.net> (2013 - 2018)
EXTENSION: mcal
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org>
MAINTENANCE: Odd Fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: mcrypt
PRIMARY MAINTAINER: Derick Rethans <d.rethans@jdimedia.nl>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.5.0
-------------------------------------------------------------------------------
EXTENSION: mhash
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: muscat
PRIMARY MAINTAINER: Sam Liddicott <sam@ananova.com>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.5
COMMENT: Not tested against windows, only core API completed, rest under development
-------------------------------------------------------------------------------
EXTENSION: openssl
PRIMARY MAINTAINER: Wez Furlong <wez@php.net> (2001 - 2006)
Pierre-Alain Joye <pajoye@php.net> (2006 - 2011)
Jakub Zelenka <bukka@php.net> (2015 - 2019)
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>
MAINTENANCE: Maintained
STATUS: Working
STATUS: Experimental
SINCE: 4.0.4
-------------------------------------------------------------------------------
EXTENSION: pcntl
PRIMARY MAINTAINER: Arnaud Le Blanc <lbarnaud@php.net> (2008 - 2010)
EXTENSION: overload
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
MAINTENANCE: Maintained
STATUS: Working
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: pcre
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net> (1999 - 2006)
Nuno Lopes <nlopess@php.net> (2006 - 2009)
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: phar
PRIMARY MAINTAINER: Greg Beaver <cellog@php.net> (2008 - 2009)
Marcus Börger <helly@php.net> (2008 - 2008)
Steph Fox <sfox@php.net> (2008 - 2008)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
-------------------------------------------------------------------------------
EXTENSION: posix
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de> (2000 - 2000)
EXTENSION: pdf
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: pspell
PRIMARY MAINTAINER: Vlad Krupin <phpdevel@echospace.com> (2000 - 2004)
MAINTENANCE: Unknown
EXTENSION: pfpro
PRIMARY MAINTAINER: David Croft <david@infotrek.co.uk>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.2
-------------------------------------------------------------------------------
EXTENSION: posix
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: printer
PRIMARY MAINTAINER: Daniel Beulshausen <daniel@php4win.de>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.4
COMMENT: Only for Win32
-------------------------------------------------------------------------------
EXTENSION: pspell
PRIMARY MAINTAINER: Vlad Krupin <phpdevel@echospace.com>
MAINTENANCE: Unknown
STATUS: Unknown
SINCE: 4.0.2
-------------------------------------------------------------------------------
EXTENSION: qtdom
MAINTENANCE: Unknown
STATUS: Experimental
SINCE: 4.0.4
-------------------------------------------------------------------------------
EXTENSION: readline
MAINTENANCE: Unknown
STATUS: Working
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: recode
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de> (2000 - 2000)
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: reflection
PRIMARY MAINTAINER: Marcus Börger <helly@php.net> (2003 - 2009)
Johannes Schlüter <johannes@php.net> (2006 - 2014)
MAINTENANCE: Maintained
STATUS: Working
EXTENSION: sablot
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Obsolete
STATUS: Experimental
SINCE: 4.0.3
-------------------------------------------------------------------------------
EXTENSION: satellite
PRIMARY MAINTAINER: David Eriksson <eriksson@php.net>
MAINTENANCE: Odd Fixes
STATUS: Experimental
SINCE: 4.0.3
-------------------------------------------------------------------------------
EXTENSION: session
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx> (1999 - 2004)
Ilia Alshanetsky <iliaa@php.net> (2002 - 2012)
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: shmop
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net> (2002 - 2008)
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>
MAINTENANCE: Maintained
STATUS: Working
STATUS: Experimental
SINCE: 4.0.3
-------------------------------------------------------------------------------
EXTENSION: snmp
PRIMARY MAINTAINER: Boris Lytochkin <lytboris@php.net> (2011 - 2013)
Rasmus Lerdorf <rasmus@php.net> (1999 - 2002)
Pierre-Alain Joye <pajoye@php.net> (2010 - 2011)
MAINTENANCE: Maintained
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
MAINTENANCE: Odd Fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: sockets
PRIMARY MAINTAINER: Chris Vandomelen <chrisv@b0rked.dhs.org> (2000 - 2000)
PRIMARY MAINTAINER: Chris Vandomelen <chrisv@b0rked.dhs.org>
MAINTENANCE: Maintained
STATUS: Working
STATUS: Experimental
SINCE: 4.0.2
-------------------------------------------------------------------------------
EXTENSION: sodium
PRIMARY MAINTAINER: Frank Denis <jedisct1@php.net> (2017 - 2017)
EXTENSION: swf
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 7.2.0
-------------------------------------------------------------------------------
EXTENSION: spl
PRIMARY MAINTAINER: Marcus Börger <helly@php.net> (2003 - 2009)
Etienne Kneuss <colder@php.net> (2008 - 2014)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.0.0
-------------------------------------------------------------------------------
EXTENSION: sysvmsg
MAINTENANCE: Unknown
STATUS: Working
STATUS: Depreciated (Use the ming swf extension instead)
COMMENT: Only for Unix (won't change)
-------------------------------------------------------------------------------
EXTENSION: sysvsem
MAINTENANCE: Unknown
STATUS: Working
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: sysvshm
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: tidy
PRIMARY MAINTAINER: John Coggeshall <john@php.net> (2003 - 2006)
Ilia Alshanetsky <iliaa@php.net> (2003 - 2009)
Nuno Lopes <nlopess@php.net> (2006 - 2012)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: tokenizer
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net> (2002 - 2002)
EXTENSION: vpopmail
MAINTENANCE: Unknown
STATUS: Working
STATUS: Experimental
SINCE: 4.0.5
-------------------------------------------------------------------------------
EXTENSION: zip
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net> (2006 - 2011)
EXTENSION: wddx
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: xml
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: xslt
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANC: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: yaz
PRIMARY MAINTAINER: Adam Dickmeiss <adam@indexdata.dk>
MAINTENANCE: Maintained
STATUS: Unknown
SINCE: 4.0.1
-------------------------------------------------------------------------------
EXTENSION: yp
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: zlib
PRIMARY MAINTAINER: Stefan Roehrich <sr@linux.de> (1999 - 2003)
PRIMARY MAINTAINER: Stefan Roehrich <sr@linux.de>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: zziplib
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Maintained
STATUS: Experimental
SINCE: 4.0.5
-------------------------------------------------------------------------------
# iptc?
+416 -2
View File
@@ -1,3 +1,417 @@
For installation of PHP, please refer to the online documentation available at:
Installation Instructions for PHP 4
-----------------------------------
STOP!
Before going any further, please remember you are going to find more
up to date instructions in the online manual, located here:
http://www.php.net/manual/en/install.apache.php
It is strongly recommended that you read the manual page before going
further. However, for the impatient, here is a quick set of steps that
will build PHP as (first) a dynamic Apache module (DSO) for Apache 1.3.x
with MySQL support and then a static module. A more verbose explanation follows.
For installing PHP on other web servers, refer to one of the following
files:
sapi/aolserver/README
sapi/pi3web/README
sapi/servlet/README
sapi/thttpd/README
README.Zeus
Some notes:
1: Only install either the static module or the dynamic one. Do not
install both.
2: If you are recompiling PHP to add new extensions or upgrading
something like GD, remove the config.cache file before you re-run
configure.
3: If you are on Linux and have installed shared libraries, make
sure the location of these shared libraries are listed in your
/etc/ld.so.conf file. For example, if you have:
/usr/local/lib/mysql/libmysqlclient.so
Make sure /etc/ld.so.conf contains:
/usr/local/lib/mysql
Then run ldconfig.
If you want both PHP 3 and 4 modules in the same Apache server, check the
bottom of this file for instructions.
INSTALLATION WITH THE ZEUS WEB SERVER:
--Please see the 'README.Zeus' file included in this distribution
QUICK INSTALL (DSO)
For this to work your Apache httpd must have mod_so enabled.
Check using httpd -l. You should see something like:
Compiled-in modules:
http_core.c
mod_so.c
Chances are you will see a lot more modules than these two. That's ok,
as long as mod_so.c shows up you can proceed with the following steps:
$ gunzip -c php-4.x.y.tar.gz | tar xf -
$ cd php-4.x.y
$ ./configure --with-mysql --with-apxs
$ make
$ make install
If you get an error telling you that the apxs script could not be found,
look for it on your system and if you find it, provide the full path to it
as: --with-apxs=/path/to/apxs
Make sure you specify the version of apxs that is actually installed on
your system and NOT the one that is in the apache source tarball.
Next you must copy php.ini-dist to the appropriate place (normally
/usr/local/lib/php.ini) and edit it as necessary to set PHP options.
The only thing left to do is to edit your httpd.conf file and make sure the
PHP 4 mime type is there and uncommented. You need a line that looks like
this:
AddType application/x-httpd-php .php
Then restart your server (apachectl restart) and you should be able to
serve up PHP files now. Make a test file called test.php and put some
PHP tags in it. Like <?phpinfo()?>, for example.
QUICK INSTALL (Static)
$ gunzip -c apache_1.3.x.tar.gz | tar xf -
$ cd apache_1.3.x
$ ./configure
$ cd ..
$ gunzip -c php-4.x.y.tar.gz | tar xf -
$ cd php-4.x.y
$ ./configure --with-mysql --with-apache=../apache_1.3.x
$ make
$ make install
$ cd ../apache_1.3.x
$ ./configure --prefix=/www --activate-module=src/modules/php4/libphp4.a
(The above line is correct! Yes, we know libphp4.a does not exist at this
stage. It isn't supposed to. It will be created.)
$ make
(you should now have an httpd binary which you can copy to your Apache bin dir if
is is your first install then you need to "make install" as well)
$ cd ../php-4.x.y
$ cp php.ini-dist /usr/local/lib/php.ini
You can edit /usr/local/lib/php.ini file to set PHP options.
Edit your httpd.conf or srm.conf file and add:
AddType application/x-httpd-php .php
VERBOSE INSTALL
Chances are you are reading this because the quick install steps above
did not work for you. If this is the case, congratulations, you are
among the elite few that actually reads documentation. It really is
not a difficult install and once you have done it once you will fly
through it.
Installing PHP can be done in four simple steps:
1. Unpack your distribution file.
You will have downloaded a file named something like php-4.x.y.tar.gz.
Unzip this file with a command like: gunzip php-4.x.y.tar.gz
Next you have to untar it with: tar -xvf php-4.x.y.tar
This will create a php-4.x.y directory. cd into this new directory.
2a. Configure PHP (Dynamic Module) - Skip to 2b if you wish to build
a static module
You now have to choose the options you would like. There are quite
a few of them. To see a list, type: ./configure --help
The only options that you are likely to want to use are the ones in
the last section entitled, "--enable and --with options recognized:"
A popular choice is to build the Apache module version. In order to
build PHP as a dynamic module for Apache-1.3.x you have to first have
Apache installed. Assuming Apache is already installed, make sure
the shared object module is enabled. To check this, type: httpd -l
You should see something like:
Compiled-in modules:
http_core.c
mod_so.c
You will most likely have a lot more modules than what is shown here.
As long as mod_so.c shows up in the list, PHP should be happy.
Now, type: ./configure --with-mysql --with-apxs
If you get an error telling you that the apxs script could not be found,
look for it on your system and if you find it, provide the full path to it
as: --with-apxs=/path/to/apxs
Make sure you specify the version of apxs that is actually installed on
your system and NOT the one that is in the apache source tarball.
You might also want other flags on this configure line. --with-mysql
is just an example.
There are a few things that can go wrong during this configure step.
The most common is that you have asked for an option and that the
configure script can not find the files required to enable this
option in PHP. Chances are you can provide the full path to the
base directory under which the related files were installed. For
example, if you have installed the GD library in /opt/gd which means
that /opt/gd/include has your GD header files and /opt/gd/lib contains
your GD library files, you would use --with-gd=/opt/gd
Skip to step 3 for compilation and installation instructions.
2b. Configure PHP (Static Module) - Skip if you performed 2a
You now have to choose the options you would like. There are quite
a few of them. To see a list, type: ./configure --help
The only options that you are likely to want to use are the ones in
the last section entitled, "--enable and --with options recognized:"
A popular choice is to build the Apache module version. You need
to know where the source code directory for your Apache server is
located. Then use an option like: --with-apache=/usr/local/src/apache
if that is your Apache source code directory. If you only specify
--with-apache, then it will default to look for your Apache source
in /usr/local/etc/httpd.
NOTE: The directory you specify should be the top-level of the
unpacked Apache (or Stronghold) distribution. The configure program
will automatically look for httpd.h in different directories under that
location depending on which version of Apache, including Stronghold,
you are running.
For MySQL support, since newer versions of MySQL installs its various
components under /usr/local, this is the default. If you have
changed the location you can specify it with: --with-mysql=/opt/local
for example. Otherwise just use: --with-mysql
*NOTE* If you are using Apache 1.3b6 or later, you should run the
Apache Configure script at least once before compiling PHP. It
doesn't matter how you have Apache configured at this point.
Skip to step 3b at this point.
3. Compile and install the files. Simply type: make install
3a. Dynamic Module Installation
Nothing else is needed here. Proceed to step 4a.
3b. Static Module Installation
For the Apache module version this will copy the appropriate files
to the src/modules/php4 directory in your Apache distribution if
you are using Apache 1.3.x. If you are still running Apache 1.2.x
these files will be copied directly to the main src directory.
For Apache 1.3b6 and later, you can use the new APACI configuration
mechanism. To automatically build Apache with PHP support, use:
cd apache_1.3.x
./configure --prefix=/<path>/apache \
--activate-module=src/modules/php4/libphp4.a
make
make install
If you do not wish to use this new configuration tool, the old
install procedure (src/Configure) will work fine.
If you are using the old Apache ./Configure script, you will have to
edit the Apache src/Configuration file manually. If you do not have
this file, copy Configuration.tmpl to Configuration.
For Apache 1.3.x add:
AddModule modules/php4/libphp4.a
For Apache 1.3.x don't do anything else. Just add this line and then
run "./Configure" followed by "make".
For Apache 1.2.x add:
Module php4_module mod_php4.o
For Apache 1.2.x you will also have to look in the libphp4.module file,
which was copied to the src directory. The EXTRA_LIBS line in the Apache
Configuration file needs to be set to use the same libs as specified on
the LIBS line in libphp4.module. You also need to make sure to add
"-L." to the beginning of the EXTRA_LIBS line.
So, as an example, your EXTRA_LIBS line might look like:
EXTRA_LIBS=-L. -lphp4 -lgdbm -ldb -L/usr/local/mysql/lib -lmysqlclient
NOTE: You should not enclose the EXTRA_LIBS line in double-quotes, as it
is in the libphp4.module file.
Also, look at the RULE_WANTHSREGEX setting in the libphp4.module file
and set the WANTHSREGEX directive accordingly in your Configuration file.
This last step applies to versions of Apache prior to 1.3b3.
This is a bit of a hassle, but should serve as incentive to move to
Apache 1.3.x where this step has been eliminated.
Once you are satisfied with your Configuration settings, type: ./Configure
If you get errors, chances are that you forgot a library or made a typo
somewhere. Re-edit Configuration and try again. If it goes well,
type: make
Assuming it compiles without errors, proceed to step 4b.
4a. Setting up the server. (Dynamic Module)
The make install command in step 3 should have done most of your
work for you. It actually edits your httpd.conf file and tries to
enable the dynamic PHP module. To verify this, look for a line that
looks like this:
LoadModule php4_module libexec/libphp4.so
The actual path before the libphp4.so part might differ slightly. This
is likely fine. If you are paranoid you can examine the output from the
make install step to see where the libphp4.so file was actually put and
place the full path to this file on this LoadModule line.
If somewhere in your httpd.conf file you have a ClearModuleList line
then you also need this line:
AddModule mod_php4.c
And finally you need to tell Apache which file extension should trigger
PHP. You do this by creating a special mime type and associating it
with an extension. We suggest using:
AddType application/x-httpd-php .php
You are however free to use any extension you wish, including .html.
Note! If a line has a # at the beginning, then it is commented out
and you need to remove the # for that line to take effect.
Finally you need to copy php.ini-dist to the appropriate place
(normally /usr/local/lib/php.ini) and edit if necessary.
Once you have made these changes you should be ready to restart your
server and try it out. Type: apachectl restart
4b. Setting up the server. (Static Module)
You should now have a new httpd binary. Shut down your existing server,
if you have one, and copy this new binary overtop of it. Perhaps make
a backup of your previous one first. Then edit your conf/httpd.conf file
and add the line:
AddType application/x-httpd-php .php
There is also an interesting feature which can be quite instructive and
helpful while debugging. That is the option of having colour syntax
highlighting. To enable this, add the following line:
AddType application/x-httpd-php-source .phps
Any file ending in .phps will now be displayed with full colour syntax
highlighting instead of being executed.
Note that on some older server setups, the AddType lines are in the
conf/srm.conf file instead of conf/httpd.conf.
Note! If a line has a # at the beginning, then it is commented out
and you need to remove the # for that line to take effect.
When you are finished making changes to your httpd.conf file, you need
to copy php.ini-dist to the appropriate place (normally
/usr/local/lib/php.ini) and edit if necessary. You can then
start up your server.
5. Testing it all worked
Create a test file named test.php in your web tree somewhere and
put some test PHP tags in it. <?phpinfo()?> is a good first test.
This tag tells PHP to do a braindump and tells you all sorts of things
about itself.
WHY DISABLING -fPIC WORKS ON LINUX
From: Martin v. Loewis <martin@loewis.home.cs.tu-berlin.de>
To: glibc-linux@ricardo.ecn.wfu.edu
Subject: Re: Shared library -shared vs. -fpic
[In reply to Kaz Kylheku <kaz@ashi.footprints.net>]
> PIC stands for Position-Independent Code.
Correct.
> Code isn't position-independent (or ``relocatable'') cannot be
> loaded at an arbitrary address;
Wrong.
> it requires some references to be patched at load time.
Correct.
> Shared libraries need to be relocatable because it's not known
> beforehand what address they will be loaded at
Correct, depending on the meaning of "relocatable". PIC code typically
does not contain relocations; that's why its position-independent.
> Just because you don't specify -fPIC doesn't mean that the compiler
> won't emit position-independent code; the option prevents it from
> emitting position-dependent code in situations where it otherwise
> would.
Correct. However, a non-trivial shared library typically won't be
position-independent unless explicitly compiled with
-fPIC. Linux/glibc indeed does not require a shared library to be
position-independent; instead, it will perform the relocations in the
binary, even if they refer to code pages. As a result, those relocated
pages won't be shared across processes, anymore.
Regards,
Martin
USING PHP 3 AND PHP 4 AS CONCURRENT APACHE MODULES
With some (newer) installations of Apache, it's possible to compile both
PHP 3 and PHP 4, and run them concurrently.
Note, it's only really wise to do this if you need to use the PHP 3 engine
to maintain backwards compatibility.
To enable it, configure PHP 3 and PHP 4 to use APXS (--with-apxs) and the
necessary link extensions (--enable-versioning). Otherwise, all standard
installations instructions apply. For example:
$ ./configure \
--with-apxs=/apache/bin/apxs \
--enable-versioning \
--with-mysql \
https://php.net/install
+18 -18
View File
@@ -1,7 +1,7 @@
--------------------------------------------------------------------
The PHP License, version 3.01
Copyright (c) 1999 - 2018 The PHP Group. All rights reserved.
--------------------------------------------------------------------
--------------------------------------------------------------------
The PHP License, version 3.0
Copyright (c) 1999 - 2002 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
@@ -9,22 +9,22 @@ 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.
@@ -38,31 +38,31 @@ are met:
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 product includes PHP, freely available from
<http://www.php.net/>".
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
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
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
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,
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
This product includes the Zend Engine, freely available at
<http://www.zend.com>.
+13 -17
View File
@@ -1,22 +1,18 @@
#
# Zend
#
$(builddir)/zend_language_scanner.lo: $(builddir)/zend_language_parser.h
$(builddir)/zend_ini_scanner.lo: $(builddir)/zend_ini_parser.h
$(builddir)/zend_language_scanner.lo: $(srcdir)/zend_language_parser.h
$(builddir)/zend_ini_scanner.lo: $(srcdir)/zend_ini_parser.h
$(builddir)/zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
$(LEX) -Pzend -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_language_scanner.l
$(srcdir)/zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l)
$(builddir)/zend_language_parser.h: $(builddir)/zend_language_parser.c
$(builddir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
$(YACC) -p zend -v -d $(srcdir)/zend_language_parser.y -o $@
$(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 $@
$(builddir)/zend_ini_parser.h: $(builddir)/zend_ini_parser.c
$(builddir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_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 $@
$(builddir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
$(LEX) -Pini_ -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_ini_scanner.l
$(srcdir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l)
$(builddir)/zend_highlight.lo $(builddir)/zend_compile.lo: $(srcdir)/zend_language_parser.h
$(builddir)/zend_indent.lo $(builddir)/zend_highlight.lo $(builddir)/zend_compile.lo: $(builddir)/zend_language_parser.h
-78
View File
@@ -1,78 +0,0 @@
#
# LCOV
#
LCOV_INCLUDE="."
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 \*.c -o -name \*.h | sed -e 's/^\.\///' | sed -e 's/\.gcda//g' -e 's/\.gcno//g' -e 's/\.da//g' | $(EGREP) $(LCOV_INCLUDE) | sed -e 's/.libs/zzzz/g' | sort | sed -e 's/zzzz/.libs/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; \
if test -f "$$x.gcno"; then \
cp $$x.gcno lcov_data/$$y.gcno ; \
fi; \
if test -f "$$x.gcda"; then \
cp $$x.gcda lcov_data/$$y.gcda ; \
fi; \
if test -f "$$x.da"; then \
cp $$x.da lcov_data/$$y.da ; \
fi; \
if test -f "$$x.bb"; then \
cp $$x.bb lcov_data/$$y.bb ; \
fi; \
if test -f "$$x.bbg"; then \
cp $$x.bbg lcov_data/$$y.bbg ; \
fi; \
done; \
for dir in ext/bcmath/libbcmath ext/date/lib ext/fileinfo/libmagic ext/gd/libgd ext/mbstring/libmbfl ext/mbstring/oniguruma ext/pcre/pcrelib ext/pdo_sqlite/libsqlite ext/sqlite3/libsqlite ext/xmlrpc/libxmlrpc ext/zip/lib; do \
if test -d lcov_data/$$dir; then \
rm -rf lcov_data/$$dir ; \
fi; \
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
+42 -115
View File
@@ -3,145 +3,72 @@ 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)
COMMON_FLAGS = $(DEFS) $(INCLUDES) $(EXTRA_INCLUDES) $(CPPFLAGS)
all: $(all_targets)
@echo
@echo "Build complete."
@echo "Don't forget to run 'make test'."
@echo
build-modules: $(PHP_MODULES) $(PHP_ZEND_EX)
all: $(all_targets)
build-binaries: $(PHP_BINARIES)
build-modules: $(PHP_MODULES)
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
libphp4.la: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(LIBTOOL) --mode=link $(CC) $(COMMON_FLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
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
libs/libphp4.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/libphp4.so
install: $(all_targets) $(install_targets)
php: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(BUILD_CGI)
sapi/cli/php: $(PHP_GLOBAL_OBJS) $(PHP_CLI_OBJS)
$(BUILD_CLI)
install-sapi: $(OVERALL_TARGET)
@echo "Installing PHP SAPI module: $(PHP_SAPI)"
install: $(install_targets)
install-cli: sapi/cli/php
@echo "Installing PHP CLI binary: $(INSTALL_ROOT)$(bindir)/"
@$(INSTALL_CLI)
install-sapi: libphp4.la
@echo "Installing PHP SAPI module"
-@$(LIBTOOL) --silent --mode=install cp libphp4.la $(phptempdir)/libphp4.la >/dev/null 2>&1
-@$(mkinstalldirs) $(INSTALL_ROOT)$(bindir)
-@if test ! -r $(phptempdir)/libphp$(PHP_MAJOR_VERSION).$(SHLIB_DL_SUFFIX_NAME); then \
-@if test ! -r $(phptempdir)/libphp4.$(SHLIB_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); \
if test -r $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME).$$i; then \
$(LN_S) $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME).$$i $(phptempdir)/libphp4.$(SHLIB_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)
$(mkinstalldirs) $(INSTALL_ROOT)$(EXTENSION_DIR) && \
echo "Installing shared extensions: $(INSTALL_ROOT)$(EXTENSION_DIR)/" && \
rm -f modules/*.la && \
cp modules/* $(INSTALL_ROOT)$(EXTENSION_DIR) >/dev/null 2>&1 || true
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
install-tester:
@echo "Installing regression tester: $(INSTALL_ROOT)$(PEAR_INSTALLDIR)/"
@$(mkinstalldirs) $(PEAR_INSTALLDIR)
@$(INSTALL) -m 755 $(top_srcdir)/run-tests.php $(INSTALL_ROOT)$(PEAR_INSTALLDIR)
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\ ]*='
install-su: install-pear install-tester
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); \
TEST_RESULT_EXIT_CODE=$$?; \
rm $(top_builddir)/tmp-php.ini; \
exit $$TEST_RESULT_EXIT_CODE; \
else \
echo "ERROR: Cannot run tests without CLI sapi."; \
fi
test: sapi/cli/php
@TEST_PHP_EXECUTABLE=$(top_builddir)/sapi/cli/php \
$(top_builddir)/sapi/cli/php -c php.ini-dist $(top_srcdir)/run-tests.php
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 \*.lo -o -name \*.o -o -name \*.la -o -name \*.a| xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
rm -f libphp4.la php sapi/cli/php modules/* libs/*
distclean: clean
rm -f Makefile config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h main/internal_functions_cli.c main/internal_functions.c stamp-h buildmk.stamp Zend/zend_dtrace_gen.h Zend/zend_dtrace_gen.h.bak Zend/zend_config.h TSRM/tsrm_config.h
rm -f php7.spec main/build-defs.h scripts/phpize
rm -f ext/date/lib/timelib_config.h ext/mbstring/oniguruma/config.h ext/mbstring/libmbfl/config.h ext/oci8/oci8_dtrace_gen.h ext/oci8/oci8_dtrace_gen.h.bak
rm -f scripts/man1/phpize.1 scripts/php-config scripts/man1/php-config.1 sapi/cli/php.1 sapi/cgi/php-cgi.1 sapi/phpdbg/phpdbg.1 ext/phar/phar.1 ext/phar/phar.phar.1
rm -f sapi/fpm/php-fpm.conf sapi/fpm/init.d.php-fpm sapi/fpm/php-fpm.service sapi/fpm/php-fpm.8 sapi/fpm/status.html
rm -f ext/iconv/php_have_bsd_iconv.h ext/iconv/php_have_glibc_iconv.h ext/iconv/php_have_ibm_iconv.h ext/iconv/php_have_iconv.h ext/iconv/php_have_libiconv.h ext/iconv/php_iconv_aliased_libiconv.h ext/iconv/php_iconv_supports_errno.h ext/iconv/php_php_iconv_h_path.h ext/iconv/php_php_iconv_impl.h
rm -f ext/phar/phar.phar ext/phar/phar.php
if test "$(srcdir)" != "$(builddir)"; then \
rm -f ext/phar/phar/phar.inc; \
fi
$(EGREP) define'.*include/php' $(top_srcdir)/configure | $(SED) 's/.*>//'|xargs rm -f
rm -f config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h stamp-h php4.spec sapi/apache/libphp4.module buildmk.stamp
find . -name Makefile | xargs rm -f
prof-gen:
CCACHE_DISABLE=1 $(MAKE) PROF_FLAGS=-fprofile-generate all
prof-clean:
find . -name \*.lo -o -name \*.o | xargs rm -f
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
prof-use:
CCACHE_DISABLE=1 $(MAKE) PROF_FLAGS=-fprofile-use all
.PHONY: all clean install distclean test prof-gen prof-clean prof-use
.PHONY: all clean install distclean test
.NOEXPORT:
+2123 -2022
View File
File diff suppressed because it is too large. Load diff
+115
View File
@@ -0,0 +1,115 @@
This is the first file you should be reading after you get your CVS account.
We'll assume you're basically familiar with CVS, but feel free to post
your questions on the mailing list. Please have a look at
http://cvsbook.red-bean.com/ for more detailed information on CVS.
PHP is developed through the efforts of a large number of people.
Collaboration is a Good Thing(tm), and CVS lets us do this. Thus, following
some basic rules with regards to CVS usage will:
a. Make everybody happier, especially those responsible for maintaining
the CVS 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.
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.
The next few rules are more of a technical nature.
1. DO NOT TOUCH ChangeLog! It is automagically updated from the commit
messages every day. Woe be to those who attempt to mess with it.
2. All news updates intended for public viewing, such as new features,
bug fixes, improvements, etc., should go into the NEWS file. Also see
the note below about automatically updating NEWS in your commit message.
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.
If a line begins with #, it is taken to be a comment and will not appear
in the ChangeLog. If the line begins with @, it will be redirected to the
NEWS file. Everything else goes into the ChangeLog.
It is important to note that if your comment or news logline spans multiple
lines, you have to put # or @ at the beginning of _every_ such line. Every
entry in NEWS has to have a name after it, so if you did it with someone's
help, put both your names there. Your name WILL NOT be automatically put
at the end of the NEWS entry - so, please provide it yourself.
Example. Say you modified two files, datetime.c and string.c. In datetime.c
you added a new format option for date() function, and in string.c you fixed
a memory leak in php_trim(). Don't commit both of these at once. Commit them
separately and try to make sure your commit messages look something like the
following.
For datetime.c:
(PHP date) Added new 'K' format modifier for printing out number of
days until New Year's Eve.
@- Added new 'K' format modifier that will output the number of days
@ until New Year's Eve. (Bob)
For string.c:
(php_trim) Fixed a memory leak resulting from improper use of zval_dtor().
# Man, that thing was leaking all over the place!
@- Fixed memory leak in trim(). (Bob)
The lines above marked with @ will go into NEWS file automagically, and the
# lines will be omitted from the ChangeLog. Alternatively, you might want
to modify NEWS file directly and not use the @ lines.
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 pgsql notice handler double free crash bug. Bug #14016
@ Fixed pgsql notice handler double free crash bug. Bug #14016
If you don't see your messages in ChangeLog and NEWS right away, don't worry!
These files are updated once a day, so your stuff will not show up until
somewhat later. Don't go adding stuff to NEWS by hand if you already put @
lines in the commit message.
You can use LXR (http://lxr.php.net/) and Bonsai (http://bonsai.php.net/)
to look at PHP CVS repository in various ways.
To receive daily updates to ChangeLog and NEWS, send an empty message to
php-cvs-daily-subscribe@lists.php.net.
Happy hacking,
PHP Team
+39
View File
@@ -0,0 +1,39 @@
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.
+169 -23
View File
@@ -1,43 +1,189 @@
WHAT IT IS
It's a tool for automatically creating the basic framework for a PHP extension.
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 sources. Then
run the following
Very simple. First, cd do directory ext/ in 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
php ext_skel.php --ext extension_name
./ext_skel --extname=module_name
and everything you need will be placed in directory ext/extension_name.
and everything you need is placed in directory module_name.
If you don't need to test the existence of any external header files,
libraries or functions in them, the extension is ready to be compiled in
PHP. To compile the extension, run the following:
[ 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 to use gawk explicitly. ]
./buildconf; ./configure --enable-extension_name; make
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,
cd back up to PHP sources top directory, and do
The definition of PHP_extension_NAME_VERSION will be present in the
php_extension_name.h and injected into the zend_extension_entry definition. This
is required by the PECL website for the version string conformity checks
against package.xml
./buildconf; ./configure --enable-module_name; make
SOURCE AND HEADER FILE NAME
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
The ext_skel.php script generates 'extension_name.c' and 'php_extension_name.h'
as the main source and header files. Keep these names.
--proto=filename.
extension functions (User functions) must be named
FORMAT OF FUNCTION DEFINITIONS FILE
extension_name_function()
All the definitions must be on one line. In it's simplest form, it's just
the function name, ie.
When you need to expose extension functions to other extensions, expose functions
strictly needed by others. Exposed internal function must be named
my_function
php_extension_name_function()
but then you'll be left with an almost empty function body without any
argument handling.
See also CODING_STANDARDS.
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
Run php ext_skel.php --help to see the available 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.
--assign-params
--string-lens
By default, function proto 'void foo(string bar)' creates the following:
...
zval **bar;
... (zend_get_parameters_ex() called in the middle...)
convert_to_string_ex(bar);
Specifying both of these options changes the generated code to:
...
zval **bar_arg;
int bar_len;
char *bar = NULL;
... (zend_get_parameters_ex() called in the middle...)
convert_to_string_ex(bar_arg);
bar = Z_STRVAL_PP(bar_arg);
bar_len = Z_STRLEN_PP(bar_arg);
You shouldn't have to ask what happens if you leave --string-lens out. If you
have to, it's questionable whether you should be reading this document.
--with-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)
{
zval **image, **text, **font, **x, **y, **color;
int argc;
int image_id = -1;
int font_id = -1;
argc = ZEND_NUM_ARGS();
if (argc < 5 || argc > 6 || zend_get_parameters_ex(argc, &image, &text, &font, &x, &y, &color) == FAILURE) {
WRONG_PARAM_COUNT;
}
ZEND_FETCH_RESOURCE(???, ???, image, image_id, "???", ???_rsrc_id);
ZEND_FETCH_RESOURCE(???, ???, font, font_id, "???", ???_rsrc_id);
switch (argc) {
case 6:
convert_to_long_ex(color);
/* Fall-through. */
case 5:
convert_to_long_ex(y);
convert_to_long_ex(x);
/* font: fetching resources already handled. */
convert_to_string_ex(text);
/* image: fetching resources already handled. */
break;
default:
WRONG_PARAM_COUNT;
}
php_error(E_WARNING, "my_drawtext: not yet implemented");
}
/* }}} */
-141
View File
@@ -1,141 +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
PHP 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-debug switch to avoid memory leaks
and 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-7.2 Is used to release the PHP 7.2.x series. This is a current
stable version and is open for bugfixes only.
PHP-7.1 Is used to release the PHP 7.1.x series. This is a current
stable version and is open for bugfixes only.
PHP-7.0 Is used to release the PHP 7.0.x series. This is an old
stable version and is open for security fixes only.
PHP-5.6 Is used to release the PHP 5.6.x series. This is an old
stable version and is open for security fixes only.
PHP-5.5 This branch is closed.
PHP-5.4 This branch is closed.
PHP-5.3 This branch is closed.
PHP-5.2 This branch is closed.
PHP-5.1 This branch is closed.
PHP-4.4 This branch is closed.
PHP-X.Y.Z These branches are used for the release managers for tagging
the releases, hence they are closed to the general public.
The next few rules are more of a technical nature::
1. All changes should first go to the lowest branch (i.e. 5.6) and then
get merged up to all other branches. If a change is not needed for
later branches (i.e. fixes for features which were 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 *any
stable release* version with the given change. In other words,
news about a bug fix which went into PHP-5.4, PHP-5.5 and master
should be noted in both PHP-5.4/NEWS and PHP-5.5/NEWS but
not master, which is not a public released version yet.
3. Do not commit multiple files 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
-79
View File
@@ -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
-139
View File
@@ -1,139 +0,0 @@
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();
Starting the default output handler:
// php_start_ob_buffer(NULL, 0, 1);
php_output_start_default();
Starting an user handler by zval:
// php_start_ob_buffer(zhandler, chunk_size, erase);
php_output_start_user(zhandler, chunk_size, flags);
Starting an internal handler without context:
// php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase);
php_output_start_internal(handler_name, handler_name_len, my_php_output_handler_func_t, chunk_size, flags);
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);
php_output_handler_set_context(h, my_context, my_context_dtor);
php_output_handler_start(h);
Testing whether a certain output handler has already been started:
// php_ob_handler_used("output handler name");
php_output_handler_started(handler_name, handler_name_len);
Flushing one output buffer:
// php_end_ob_buffer(1, 1);
php_output_flush();
Flushing all output buffers:
// not possible with old API
php_output_flush_all();
Cleaning one output buffer:
// php_ob_end_buffer(0, 1);
php_output_clean();
Cleaning all output buffers:
// not possible with old API
php_output_clean_all();
Discarding one output buffer:
// php_ob_end_buffer(0, 0);
php_output_discard();
Discarding all output buffers:
// php_ob_end_buffers(0);
php_output_discard_all();
Stopping (and dropping) one output buffer:
// php_ob_end_buffer(1, 0)
php_output_end();
Stopping (and dropping) all output buffers:
// php_ob_end_buffers(1, 0);
php_output_end_all();
Retrieving output buffers contents:
// php_ob_get_buffer(zstring);
php_output_get_contents(zstring);
Retrieving output buffers length:
// php_ob_get_length(zlength);
php_output_get_length(zlength);
Retrieving output buffering level:
// OG(nesting_level);
php_output_get_level();
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");
php_output_handler_conflict(new_handler_name, new_handler_name_len, set_handler_name, set_handler_name_len);
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);
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);
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);
Disabling of the output handler by itself:
//not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_DISABLE, NULL);
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);
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
+59 -167
View File
@@ -13,8 +13,8 @@ meaningful error messages.
Prototypes
----------
/* Implemented. */
int zend_parse_parameters(int num_args, char *type_spec, ...);
int zend_parse_parameters_ex(int flags, int num_args, char *type_spec, ...);
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
@@ -26,116 +26,51 @@ 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.
PHP 5.3 includes a new function (actually implemented as macro):
int zend_parse_parameters_none();
This returns SUCCESS if no argument has been passed to the function,
FAILURE otherwise.
PHP 5.5 includes a new function:
int zend_parse_parameter(int flags, int arg_num, zval **arg, const char *spec, ...);
This function behaves like zend_parse_parameters_ex() except that instead of
reading the arguments from the stack, it receives a single zval to convert
(passed with double indirection). The passed zval may be changed in place as
part of the conversion process.
See also https://wiki.php.net/rfc/zpp_improv#expose_zend_parse_arg_as_zend_parse_parameter
resources cannot be autoconverted.
Type specifiers
---------------
The following list shows the type specifier, its meaning and the parameter
types that need to be passed by address. All passed parameters 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 (zend_long)
L - long, limits out-of-range numbers to LONG_MAX/LONG_MIN (zend_long, ZEND_LONG_MAX/ZEND_LONG_MIN)
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*, size_t)
P - valid path (string without null bytes in the middle) as zend_string (zend_string*)
r - resource (zval*)
s - string (with possible null bytes) and its length (char*, size_t)
S - string (with possible null bytes) as zend_string (zend_string*)
z - the actual zval (zval*)
* - variable arguments list (0 or more)
+ - variable arguments list (1 or more)
l - long
d - double
s - string (with possible null bytes) and its length
b - boolean, stored in zend_bool
r - resource (stored in zval)
a - array
o - object (of any type)
O - object (of specific type, specified by class entry)
z - the actual zval
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. If NULL is
passed and the output for such type is a pointer, then the output
pointer is set to a native NULL pointer.
For 'b', 'l' and 'd', an extra argument of type zend_bool* must be
passed after the corresponding bool*, zend_long* or double* arguments,
respectively. A non-zero value will be written to the zend_bool if a
PHP NULL is passed.
Note on 64bit compatibility
---------------------------
Please note that since version 7 PHP uses zend_long as integer type and
zend_string with size_t as length, so make sure you pass zend_longs to "l"
and size_t to strings length (i.e. for "s" you need to pass char * and size_t),
not the other way round!
Both mistakes might cause memory corruptions and segfaults:
1)
char *str;
long str_len; /* XXX THIS IS WRONG!! Use size_t instead. */
zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &str_len)
2)
int num; /* XXX THIS IS WRONG!! Use zend_long instead. */
zend_parse_parameters(ZEND_NUM_ARGS(), "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/
| - 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 (only applies
to 'a', 'o', 'O', 'r', and 'z'). If NULL is passed, the results
pointer is set to NULL as well.
Examples
--------
/* Gets a long, a string and its length, and a zval */
zend_long l;
long l;
char *s;
size_t s_len;
int s_len;
zval *param;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "lsz",
&l, &s, &s_len, &param) == FAILURE) {
return;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsz",
&l, &s, &s_len, &param) == 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(), "O|d",
&obj, my_ce, &d) == FAILURE) {
return;
zend_class_entry my_ce;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|d",
&obj, my_ce, &d) == FAILURE) {
return;
}
@@ -143,93 +78,50 @@ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|d",
If null is passed for object, obj will be set to NULL. */
zval *obj;
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "o!a",
&obj, &arr) == FAILURE) {
return;
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(), "a/!",
&arr) == FAILURE) {
return;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!",
&arr) == FAILURE) {
return;
}
/* Get only the first three parameters (useful for varargs functions). */
zval *z;
zend_bool b;
zval *r;
if (zend_parse_parameters(3 TSRMLS_CC, "zbr!",
&z, &b, &r) == FAILURE) {
return;
}
/* Get either a set of 3 longs or a string. */
zend_long l1, l2, l3;
long l1, l2, l3;
char *s;
/*
* The function expects a pointer to a size_t in this case, not a long
/*
* 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 'size_t', the upper bits might not be initialized
* than a 'int', the upper bits might not be initialized
* properly, leading to random crashes on platforms like
* Tru64 or Linux/Alpha.
*/
size_t length;
int length;
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(),
"lll", &l1, &l2, &l3) == SUCCESS) {
/* manipulate longs */
} else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(),
"s", &s, &length) == SUCCESS) {
/* manipulate string */
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 */
/* 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(), "*", &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;
size_t str_len;
int i, num_varargs;
zval *varargs = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s+", &str, &str_len, &varargs, &num_varargs) == FAILURE) {
return;
}
for (i = 0; i < num_varargs; i++) {
/* do something with varargs[i] */
}
/* Function that takes an array, followed by varargs, and ending with a long */
zend_long num;
zval *array;
int i, num_varargs;
zval *varargs = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a*l", &array, &varargs, &num_varargs, &num) == FAILURE) {
return;
}
for (i = 0; i < num_varargs; i++) {
/* do something with varargs[i] */
}
/* Function that doesn't accept any arguments */
if (zend_parse_parameters_none() == FAILURE) {
return;
return;
}
+57
View File
@@ -0,0 +1,57 @@
QNX4 Installation Notes
-----------------------
NOTE: General installation instructions are in the INSTALL file
1. To compile and test PHP3 you have to grab, compile and install:
- GNU dbm library or another db library;
- GNU bison (1.25 or later; 1.25 tested);
- GNU flex (any version supporting -o and -P options; 2.5.4 tested);
- GNU diffutils (any version supporting -w option; 2.7 tested);
2. To use CVS version you may need also:
- GNU CVS (1.9 tested);
- GNU autoconf (2.12 tested);
- GNU m4 (1.3 or later preferable; 1.4 tested);
3. To run configure define -lunix in command line:
LDFLAGS=-lunix ./configure
4. To use Sybase SQL Anywhere define ODBC_QNX and CUSTOM_ODBC_LIBS in
command line and run configure with --with-custom-odbc:
CFLAGS=-DODBC_QNX LDFLAGS=-lunix CUSTOM_ODBC_LIBS="-ldblib -lodbc" ./configure --with-custom-odbc=/usr/lib/sqlany50
If you have SQL Anywhere version 5.5.00, then you have to add
CFLAGS=-DSQLANY_BUG
to workaround its SQLFreeEnv() bug. Other versions has not been tested,
so try without this flag first.
5. To build the Apache module, you may have to hardcode an include path for
alloc.h in your Apache base directory:
- APACHE_DIRECTORY/src/httpd.h:
change #include "alloc.h"
to #include "APACHE_DIRECTORY/src/alloc.h"
Unless you want to use system regex library, you have to hardcode also
a path to regex.h:
- APACHE_DIRECTORY/src/conf.h:
change #include <regex.h>
to #include "APACHE_DIRECTORY/src/regex/regex.h"
I don't know so far why this required for QNX, may be it is Watcom
compiler problem.
If you building Apache module with SQL Anywhere support, you'll get
symbol conflict with BOOL. It is defined in Apache (httpd.h) and in
SQL Anywhere (odbc.h). This has nothing to do with PHP, so you have to
fix it yourself someway.
6. With above precautions, it should compile as is and pass regression
tests completely:
make
make check
make install
Don't bother me unless you really sure you made that all but it
still doesn't work.
June 28, 1998
Igor Kovalenko -- owl@infomarket.ru
-545
View File
@@ -1,545 +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. pcre2lib (ext/pcre)
5. ext/standard crypt
6. ext/standard crypt's blowfish implementation
7. Sqlite/Sqlite3 ext/sqlite3 ext/sqlite
8. ext/standard/rand
9. ext/standard/scanf
10. ext/standard/strnatcmp.c
11. ext/standard/uuencode
12. libxmlrpc ext/xmlrpc
13. libzip ext/zip
14. main/snprintf.c
15. main/strlcat
16. main/strlcpy
17. libgd see ext/gd/libgd/COPYING
18. ext/phar portions of tar implementations
19. libbcmath (ext/bcmath) see ext/bcmath/libbcmath/COPYING.LIB
4. pcre2lib (ext/pcre)
PCRE2 LICENCE
-------------
PCRE2 is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language.
Release 10 of PCRE2 is distributed under the terms of the "BSD" licence, as
specified below, with one exemption for certain binary redistributions. The
documentation for PCRE2, supplied in the "doc" directory, is distributed under
the same terms as the software itself. The data in the testdata directory is
not copyrighted and is in the public domain.
The basic library functions are written in C and are freestanding. Also
included in the distribution is a just-in-time compiler that can be used to
optimize pattern matching. This is an optional feature that can be omitted when
the library is built.
THE BASIC LIBRARY FUNCTIONS
---------------------------
Written by: Philip Hazel
Email local part: ph10
Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
Copyright (c) 1997-2018 University of Cambridge
All rights reserved.
PCRE2 JUST-IN-TIME COMPILATION SUPPORT
--------------------------------------
Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
Copyright(c) 2010-2018 Zoltan Herczeg
All rights reserved.
STACK-LESS JUST-IN-TIME COMPILER
--------------------------------
Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
Copyright(c) 2009-2018 Zoltan Herczeg
All rights reserved.
THE "BSD" LICENCE
-----------------
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 notices,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notices, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Cambridge nor the names of any
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 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.
EXEMPTION FOR BINARY LIBRARY-LIKE PACKAGES
------------------------------------------
The second condition in the BSD licence (covering binary redistributions) does
not apply all the way down a chain of software. If binary package A includes
PCRE2, it must respect the condition, but if package B is software that
includes package A, the condition is not imposed on package B unless it uses
PCRE2 independently.
End
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/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.
9. 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.
10. 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.
11. 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.
12. 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.
13. 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.
14. 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.
15. main/strlcat
16. 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.
18. ext/phar portions of tar implementations
portions of tar implementations in ext/phar - phar_tar_octal() are based on an
implementation by Tim Kientzle from libarchive, licensed with this license:
Copyright (c) 2003-2007 Tim Kientzle
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.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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.
-372
View File
@@ -1,372 +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 two days before a release. So if the release is to be on Thursday,
package on Tuesday. Think about timezones as well.
3. Ensure that the tests on Travis CI are green.
See: https://travis-ci.org/php/php-src/builds
It is recommended to do so a couple of days before the packaging day, to
have enough time to investigate failures, communicate with the authors and
commit the fixes.
The RM for the branch is also responsible for keeping the CI green on
ongoing basis between the releases. Check the CI status for your branch
periodically and resolve the failures ASAP. See more in:
https://wiki.php.net/rfc/travis_ci
4. Ensure that Windows builds will work before packaging
5. Follow all steps to the letter. When unclear ask previous RM's (David/Julien/
Johannes/Stas/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.
6. Verify the tags to be extra sure everything was tagged properly.
7. Moving extensions from/to PECL requires write access 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 a 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 done 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. Check the tests at https://travis-ci.org/php/php-src/builds
3. run the "scripts/dev/credits" script in php-src and commit the changes in the
credits files in ext/standard.
4. Checkout the release branch for this release (e.g., PHP-5.4.2) from the main branch.
5. Bump the version numbers in ``main/php_version.h``, ``configure.ac`` and possibly ``NEWS``.
Do not use abbreviations for alpha and beta. Do not use dashes, you should
``#define PHP_VERSION "5.4.22RC1"`` and not ``#define PHP_VERSION "5.4.22-RC1"``
6. Compile and make test, with and without ZTS, using the right Bison version
(for example, for 5.5, Bison 2.4.1 is used)
7. Check ./sapi/cli/php -v output for version matching.
8. If all is right, commit the changes to the release branch with ``git commit -a``.
9. Tag the repository release branch with the version, e.g.:
``git tag -u YOURKEYID php-5.4.2RC2``
10. Bump the version numbers in ``main/php_version.h``, ``configure.ac`` and ``NEWS``
in the *main* branch (PHP-5.4 for example) to prepare for the **next** version.
F.e. if the RC is "5.4.1RC1" then the new one should be "5.4.2-dev" - regardless if we get
a new RC or not. This is to make sure ``version_compare()`` can correctly work.
Commit the changes to the main branch.
11. Push the changes to the main repo, the tag, the main branch and the release branch :
``git push --tags origin HEAD``
``git push origin {main branch}``
``git push origin {release branch}``
12. run: ``PHPROOT=. ./makedist 5.4.2RC2``, this will export the tree, create configure
and build three tarballs (gz, bz2 and xz).
13. run ``scripts/dev/gen_verify_stub <version> [identity]``, this will sign the tarballs
and output verification information to be included in announcement email
14. Copy those tarballs (scp, rsync) to downloads.php.net, in your homedir there should be a
directory "public_html/". Copy them into there, so that the system can generate
MD5 sums. If you do not have this directory, create it.
15. Now the RC can be found on http://downloads.php.net/~yourname,
f.e. http://downloads.php.net/~derick/
16. Once the release has been tagged, contact the release-managers@ distribution list
so that Windows binaries can be created. Once those are made, they can be found at
http://windows.php.net/download
Getting the non stable release (alpha/beta/RC) announced
--------------------------------------------------------
1. 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 and sha256 checksum information.
2. Update ``web/php.git/include/version.inc`` (x=major version number)
a. ``$PHP_x_RC`` = "5.4.0RC1" (should be set to "false" before)
b. ``$PHP_x_RC_DATE`` = "06 September 2007"
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
Use category "releases" for all stable releases.
Use category "frontpage" for X.Y.0 non-stable releases only (news only).
b. Add the content for the news entry. Be sure to include the text:
"THIS IS A DEVELOPMENT PREVIEW - DO NOT USE IT IN PRODUCTION!"
4. Commit and push changes to qa and web
*Wait for web and qa sites to update with new information before sending announce*
5. Send **separate** emails **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". Include in this information the verification
information output by ``gen_verify_stub``.
6. Send **separate** emails (see example here http://news.php.net/php.pear.qa/5201) **To**
``php-qa@lists.php.net`` and ``primary-qa-tester@lists.php.net``.
These emails are 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-tester@lists.php.net`` by having someone (Hannes, Dan,
Derick) run the following commands for you:
``ssh lists.php.net``
``sudo -u ezmlm ezmlm-sub ~ezmlm/primary-qa-tester/mod moderator-email-address``
Rolling a stable release
------------------------
1. Checkout your release branch, you should have created when releasing previous RC
and bump the version numbers in ``main/php_version.h``, ``configure.ac`` and possibly ``NEWS``.
2. If a CVE commit needs to be merged to the release, then have it committed to
the base branches and merged upwards as usual (f.e commit the CVE fix to 5.3,
merge to 5.4, 5.5 etc...). Then you can cherry-pick it in your release branch.
Don't forget to update NEWS manually in an extra commit then.
3. Commit those changes. Ensure the tests at https://travis-ci.org/php/php-src/builds are
still passing.
4. run the "scripts/dev/credits" script in php-src and commit the changes in the
credits files in ext/standard.
5. Compile and make test, with and without ZTS, using the right Bison version
(for example, for 5.5, Bison 2.4.1 is used)
6. Check ./sapi/cli/php -v output for version matching.
7. tag the repository with the version f.e. "``git tag -u YOURKEYID -s php-5.4.1``"
8. Push the tag f.e. "``git push origin php-5.4.1``"
9. run: ``PHPROOT=. ./makedist php 5.4.1``, this will export the tag, create configure
and build three tarballs (gz, bz2 and xz).
Check if the pear files are updated (phar).
On some systems the behavior of GNU tar can default to produce POSIX compliant archives
with PAX headers. As not every application is compatible with that format, creation of
archives with PAX headers should be avoided. When packaging on such a system, the GNU tar
can be influenced by defining the environment variable TAR_OPTIONS='--format=gnu'.
10. Generate the GPG signature files for the archives.
``gpg -u YOUREMAIL --armor --detach-sign php-X.Y.Z.tar.xxx``
11. Commit and push all the tarballs and signature files to web/php-distributions.git,
then update the git submodule reference in web/php.git:
``git submodule init;
git submodule update;
cd distributions;
git fetch;
git pull --rebase origin master;
cd ..;
git commit distributions;
git push;``
This is to fetch the last commit id from php-distributions.git and commit this
last commit id to web/php.git, then, mirrors will now sync
12. Once the release has been tagged, contact release managers, windows builders, and package maintainers
so that they can build releases. Do not send this announcement to any public lists.
Getting the stable release announced
------------------------------------
1. Update phpweb/include/releases.inc with the old release info
(updates the download archives)
a. You can run ``php bin/bumpRelease 5`` if you are making a release for the
highest branch, otherwise you have to do this manually, see point 1.b
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. ``$PHP_X_SHA256`` array and update all the SHA256 sums
e. set ``$PHP_X_RC`` to false!
f. Make sure there are no outdated "notes" or edited "date" keys in the
``$RELEASES[X][$PHP_X_VERSION]["source"]`` array
g. if the windows builds aren't ready yet prefix the "windows" key with a dot (".windows")
3. Create the release file (releases/x_y_z.php)
Usually we use the same content as for point 6, but included in php template
instead of the release xml.
4. Update php-qa/include/release-qa.php and add the next version as an QARELEASE
(prepare for next RC)
5. 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); ?>/``
e. You may want to try php-web/bin/news2html to automate this task
6. 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
7. **Check mirrors have been synced before announcing or pushing news**
Try, f.e. http://www.php.net/get/php-5.5.1.tar.bz2/from/a/mirror
Try several mirrors, mirrors may update slowly (may take an hour)
8. Commit all the changes to their respective git repos
9. Please note down the sha256 and the PGP signature (.asc). These *must* be
included in the release mail.
10. 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.
Please make sure that the mail to php-announce@ is its own completely separate email.
This is to make sure that replies to the announcement on php-general@ or internals@
will not accidentally hit the php-announce@ mailinglist.
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. ``$PHP_X_SHA256`` array and update all the SHA256 sums
f. 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.
Please make sure that the mail to php-announce@ is its own completely separate email.
This is to make sure that replies to the announcement on php-general@ or internals@
will not accidentally hit the php-announce@ mailinglist.
Forking a new release branch
----------------------------
1. One week prior to cutting X.Y.0beta1, warn internals@ that your version's branch
is about to be cut, and that PHP-X.Y will be moving into feature freeze.
Try to be specific about when the branch will be cut.
Example: http://news.php.net/php.internals/99864
2. Just prior to cutting X.Y.0beta1, create the new branch locally.
Add a commit on master after the branch point clearing the NEWS file, and updating
main/php_versions.h and Zend/zend.h to update versions.
Example: https://github.com/php/php-src/commit/5230541ef59e0637d5522293a7d099bf18ce6af3
Push the new branch and the commit just added to master.
3. Immediately notify internals@ of the branch cut and advise the new merging order:
Example: http://news.php.net/php.internals/99903
4. Update php-web:git.php and wiki.php.net/vcs/gitworkflow to reflect the new branch:
Example: https://github.com/php/web-php/commit/74bcad4c770d95f21b7fbeeedbd76d943bb83f23
5. Notify nlopess@ to add PHP_X_Y tag to gcov.php.net
New Release Manager Checklist
-----------------------------
1. Email systems@ to get setup for access to downloads.php.net and to be added to the
release-managers@ distribution list.
2. Create a GPG key for your @php.net address and publish it by editing `include/gpg-keys.inc`
in the `web-php` repository, adding the output of `gpg --fingerprint "$USER@php.net"`. Let
one or more of the previous RMs sign your key. Publish your public key to pgp.mit.edu with:
`gpg --keyserver pgp.mit.edu --send-keys $KEYID`
3. Request karma to edit main/php_version.h. Possibly karma for other restricted parts of
php-src might come in question.
4. Request karma for web/qa.git and web/php.git for publishing release announcements.
5. Request moderation access to announce@php.net and primary-qa-tester@lists.php.net lists, to
be able to moderate your release announcements. All the announcements should be sent from
the @php.net alias.
+14 -26
View File
@@ -1,7 +1,10 @@
$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
the PHP source. To create such an extension, three things are
required:
- Configuration file (config.m4)
@@ -20,7 +23,7 @@ PREPARING YOUR SYSTEM
GNU libtool
GNU m4
All of these are available from
All of these are available from
ftp://ftp.gnu.org/pub/gnu/
@@ -30,7 +33,7 @@ CONVERTING AN EXISTING EXTENSION
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
@@ -53,7 +56,7 @@ CONVERTING AN EXISTING EXTENSION
[--with-mysql=MYSQL-DIR]
$ make install
The MySQL module will either use the embedded MySQL client
The MySQL module will either use the embedded MySQL client
library or the MySQL installation in MYSQL-DIR.
@@ -64,8 +67,8 @@ DEFINING THE NEW EXTENSION
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
The demo extension does not reference any external
libraries (that is important, because the user does not
need to specify anything).
@@ -75,7 +78,7 @@ DEFINING THE NEW EXTENSION
CREATING THE M4 CONFIGURATION FILE
The m4 configuration can perform additional checks. For a
The m4 configuration can perform additional checks. For a
self-contained extension, you do not need more than a few
macro calls.
@@ -94,7 +97,7 @@ fi
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.
@@ -112,9 +115,8 @@ CREATING SOURCE FILES
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).
Put config.m4 and the source files into one directory. Afterwards,
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
@@ -135,7 +137,7 @@ INSTALLING A SELF-CONTAINED EXTENSION
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
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
@@ -150,17 +152,3 @@ ADDING SHARED MODULE SUPPORT TO A MODULE
#ifdef COMPILE_DL_FOO
ZEND_GET_MODULE(foo)
#endif
PECL SITE CONFORMITY
If you plan to release an extension to the PECL website, there are several
points to be regarded.
1. Add LICENSE or COPYING to the package.xml
2. The following should be defined in one of the extension header files
#define PHP_FOO_VERSION "1.2.3"
This macros has to be used within your foo_module_entry to indicate the
extension version.
+16 -27
View File
@@ -1,9 +1,6 @@
An Overview of the PHP Streams abstraction
==========================================
WARNING: some prototypes in this file are out of date.
The information contained here is being integrated into
the PHP manual - stay tuned...
$Id$
Please send comments to: Wez Furlong <wez@thebrainroom.com>
@@ -11,7 +8,7 @@ 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"
special case sockets and files everytime 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
@@ -27,8 +24,6 @@ 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,
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);
@@ -36,17 +31,16 @@ 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.
names: fread, fwrite, feof, fgetc, fgets, fclose, fflush, fseek, ftell.
Opening Streams
===============
In most cases, you should use this API:
PHPAPI php_stream *php_stream_open_wrapper(const char *path, const char *mode,
int options, char **opened_path);
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.
@@ -62,7 +56,7 @@ Where:
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
@@ -79,7 +73,7 @@ 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);
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:
@@ -94,7 +88,7 @@ PHPAPI php_stream *php_stream_sock_open_host(const char *host, unsigned short po
PHPAPI php_stream *php_stream_sock_open_unix(const char *path, int persistent,
struct timeval *timeout);
Open a UNIX domain socket.
Stream Utilities
================
@@ -140,7 +134,7 @@ 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
NOTE: If you only need to seek forwards, there is no need to call this
function, as the php_stream_seek can emulate forward seeking when the
whence parameter is SEEK_CUR.
@@ -157,11 +151,6 @@ 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?
@@ -195,7 +184,7 @@ 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
In situations where this is not desireable, you should query the stream
to see if it naturally supports FILE *. You can use this code snippet
for this purpose:
@@ -245,7 +234,7 @@ 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)
@@ -289,7 +278,7 @@ 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
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.
@@ -302,7 +291,7 @@ 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.
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
@@ -332,7 +321,7 @@ 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:
For example, for reading from this wierd mysql stream:
static size_t php_mysqlop_read(php_stream * stream, char * buf, size_t count)
{
@@ -346,7 +335,7 @@ static size_t php_mysqlop_read(php_stream * stream, char * buf, size_t count)
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,
@@ -361,7 +350,7 @@ 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"
"Strange mySQL example"
}
Thats it!
+96 -169
View File
@@ -1,194 +1,121 @@
Submitting Enhancements and Patches to PHP
==========================================
Submitting Patch for PHP
========================
This document describes how to submit an enhancement or patch for PHP.
It's easy!
This document describes how to submit a patch for PHP. Since you are
reading this document, you are willing to submit a patch for PHP.
Please keep reading! Submitting a patch for PHP is easy. The hard
part is making it acceptable for inclusion into our repository. :-)
You don't need any login accounts or special access to download,
build, debug and begin submitting PHP or PECL code, tests or
documentation. Once you've followed this README and had several
patches accepted, commit privileges are often quickly granted.
How to create patch?
--------------------
We are working with CVS. You need to get CVS source to create a patch
that we accept. Visit http://www.php.net/anoncvs.php to get CVS
source. You can check out older versions, but make sure you get
the default branch (i.e. Do not use -r option when you check out the
CVS source)
An excellent article to read first is:
http://phpadvent.org/2008/less-whining-more-coding-by-elizabeth-smith
Read CODING_STANDARDS file before you start working.
Now you are ready to create a patch. Modify source to fix a bug in PHP or
add a new feature to PHP. After you finished editing, please test your
patch. Read README.TESTING for testing.
After you finish testing your patch, take diff file using
"cvs diff > your.patch" command.
Read README.TESTING for submitting a test script for your patch. This is
not strictly required, but it is preferred to submit a test script along
with your patch. Making new test script is very easy. It also helps us
to understand what you have been fixed or added to PHP.
Online Forums
-------------
There are several IRC channels where PHP developers are often
available to discuss questions. They include #php.pecl and #php.doc
on the EFNet network and #winphp-dev on FreeNode.
Tips for creating patch
-----------------------
If you would like to fix multiple bugs. It is easier for us if you
could create 1 patch for 1 bug, but this is not strictly required.
Note though that you might get little response, if your patch is
too hard to review.
If you would like change/add many lines, it is better to ask module
maintainer and/or php-dev@lists.php.net, or pear-dev@lists.php.net if
you are patching PEAR. Official module maintainers can be found in
EXTENSIONS file in PHP source.
If you are new to CVS (Concurrent Versions System), visit
http://cvshome.org/ for details.
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.
Recommended CVS client settings for creating patch file
------------------------------------------------------
Recommended ~/.cvsrc file setting is:
------
cvs -z3
update -d -P
checkout -P
diff -u
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://php.net/mailing-lists.php.
------
diff -u means:
-u Use the unified output format.
Information on PHP internal C functions is at
http://php.net/internals, though this is considered incomplete.
Various external resources can be found on the web. See
https://wiki.php.net/internals for some references. A standard
printed reference is the book "Extending and Embedding PHP" by Sara
Golemon.
The preferred way to propose PHP patch is sending pull request from
GitHub: https://github.com/php/php-src
Fork the official PHP repository and send a pull request. A
notification will be sent to the pull request mailing list. Sending a
note to PHP Internals list (internals@lists.php.net) may help getting
more feedback and quicker turnaround. You can also add pull requests
to bug reports at http://bugs.php.net/.
If you are not using GitHub, attach your patch to a PHP bug and
consider sending a notification email about the change to
internals@lists.php.net. If the bug is for an extension, 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.
With this CVS setting, you don't have to worry about adding/deleting
newlines and spaces.
Check list for submitting patch
-------------------------------
- Did you run "make test" to check if your patch didn't break
other features?
- Did you compile PHP with --enable-debug and check php/webserver
error logs when you test your patch?
- Did you build PHP for multi-threaded web servers. (Optional)
- Did you create test script for "make test"? (Recommended)
- Did you check your patch is unified format and it does not
contain white space changes? (If you are not using recommended
cvs setting)
- Did you update CVS source before you take final patch?
- Did you read the patch again?
PHP Documentation Patches
Where to send your patch?
-------------------------
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 you are patching C source, send the patch to php-dev@lists.php.net.
If you are patching a module, you should also send the patch to the
maintainer. Official module maintainers are listed in EXTENSION file
in source.
If your change is large, then first discuss it with the mail list
phpdoc@lists.php.net. Subscription is explained on
http://php.net/mailing-lists.php.
If you are patching PEAR, send the patch to pear-dev@lists.php.net.
Information on contributing to PHP documentation is at
http://php.net/dochowto and http://wiki.php.net/doc/howto
Please add the prefix "[PATCH]" to your email subject and make sure
to include the patch as a MIME attachment even if it is short.
Test scripts should be included in the same email.
Explain what has been fixed/added/changed by your patch.
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.
Finally, add the bug Id(s) which can be closed by your patch, if any.
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://bugs.php.net/. A bug
can be used to track the patch progress and prevent your changes
getting lost in the PHP mail archives.
What happens after you submit your patch
--------------------------------------
If your patch is easy to review and has obviously no side-effects,
it might take up to a few hours until someone commits it.
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
Because this is a volunteer-driven effort, more complex patches will
require more patience on your side.
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.
If you did not receive any feedback in a few days, please consider
resubmitting the description of your patch, along-side with
these questions:
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.
- Is my patch too hard to review? Because of which factors?
- Should I split it up in multiple parts?
- Are there any unwanted whitespace changes?
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
What happens when your patch is applied?
----------------------------------------
Your name will be included together with your email address in the CVS
commit log. If your patch affects end-users, a brief description
and your name might be added to the NEWS file.
How to create your PHP, PHP Documentation or PECL patch
-------------------------------------------------------
PHP and most PECL packages use Git for revision control. Some PECL
packages use Subversion (SVN) Read http://www.php.net/git.php for help
on using Git to get and build PHP source code. We recommend to look
at our workflow on https://wiki.php.net/vcs/gitworkflow and our FAQ
https://wiki.php.net/vcs/gitfaq.
Generally we ask that bug fix patches work on the current stable PHP
development branches and on "master". New PHP features only need to
work on "master".
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:
git 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 git 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 Git 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!
Thank you for submitting patch for PHP!
+107 -248
View File
@@ -1,20 +1,11 @@
[IMPORTANT NOTICE]
------------------
Failed tests usually indicate a problem with your local system setup
and not within PHP itself (at least for official PHP release versions).
You may decide to automatically 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 :-)
Do _not_ ask to developers why some or all tests are failed under
your environment! Let us know if you find why it fails. Thank you.
[Testing Basics]
[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.
@@ -23,24 +14,22 @@ 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:
under source root. Therefore you can execute the script
as follows
./sapi/cli/php -c /path/to/php.ini/ run-tests.php [ext/some_extension_name]
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
"make test" executes "run-tests.php" script with "php" 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.
If PHP is not build with CGI SAPI, "run-tests.php" script uses CLI
SAPI. Tests that may not executed by CLI SAPI will be skipped.
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.
@@ -48,123 +37,128 @@ 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.
"make test" force to use php.ini-dist as default config file. If
you would like to test with other configuration file, user
"run-tests.php" script.
Example:
./sapi/cli/php -c /path/to/php.ini/ ext/standard
If you use php.ini other than php.ini-dist, you may see more failed
tests.
[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 'SKIPIF' 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.
"run-tests.php" ("make test") executes all test scripts by default
by looking all directory named "tests". If there are files have "phpt"
extension, "run-tests.php" takes test php code from the file and
executes it.
Tester can easily execute tests selectively with as follows.
Tester can easily executes tests selectively with as follows.
Examples:
./sapi/cli/php run-tests.php ext/mbstring/*
./sapi/cli/php run-tests.php ext/mbstring/020.phpt
Example:
./sapi/cli/php -c /path/to/php.ini/ run-tests.php ext/mbstring
[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:
Test results are printed to standard output. If there is a failed test,
"run-tests.php" script saves the result, expected result and code
executed to the test script directory. For example, if
ext/myext/tests/myext.phpt is failed to pass, 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)
ext/myext/tests/myext.out - output from test script
ext/myext/tests/myext.exp - expected output
ext/myext/tests/myext.php - test script executed
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/php7
MYMAIL=qa-test@domain.com
TMPDIR=/var/tmp
TODAY=`date +"%Y%m%d"`
# Make sure compilation environment 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.
Tester can verify these files, if failed test is actually a bug
or not.
[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
Writing test file is very easy if you are used to PHP. Test file
has following format. Here is a actual test file from iconv module.
===== ext/iconv/002.phpt =======
--TEST--
UCS4BE to ASCII
--SKIPIF--
<?php include('skipif.inc'); ?>
--POST--
--GET--
--FILE--
<?php include('002.inc'); ?>
--EXPECT--
&#97;&#98;&#99;&#100;
abcd
===== end of ext/iconv/002.phpt =======
"--TEST--" is title of the test.
"--SKIPIF--" is condition when to skip this test.
"--POST--" is POST variable passed to test script.
"--GET--" is GET variable passed to test script.
"--FILE--" is the test script.
"--EXPECT--" is the expected output from the test script.
ext/iconv/002.phpt uses 2 files. "skipif.inc" is used to skip
test when test cannot be performed such as iconv module is not
compiled or loaded.
==== ext/iconv/skipif.inc ====
<?php
// This script prints "skip" if condition does not meet.
if (!extension_loaded("iconv") && ini_get("enable_dl")) {
$dlext = (substr(PHP_OS, 0, 3) == "WIN") ? ".dll" : ".so";
@dl("iconv$dlext");
}
if (!extension_loaded("iconv")) {
die("skip\n");
}
?>
==== end of ext/iconv/skipif.inc ====
ext/inconv/002.inc is the test script. "run-tests.php" script
executes test script with CGI executable.
==== ext/iconv/002.inc ===
<?php
/*
Expected output:
&#97;&#98;&#99;&#100;
abcd
*/
$s = unpack("V*", iconv("ascii","UCS-4LE", "abcd"));
foreach($s as $c) { print "&#$c;"; } print "\n";
$s = pack("NNNN", 97, 98, 99, 100);
$q = iconv("UCS-4BE", "ascii", $s);
print $q; print "\n";
?>
=== end of ext/iconv/002.inc ===
Test script and skipif code may be directly write into *.phpt.
However, it is recommended to use other files for ease of writing
test script. For instance, you can execute test script under
ext/iconv as follows:
./sapi/cli/php -c /path/to/php.ini/ ext/iconv
[How to help us]
----------------
If you find bug in PHP, you can submit bug report AND test script
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.
@@ -179,138 +173,3 @@ $str = "XYZABCD";
echo substr($str,3,7);
?>
[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 accessible 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 equivalent 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 initial 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
+4 -4
View File
@@ -2,7 +2,7 @@ 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
- supports seperate 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
@@ -50,8 +50,8 @@ 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.
modules, two in C and one in C++. And dependending on the user's
wishes, the extension will even be built as a dynamic module.
The full syntax:
@@ -108,7 +108,7 @@ module, program, etc).
For example for APXS:
PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php7.c php_apache.c)
PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php4.c php_apache.c)
-5
View File
@@ -1,5 +0,0 @@
The Win32 Build System.
See https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2
vim:tw=78:sw=1:ts=1:et
+126
View File
@@ -0,0 +1,126 @@
Using PHP4 with the Zeus Web Server
-----------------------------------
Zeus fully supports running PHP in combination with our
webserver. There are three different interfaces that can be used to
enable PHP:
* CGI
* ISAPI
* FastCGI
Of the three, we recommend using FastCGI, which has been tested and
benchmarked as providing the best performance and reliability.
Full details of how to install PHP are available from our
website, at:
http://support.zeus.com/products/php.html
If you have any problems, please check the support site for more
up-to-date information and advice.
Quick guide to installing FastCGI with Zeus
-------------------------------------------
Step 1 - obtain and install FastCGI development kit.
Grab the package from:
http://www.fastcgi.com/dist/devkit_2.2.0.tar.gz
Extract the package and follow the instructions:
./configure
make
make export
(run the last as root)
This will install to /usr/local/lib/libfcgi.a
and /usr/local/include/*fcgi*
Step 2 - Compile PHP as FastCGI.
Compile as follows:
./configure --with-fastcgi
make
Note that PHP has many options to the configure script -
e.g. --with-mysql. You will probably want to select your usual options
before compiling; the above is just a bare minimum, for illustration.
After compilation finishes, you will be left with an executable
program called 'php'. Copy this into your document root, under a
dedicated FastCGI directory (e.g. $DOCROOT/fcgi-bin/php)
Step 3 - configure Zeus
Four stages:
- enable FastCGI
- configure FastCGI
- setup alias for FastCGI
- setup alias for PHP
1) Using the admin server, go to the 'module configuration' page for
your virtual server, and ensure that 'fastcgi' is enabled (select the
tickbox to the left).
2) While we can run FastCGI's locally, there are known problems with
some OS's (specifically, the communication between web server and
FastCGI happens over a unix domain socket, and some OS's have trouble
sustaining high connection rates over these sockets). So instead, we
are going to set up the PHP FastCGI to run 'remotely' over localhost
(this uses TCP sockets, which do not suffer this problem). Go to the
'fastcgi configuration' page, and under 'add remote fastcgi':
Add Remote FastCGI
Docroot path /fcgi-bin/php
Remote machine localhost:8002
The first entry is where you saved PHP, above.
The second entry is localhost:<any unused port>
We will start the FastCGI listening on this port shortly.
Click 'update' to commit these changes.
3) Go to the path mapping module and add an alias for FastCGI:
Add Alias
Docroot path /fcgi-bin
Filesystem directory /path/to/docroot/fcgi-bin
Alias type fastcgi
Click 'update' to commit these changes
4) Also on the path mapping module, add a handler for PHP:
Add handler
File extension php
Handler /fcgi-bin/php
Click 'update' to commit these changes
Finally restart your virtual server for these changes to take effect.
Step 4 - start PHP as a FastCGI runner
When you start PHP, it will pre-fork a given number of child processes
to handle incoming PHP requests. Each process will handle a given
number of requests before exiting (and being replaced by a newly
forked process). You can control these two parameters by setting the
following environment variables BEFORE starting the FastCGI runner:
PHP_FCGI_CHILDREN - the number of child processes to pre-fork. If not
set, defaults to 8.
PHP_FCGI_MAX_REQUESTS - the number of requests each PHP child process
handles before exiting. If not set, defaults to 500.
To start the FastCGI runner, execute '$ZEUSHOME/web/bin/fcgirunner
8002 $DOCROOT/fcgi-bin/php'. Substitute the appropriate values for
$ZEUSHOME and $DOCROOT; also substitute for 8002 the port you chose,
above.
To stop the runner (e.g. to experiment with the above environment
variables) you will need to manually stop and running PHP
processes. (Use 'ps' and 'kill'). As it is PHP which is forking lots
of children and not the runner, Zeus unfortunately cannot keep track
of what processes are running, sorry. A typical command line may look
like 'ps -efl | grep $DOCROOT/fcgi-bin/php | grep -v grep | awk
'{print $4}' | xargs kill'
-182
View File
@@ -1,182 +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_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);
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, "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;
}
}
-39
View File
@@ -1,39 +0,0 @@
The PHP Interpreter
===================
This is the github mirror of the official PHP repository located at
https://git.php.net.
[![Build Status](https://secure.travis-ci.org/php/php-src.svg?branch=master)](http://travis-ci.org/php/php-src)
[![Build status](https://ci.appveyor.com/api/projects/status/meyur6fviaxgdwdy?svg=true)](https://ci.appveyor.com/project/php/php-src)
Pull Requests
=============
PHP accepts pull requests via github. Discussions are done on github, but
depending on the topic can also be relayed to the official PHP developer
mailing list internals@lists.php.net.
New features require an RFC and must be accepted by the developers.
See https://wiki.php.net/rfc and https://wiki.php.net/rfc/voting for more
information on the process.
Bug fixes **do not** require an RFC, but require a bugtracker ticket. Always
open a ticket at https://bugs.php.net and reference the bug id using #NNNNNN.
Fix #55371: get_magic_quotes_gpc() throws deprecation warning
After removing magic quotes, the get_magic_quotes_gpc function caused
a deprecate warning. get_magic_quotes_gpc can be used to detected
the magic_quotes behavior and therefore should not raise a warning at any
time. The patch removes this warning
We do not merge pull requests directly on github. All PRs will be
pulled and pushed through https://git.php.net.
Guidelines for contributors
===========================
- [CODING_STANDARDS](/CODING_STANDARDS)
- [README.GIT-RULES](/README.GIT-RULES)
- [README.MAILINGLIST_RULES](/README.MAILINGLIST_RULES)
- [README.RELEASE_PROCESS](/README.RELEASE_PROCESS)
+170
View File
@@ -0,0 +1,170 @@
Things to do or at least think about doing in the future. Name in
parenthesis means that person has taken on this project.
Zend
----
For PHP 4.3.0:
* Allow foreach ($array as $k => &$val) syntax. right now we cannot
traverse an array without copying each element.
* Allow foreach ($array as $k => list($a, $b)) syntax for multi
dimensional arrays.
* Look at replacing c-lib call tolower().
* Make hash API functions work with HASH_OF() to save time.
* Allow to set a default value for call-by-reference-parameters.
eg: function hello (&$pallo = NULL) {}
* Disallow function(method) redefinition in class.
* Add configure test to determine if dlsym() requires underscore and set
DLSYM_NEEDS_UNDERSCORE accordingly. Perl and zsh have it in configure,
for example. (DONE?)
For PHP 5.0.0:
* Native large number support (probably with GNU GMP)
* Const'ify APIs. Right now, many functions leave parameters untouched,
but don't declare those as const. This makes interaction with other
interfaces difficult which pass const parameters to us.
global
------
For PHP 4.3.0:
* Add aliases to functions to conform to new naming conventions, e.g.
str_to_upper().
* Make all extensions thread-safe.
* Make everything on the language-level independent of your locale
settings.
* Change PHP error messages, so that they point to pages or sections
in the PHP Manual.
* Make sure that all ZTS globals get destructed. Most ts_allocate_id()
calls should have a dtor entry.
* Activate all extensions by default that don't rely on external
dependencies. (eg ftp) (DONE?)
* on some platforms unimplemented function will just do nothing
(e.g. symlink) they should print a warning or not even be defined!
(DONE ?)
* Use arg_separator.input to implode args in the CGI sapi extension
and arg_separator.input to explode in php_build_argv(). (DONE?)
* Change the odbc_fetch_into() function to require ALWAYS the first two
parameters ($conn_id and $array), and make the third (row) be optional.
* Remove --with-openlink configure option (--with-iodbc replaces it).
* Implement flush feature suitable for nested output buffers.
For PHP 5.0.0
* bundle and use curl lib for fopen wrapper.
* --enable-all in configure. (--enable-shared=max ...)
* make configure print out a summary when it's done (like XEmacs)
* replace standard functions which work on static data with
reentrancy-safe functions (DONE?).
* make SAPI conform to CGI/1.1. Currently, all SAPI modules
define REMOTE_ADDR etc. themselves and reach only various level
of compliance.
* see what functions might need to be changed to use HashPosition, so
that the internal array pointer is not affected.
* Move most extensions and PEAR packages out of the PHP CVS tree,
include them again during release packaging.
Other
* use thread-safe resolver functions (either require BIND 8 or adns).
* implement javadoc based function docs template system.
* provide optional IPv6 support.
* find a better way to implement script timeouts. SIGVTALRM is used
by some POSIX threads implementations (i.e. OpenBSD) and is not
available in ZTS mode.
documentation
-------------
* Add remarks in the documentation which functions are not implemented
on win32.
* Add remarks in the documentation which functions are not binary-safe.
* Update curl documentation (DONE?)
* Add developer documentation.
* Add detailed documentation for Java extension.
ext/bz2
-------
* Add ini setting for decompression buffer size. The default 4k is to small
for big files and takes ages to decompress. However, 40k which perform
quite good with big files may be to much under certain environments as
default setting. There should be consideren different default sizes for
different SAPIS (e.g. apache and cli).
ext/curl
--------
* Have a warning scheme for when people use unsupported features.
ext/oci8
--------
* All OCIFetch*() functions should return 0 for no more data and false on
error.
* Have a flag that trims trailing spaces from CHAR fields on retrieval.
* Make allow_call_time_pass_reference=Off working.
* For additional todo information, see oci8.c, in ext/oci8
ext/pcre
--------
* Allow user to set PCRE_NOTEMPTY, PCRE_ANCHORED at execution time, maybe
ext/pcntl
---------
* Change internal callback handler to use TICKS
* Remove all zend_extension code
* Add object callback support to pcntl_signal()
ext/pgsql
---------
For PHP 4.3.0:
* Add pg_metadata() with metadata cache feature.
* Add pg_convert() to check and convert array value for query.
* Add pg_insert/pg_update/pg_delete/pg_select for simple query.
ext/session
-----------
For PHP 4.3.0:
* session_abort() to abort session. ie: Do not save session data.
* Allow unset($_SESSION) or unset($HTTP_SESSION_VARS) to unset
session vars regardless of register_globals setting.
Other:
* Maybe implement finer-grained session variables that could be
locked individually.
* Write a network-transparent storage back-end with fallover
facilities
* Provide a callback facility which is executed upon encountering
an unknown class name during deserialization
ext/sockets
-----------
* Implement IPv6
* Review/Fix vectors
ext/standard
------------
* Add a version number to data serialized via serialize().
* Possibly modify parsing of GPC data to automatically create arrays if
variable name is seen more than once.
* Implement regex-cache for url-functions.
* stri_replace(). (Andrei)
* Move socket related functions to fsock.c.
* NOT binary safe:
strtok()
basename()
dirname()
strrpos()
strrchr()
strip_tags()
ext/wddx
--------
* See if we can support the remaining data types:
dateTime
binary
http://www.wddx.org/WDDX_SDK_10a/7__References/WDDX_DTD.htm
(Andrei)
* implement wddx_packet_as_javascript(). (Andrei)
other cool stuff
----------------
* PVM extension
+3
View File
@@ -0,0 +1,3 @@
- clean up .cvsignores
- purge Makefile.ins and replace PHP_EXTENSION in config.m4s
with appropiate calls to PHP_NEW_EXTENSION
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 1999-2006, Andi Gutmans, Sascha Schumann, Zeev Suraski.
Copyright (c) 1999, 2000, Andi Gutmans, Sascha Schumann, Zeev Suraski.
All rights reserved.
Redistribution and use in source and binary forms, with or without
+1 -1
View File
@@ -1,6 +1,6 @@
## 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
libtsrm_la_SOURCES = TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c
depend:
+2
View File
@@ -0,0 +1,2 @@
- Improve the lock in ts_resource_ex() in order to cover less code.
This can probably be done by more careful hash table access
+126 -331
View File
@@ -2,11 +2,11 @@
+----------------------------------------------------------------------+
| Thread Safe Resource Manager |
+----------------------------------------------------------------------+
| Copyright (c) 1999-2011, Andi Gutmans, Sascha Schumann, Zeev Suraski |
| Copyright (c) 1999, 2000, 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@php.net> |
| Authors: Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
@@ -15,6 +15,7 @@
#ifdef ZTS
#include <stdio.h>
#include <stdlib.h>
#if HAVE_STDARG_H
#include <stdarg.h>
@@ -22,10 +23,6 @@
typedef struct _tsrm_tls_entry tsrm_tls_entry;
#if defined(TSRM_WIN32)
/* TSRMLS_CACHE_DEFINE; is already done in Zend, this is being always compiled statically. */
#endif
struct _tsrm_tls_entry {
void **storage;
int count;
@@ -38,7 +35,6 @@ typedef struct {
size_t size;
ts_allocate_ctor ctor;
ts_allocate_dtor dtor;
int done;
} tsrm_resource_type;
@@ -55,9 +51,8 @@ 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 = NULL;
static tsrm_thread_end_func_t tsrm_new_thread_end_handler = NULL;
static tsrm_shutdown_func_t tsrm_shutdown_handler = NULL;
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, ...);
@@ -85,7 +80,7 @@ static FILE *tsrm_error_file;
} \
}
#else
#define TSRM_ERROR(args)
#define TSRM_ERROR
#define TSRM_SAFE_RETURN_RSRC(array, offset, range) \
if (offset==0) { \
return &array; \
@@ -94,41 +89,21 @@ static FILE *tsrm_error_file;
}
#endif
#if defined(GNUPTH)
static pth_key_t tls_key;
# define tsrm_tls_set(what) pth_key_setdata(tls_key, (void*)(what))
# define tsrm_tls_get() pth_key_getdata(tls_key)
#elif defined(PTHREADS)
#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)
#else
# define tsrm_tls_set(what)
# define tsrm_tls_get() NULL
# warning tsrm_set_interpreter_context is probably broken on this platform
#endif
TSRM_TLS uint8_t in_main_thread = 0;
/* 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();
pth_key_create(&tls_key, 0);
#elif defined(PTHREADS)
pthread_key_create( &tls_key, 0 );
#elif defined(TSRM_ST)
@@ -138,9 +113,6 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
tls_key = TlsAlloc();
#endif
/* ensure singleton */
in_main_thread = 1;
tsrm_error_file = stderr;
tsrm_error_set(debug_level, debug_filename);
tsrm_tls_table_size = expected_threads;
@@ -163,21 +135,18 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
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 (!in_main_thread) {
/* ensure singleton */
return;
}
if (tsrm_tls_table) {
for (i=0; i<tsrm_tls_table_size; i++) {
tsrm_tls_entry *p = tsrm_tls_table[i], *next_p;
@@ -186,13 +155,8 @@ TSRM_API void tsrm_shutdown(void)
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]);
}
free(p->storage[j]);
}
for (j=0; j<id_count; j++) {
free(p->storage[j]);
}
free(p->storage);
free(p);
@@ -215,23 +179,16 @@ TSRM_API void tsrm_shutdown(void)
#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
if (tsrm_shutdown_handler) {
tsrm_shutdown_handler();
}
tsrm_new_thread_begin_handler = NULL;
tsrm_new_thread_end_handler = NULL;
tsrm_shutdown_handler = NULL;
}/*}}}*/
}
/* 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));
@@ -244,21 +201,18 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
/* store the new resource type in the resource sizes table */
if (resource_types_table_size < id_count) {
tsrm_resource_type *_tmp;
_tmp = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
if (!_tmp) {
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 = _tmp;
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++) {
@@ -272,7 +226,7 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
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]);
resource_types_table[j].ctor(p->storage[j], &p->storage);
}
}
p->count = id_count;
@@ -284,64 +238,69 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
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 = NULL;
if (id_count > 0) {
(*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count);
}
(*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;
#if defined(PTHREADS)
/* Set thread local storage to this new thread resources structure */
tsrm_tls_set(*thread_resources_ptr);
pthread_setspecific(tls_key, (void *) *thread_resources_ptr);
#elif defined(TSRM_ST)
st_thread_setspecific(tls_key, (void *) *thread_resources_ptr);
#elif defined(TSRM_WIN32)
TlsSetValue(tls_key, (void *) *thread_resources_ptr);
#endif
if (tsrm_new_thread_begin_handler) {
tsrm_new_thread_begin_handler(thread_id);
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[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);
}
tsrm_mutex_unlock(tsmm_mutex);
}/*}}}*/
if (tsrm_new_thread_end_handler) {
tsrm_new_thread_end_handler(thread_id, &((*thread_resources_ptr)->storage));
}
}
/* 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;
if (!th_id) {
#if defined(PTHREADS)
/* 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();
thread_resources = pthread_getspecific(tls_key);
#elif defined(TSRM_ST)
thread_resources = st_thread_getspecific(tls_key);
#elif defined(TSRM_WIN32)
thread_resources = TlsGetValue(tls_key);
#else
thread_resources = NULL;
#endif
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.
@@ -387,71 +346,12 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
* changes to the structure as we read it.
*/
TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
}/*}}}*/
/* 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]);
}
}
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();
@@ -466,7 +366,7 @@ void ts_free_thread(void)
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]);
resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage);
}
}
for (i=0; i<thread_resources->count; i++) {
@@ -478,7 +378,11 @@ void ts_free_thread(void)
} else {
tsrm_tls_table[hash_value] = thread_resources->next;
}
tsrm_tls_set(0);
#if defined(PTHREADS)
pthread_setspecific(tls_key, 0);
#elif defined(TSRM_WIN32)
TlsSetValue(tls_key, 0);
#endif
free(thread_resources);
break;
}
@@ -488,87 +392,13 @@ void ts_free_thread(void)
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]);
}
}
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]);
}
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));
}/*}}}*/
{
}
@@ -579,152 +409,151 @@ void ts_free_id(ts_rsrc_id id)
/* Obtain the current thread id */
TSRM_API THREAD_T tsrm_thread_id(void)
{/*{{{*/
{
#ifdef TSRM_WIN32
return GetCurrentThreadId();
#elif defined(NETWARE)
return NXThreadGetId();
#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();
#endif
}/*}}}*/
}
/* Allocate a mutex */
TSRM_API MUTEX_T tsrm_mutex_alloc(void)
{/*{{{*/
MUTEX_T mutexp;
{
MUTEX_T mutexp;
#ifdef NETWARE
long flags = 0; /* Don't require NX_MUTEX_RECURSIVE, I guess */
NXHierarchy_t order = 0;
NX_LOCK_INFO_ALLOC (lockInfo, "PHP-TSRM", 0);
#endif
#ifdef TSRM_WIN32
mutexp = malloc(sizeof(CRITICAL_SECTION));
mutexp = malloc(sizeof(CRITICAL_SECTION));
InitializeCriticalSection(mutexp);
#elif defined(NETWARE)
mutexp = NXMutexAlloc(flags, order, &lockInfo); /* return value ignored for now */
#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();
#endif
#ifdef THR_DEBUG
printf("Mutex created thread: %d\n",mythreadid());
printf("Mutex created thread: %d\n",mythreadid());
#endif
return( mutexp );
}/*}}}*/
return( mutexp );
}
/* Free a mutex */
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
{/*{{{*/
if (mutexp) {
{
if (mutexp) {
#ifdef TSRM_WIN32
DeleteCriticalSection(mutexp);
free(mutexp);
#elif defined(NETWARE)
NXMutexFree(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);
#endif
}
}
#ifdef THR_DEBUG
printf("Mutex freed thread: %d\n",mythreadid());
printf("Mutex freed thread: %d\n",mythreadid());
#endif
}/*}}}*/
}
/*
Lock a mutex.
A return value of 0 indicates success
*/
/* Lock a mutex */
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;
return 1;
#elif defined(NETWARE)
return NXLock(mutexp);
#elif defined(GNUPTH)
if (pth_mutex_acquire(mutexp, 0, NULL)) {
return 0;
}
return -1;
return pth_mutex_acquire(mutexp, 0, NULL);
#elif defined(PTHREADS)
return pthread_mutex_lock(mutexp);
#elif defined(NSAPI)
return crit_enter(mutexp);
#elif defined(PI3WEB)
return PISync_lock(mutexp);
#elif defined(TSRM_ST)
return st_mutex_lock(mutexp);
#endif
}/*}}}*/
}
/*
Unlock a mutex.
A return value of 0 indicates success
*/
/* Unlock a mutex */
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;
return 1;
#elif defined(NETWARE)
return NXUnlock(mutexp);
#elif defined(GNUPTH)
if (pth_mutex_release(mutexp)) {
return 0;
}
return -1;
return pth_mutex_release(mutexp);
#elif defined(PTHREADS)
return pthread_mutex_unlock(mutexp);
#elif defined(NSAPI)
return crit_exit(mutexp);
#elif defined(PI3WEB)
return PISync_unlock(mutexp);
#elif defined(TSRM_ST)
return st_mutex_unlock(mutexp);
#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;
}/*}}}*/
}
TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler)
{/*{{{*/
void *retval = (void *) tsrm_shutdown_handler;
tsrm_shutdown_handler = shutdown_handler;
return retval;
}/*}}}*/
/*
* Debug support
@@ -732,7 +561,7 @@ TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler)
#if TSRM_DEBUG
int tsrm_error(int level, const char *format, ...)
{/*{{{*/
{
if (level<=tsrm_error_level) {
va_list args;
int size;
@@ -747,12 +576,12 @@ int tsrm_error(int level, const char *format, ...)
} else {
return 0;
}
}/*}}}*/
}
#endif
void tsrm_error_set(int level, char *debug_filename)
{/*{{{*/
{
tsrm_error_level = level;
#if TSRM_DEBUG
@@ -769,40 +598,6 @@ void tsrm_error_set(int level, char *debug_filename)
tsrm_error_file = stderr;
}
#endif
}/*}}}*/
TSRM_API void *tsrm_get_ls_cache(void)
{/*{{{*/
return tsrm_tls_get();
}/*}}}*/
TSRM_API uint8_t tsrm_is_main_thread(void)
{/*{{{*/
return in_main_thread;
}/*}}}*/
TSRM_API const char *tsrm_api_name(void)
{/*{{{*/
#if defined(GNUPTH)
return "GNU Pth";
#elif defined(PTHREADS)
return "POSIX Threads";
#elif defined(TSRM_ST)
return "State Threads";
#elif defined(TSRM_WIN32)
return "Windows Threads";
#else
return "Unknown";
#endif
}/*}}}*/
}
#endif /* ZTS */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
+186
View File
@@ -0,0 +1,186 @@
# 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
+32 -97
View File
@@ -2,59 +2,50 @@
+----------------------------------------------------------------------+
| Thread Safe Resource Manager |
+----------------------------------------------------------------------+
| Copyright (c) 1999-2011, Andi Gutmans, Sascha Schumann, Zeev Suraski |
| Copyright (c) 1999, 2000, 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@php.net> |
| 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>
/* #ifndef WIN32 */
#if !defined(WIN32) && !defined(NETWARE)
# include "tsrm_config.h"
#endif
#include "main/php_stdint.h"
#ifdef WIN32
# define TSRM_WIN32
#endif
#ifdef TSRM_WIN32
# ifdef TSRM_EXPORTS
# define TSRM_API __declspec(dllexport)
# define TSRM_API __declspec(dllexport)
# else
# define TSRM_API __declspec(dllimport)
# define TSRM_API __declspec(dllimport)
# endif
#elif defined(__GNUC__) && __GNUC__ >= 4
# define TSRM_API __attribute__ ((visibility("default")))
#else
# define TSRM_API
#endif
typedef intptr_t tsrm_intptr_t;
typedef uintptr_t tsrm_uintptr_t;
/* 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(NETWARE)
# include <nks/thread.h>
# include <nks/synch.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;
@@ -63,23 +54,28 @@ typedef int ts_rsrc_id;
#ifdef TSRM_WIN32
# define THREAD_T DWORD
# define MUTEX_T CRITICAL_SECTION *
#elif defined(NETWARE)
# define THREAD_T NXThreadId_t
# define MUTEX_T NXMutex_t *
#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
#endif
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
typedef void (*ts_allocate_ctor)(void *);
typedef void (*ts_allocate_dtor)(void *);
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
@@ -101,9 +97,6 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id);
/* 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);
@@ -113,9 +106,8 @@ TSRM_API void ts_free_id(ts_rsrc_id id);
#define TSRM_ERROR_LEVEL_CORE 2
#define TSRM_ERROR_LEVEL_INFO 3
typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id);
typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id);
typedef void (*tsrm_shutdown_func_t)(void);
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, ...);
@@ -127,55 +119,19 @@ 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);
TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_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);
TSRM_API void *tsrm_get_ls_cache(void);
TSRM_API uint8_t tsrm_is_main_thread(void);
TSRM_API const char *tsrm_api_name(void);
#if defined(__cplusplus) && __cplusplus > 199711L
# define TSRM_TLS thread_local
#else
# ifdef TSRM_WIN32
# define TSRM_TLS __declspec(thread)
# else
# define TSRM_TLS __thread
# endif
#endif
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
#define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx
#define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_get_ls_cache()
#define TSRMG(id, type, element) (TSRMG_BULK(id, type)->element)
#define TSRMG_BULK(id, type) ((type) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(id)])
#define TSRMG_STATIC(id, type, element) (TSRMG_BULK_STATIC(id, type)->element)
#define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)])
#define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE;
#define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL;
#define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache()
#define TSRMLS_CACHE _tsrm_ls_cache
/* BC only */
#define TSRMLS_D void
#define TSRMLS_DC
#define TSRMLS_C
#define TSRMLS_CC
#define TSRMLS_FETCH()
#define TSRMLS_FETCH() void ***tsrm_ls = (void ***) ts_resource_ex(0, NULL)
#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
}
@@ -184,18 +140,6 @@ TSRM_API const char *tsrm_api_name(void);
#else /* non ZTS */
#define TSRMLS_FETCH()
#define TSRMLS_FETCH_FROM_CTX(ctx)
#define TSRMLS_SET_CTX(ctx)
#define TSRMG_STATIC(id, type, element)
#define TSRMLS_CACHE_EXTERN()
#define TSRMLS_CACHE_DEFINE()
#define TSRMLS_CACHE_UPDATE()
#define TSRMLS_CACHE
#define TSRM_TLS
/* BC only */
#define TSRMLS_D void
#define TSRMLS_DC
#define TSRMLS_C
@@ -204,12 +148,3 @@ TSRM_API const char *tsrm_api_name(void);
#endif /* ZTS */
#endif /* TSRM_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
+1
View File
@@ -0,0 +1 @@
#undef PTHREADS
+3 -1
View File
@@ -1,3 +1,5 @@
AC_DEFUN([AM_SET_LIBTOOL_VARIABLE],[
AC_DEFUN(AM_SET_LIBTOOL_VARIABLE,[
LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
])
+7 -4
View File
@@ -4,6 +4,9 @@
# make -f build.mk
#
# Written by Sascha Schumann
#
# $Id$
LT_TARGETS = ltmain.sh ltconfig
@@ -27,14 +30,14 @@ $(LT_TARGETS):
$(makefile_in_files): $(makefile_am_files)
automake -a -i $(AMFLAGS) $(makefile_files)
aclocal.m4: configure.ac acinclude.m4
aclocal.m4: configure.in acinclude.m4
aclocal
$(config_h_in): configure.ac
# explicitly remove target since autoheader does not seem to work
$(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 $@
autoheader
configure: aclocal.m4 configure.ac
configure: aclocal.m4 configure.in
autoconf
-4
View File
@@ -1,4 +0,0 @@
// vim:ft=javascript
ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_win32.c");
ADD_FLAG("CFLAGS_BD_TSRM", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
-35
View File
@@ -1,35 +0,0 @@
dnl
dnl Minimalistic configure.ac 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_CONFIG_FILES([Makefile])
AC_OUTPUT
+31
View File
@@ -0,0 +1,31 @@
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)
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)
-196
View File
@@ -1,196 +0,0 @@
# ==================================================================================
# https://www.gnu.org/software/autoconf-archive/ax_func_which_gethostbyname_r.html
# ==================================================================================
#
# SYNOPSIS
#
# AX_FUNC_WHICH_GETHOSTBYNAME_R
#
# DESCRIPTION
#
# Determines which historical variant of the gethostbyname_r() call
# (taking three, five, or six arguments) is available on the system and
# defines one of the following macros accordingly:
#
# HAVE_FUNC_GETHOSTBYNAME_R_6
# HAVE_FUNC_GETHOSTBYNAME_R_5
# HAVE_FUNC_GETHOSTBYNAME_R_3
#
# as well as
#
# HAVE_GETHOSTBYNAME_R
#
# If used in conjunction with gethostname.c, the API demonstrated in
# test.c can be used regardless of which gethostbyname_r() is available.
# These example files can be found at
# http://www.csn.ul.ie/~caolan/publink/gethostbyname_r
#
# based on David Arnold's autoconf suggestion in the threads faq
#
# Originally named "AC_caolan_FUNC_WHICH_GETHOSTBYNAME_R". Rewritten for
# Autoconf 2.5x, and updated for 2.68 by Daniel Richard G.
#
# LICENSE
#
# Copyright (c) 2008 Caolan McNamara <caolan@skynet.ie>
# Copyright (c) 2008 Daniel Richard G. <skunk@iskunk.org>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 8
AC_DEFUN([AX_FUNC_WHICH_GETHOSTBYNAME_R], [
AC_LANG_PUSH([C])
AC_MSG_CHECKING([how many arguments gethostbyname_r() takes])
AC_CACHE_VAL([ac_cv_func_which_gethostbyname_r], [
################################################################
ac_cv_func_which_gethostbyname_r=unknown
#
# ONE ARGUMENT (sanity check)
#
# This should fail, as there is no variant of gethostbyname_r() that takes
# a single argument. If it actually compiles, then we can assume that
# netdb.h is not declaring the function, and the compiler is thereby
# assuming an implicit prototype. In which case, we're out of luck.
#
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <netdb.h>],
[
char *name = "www.gnu.org";
(void)gethostbyname_r(name) /* ; */
])],
[ac_cv_func_which_gethostbyname_r=no])
#
# SIX ARGUMENTS
# (e.g. Linux)
#
if test "$ac_cv_func_which_gethostbyname_r" = "unknown"; then
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <netdb.h>],
[
char *name = "www.gnu.org";
struct hostent ret, *retp;
char buf@<:@1024@:>@;
int buflen = 1024;
int my_h_errno;
(void)gethostbyname_r(name, &ret, buf, buflen, &retp, &my_h_errno) /* ; */
])],
[ac_cv_func_which_gethostbyname_r=six])
fi
#
# FIVE ARGUMENTS
# (e.g. Solaris)
#
if test "$ac_cv_func_which_gethostbyname_r" = "unknown"; then
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <netdb.h>],
[
char *name = "www.gnu.org";
struct hostent ret;
char buf@<:@1024@:>@;
int buflen = 1024;
int my_h_errno;
(void)gethostbyname_r(name, &ret, buf, buflen, &my_h_errno) /* ; */
])],
[ac_cv_func_which_gethostbyname_r=five])
fi
#
# THREE ARGUMENTS
# (e.g. AIX, HP-UX, Tru64)
#
if test "$ac_cv_func_which_gethostbyname_r" = "unknown"; then
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <netdb.h>],
[
char *name = "www.gnu.org";
struct hostent ret;
struct hostent_data data;
(void)gethostbyname_r(name, &ret, &data) /* ; */
])],
[ac_cv_func_which_gethostbyname_r=three])
fi
################################################################
]) dnl end AC_CACHE_VAL
case "$ac_cv_func_which_gethostbyname_r" in
three|five|six)
AC_DEFINE([HAVE_GETHOSTBYNAME_R], [1],
[Define to 1 if you have some form of gethostbyname_r().])
;;
esac
case "$ac_cv_func_which_gethostbyname_r" in
three)
AC_MSG_RESULT([three])
AC_DEFINE([HAVE_FUNC_GETHOSTBYNAME_R_3], [1],
[Define to 1 if you have the three-argument form of gethostbyname_r().])
;;
five)
AC_MSG_RESULT([five])
AC_DEFINE([HAVE_FUNC_GETHOSTBYNAME_R_5], [1],
[Define to 1 if you have the five-argument form of gethostbyname_r().])
;;
six)
AC_MSG_RESULT([six])
AC_DEFINE([HAVE_FUNC_GETHOSTBYNAME_R_6], [1],
[Define to 1 if you have the six-argument form of gethostbyname_r().])
;;
no)
AC_MSG_RESULT([cannot find function declaration in netdb.h])
;;
unknown)
AC_MSG_RESULT([can't tell])
;;
*)
AC_MSG_ERROR([internal error])
;;
esac
AC_LANG_POP
]) dnl end AC_DEFUN
+44 -3
View File
@@ -1,3 +1,44 @@
/* Keep this header for compatibility with external code, it's currently not
used anywhere in the core and there are no implementations in TSRM. */
#include "win32/readdir.h"
#ifndef READDIR_H
#define READDIR_H
/*
* Structures and types used to implement opendir/readdir/closedir
* on Windows 95/NT.
*/
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.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 {
long handle; /* _findfirst/_findnext handle */
short offset; /* offset into directory */
short finished; /* 1 if there are not more files */
struct _finddata_t 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 *);
void rewinddir(DIR *);
#endif /* READDIR_H */
+18 -23
View File
@@ -1,17 +1,17 @@
dnl Copyright (c) 1999, 2000 Sascha Schumann. All rights reserved.
dnl
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
dnl 1. Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl
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
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
@@ -30,7 +30,7 @@ dnl PTHREADS_FLAGS
dnl
dnl Set some magic defines to achieve POSIX threads conformance
dnl
AC_DEFUN([PTHREADS_FLAGS],[
AC_DEFUN(PTHREADS_FLAGS,[
if test -z "$host_alias" && test -n "$host"; then
host_alias=$host
fi
@@ -65,8 +65,8 @@ dnl PTHREADS_CHECK_COMPILE
dnl
dnl Check whether the current setup can use POSIX threads calls
dnl
AC_DEFUN([PTHREADS_CHECK_COMPILE], [
AC_LINK_IFELSE([ AC_LANG_SOURCE([
AC_DEFUN(PTHREADS_CHECK_COMPILE, [
AC_TRY_RUN( [
#include <pthread.h>
#include <stddef.h>
@@ -80,12 +80,11 @@ int main() {
int data = 1;
pthread_mutexattr_init(&mattr);
return pthread_create(&thd, NULL, thread_routine, &data);
} ]) ], [
pthreads_checked=yes
} ], [
pthreads_working=yes
], [
pthreads_checked=no
]
) ] )dnl
pthreads_working=no
], pthreads_working=no ) ] )dnl
dnl
dnl PTHREADS_CHECK()
dnl
@@ -97,11 +96,11 @@ 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 -pthreads gcc (Solaris)
dnl -qthreaded AIX cc V5
dnl -threads gcc (HP-UX)
dnl
AC_DEFUN([PTHREADS_CHECK],[
AC_DEFUN(PTHREADS_CHECK,[
save_CFLAGS=$CFLAGS
save_LIBS=$LIBS
@@ -113,12 +112,12 @@ 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
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_checked" = "yes"; then
if test "$pthreads_working" = "yes"; then
ac_cv_pthreads_cflags=$flag
break
fi
@@ -129,12 +128,12 @@ 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
for lib in pthread pthreads c_r; do
ac_save=$LIBS
LIBS="$LIBS -l$lib"
PTHREADS_CHECK_COMPILE
LIBS=$ac_save
if test "$pthreads_checked" = "yes"; then
if test "$pthreads_working" = "yes"; then
ac_cv_pthreads_lib=$lib
break
fi
@@ -142,10 +141,6 @@ if test "$pthreads_working" != "yes"; then
fi
])
if test "x$ac_cv_pthreads_cflags" != "x" -o "x$ac_cv_pthreads_lib" != "x"; then
pthreads_working="yes"
fi
if test "$pthreads_working" = "yes"; then
threads_result="POSIX-Threads found"
else
@@ -154,7 +149,7 @@ fi
])dnl
dnl
dnl
AC_DEFUN([PTHREADS_ASSIGN_VARS],[
AC_DEFUN(PTHREADS_ASSIGN_VARS,[
if test -n "$ac_cv_pthreads_lib"; then
LIBS="$LIBS -l$ac_cv_pthreads_lib"
fi
+34 -16
View File
@@ -1,6 +1,27 @@
m4_include([TSRM/m4/ax_func_which_gethostbyname_r.m4])
AC_DEFUN([TSRM_BASIC_CHECKS],[
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
@@ -9,14 +30,10 @@ AC_REQUIRE([AC_PROG_RANLIB])dnl
AC_CHECK_HEADERS(stdarg.h)
AC_CHECK_FUNCS(sigprocmask)
AX_FUNC_WHICH_GETHOSTBYNAME_R()
])
AC_DEFUN([TSRM_CHECK_PTH],[
AC_DEFUN(TSRM_CHECK_PTH,[
AC_MSG_CHECKING(for GNU Pth)
PTH_PREFIX="`$1 --prefix`"
@@ -33,7 +50,7 @@ AC_MSG_RESULT(yes - installed in $PTH_PREFIX)
])
AC_DEFUN([TSRM_CHECK_ST],[
AC_DEFUN(TSRM_CHECK_ST,[
if test -r "$1/include/st.h"; then
CPPFLAGS="$CPPFLAGS -I$1/include"
LDFLAGS="$LDFLAGS -L$1/lib"
@@ -51,36 +68,37 @@ AC_DEFUN([TSRM_CHECK_ST],[
])
sinclude(threads.m4)
sinclude(TSRM/threads.m4)
AC_DEFUN([TSRM_CHECK_PTHREADS],[
AC_DEFUN(TSRM_CHECK_PTHREADS,[
PTHREADS_CHECK
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)
])
AC_DEFUN([TSRM_THREADS_CHECKS],[
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],[
[ --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],[
[ --with-tsrm-st],[
TSRM_ST=$withval
],[
TSRM_ST=no
+9
View File
@@ -0,0 +1,9 @@
#ifndef TSRM_CONFIG_NW_H
#define TSRM_CONFIG_NW_H
#define HAVE_UTIME 1
/* Though we have alloca(), this seems to be causing some problem with the stack pointer -- hence not using it */
/* #define HAVE_ALLOCA 1 */
#endif
+7 -15
View File
@@ -1,23 +1,15 @@
#ifndef TSRM_CONFIG_W32_H
#define TSRM_CONFIG_W32_H
#include <../main/config.w32.h>
#include "Zend/zend_config.w32.h"
#define HAVE_UTIME 1
#define HAVE_ALLOCA 1
#include <malloc.h>
#include <stdlib.h>
#include <crtdbg.h>
#undef inline
#ifdef ZEND_WIN32_FORCE_INLINE
# define inline __forceinline
#else
# define inline
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
#endif
+16 -36
View File
@@ -1,28 +1,30 @@
#ifndef TSRM_CONFIG_COMMON_H
#define TSRM_CONFIG_COMMON_H
#ifndef __CYGWIN__
# ifdef _WIN32
# define TSRM_WIN32
# endif
#if WINNT|WIN32
# define TSRM_WIN32
#endif
#ifdef TSRM_WIN32
# include "tsrm_config.w32.h"
#elif defined(NETWARE)
# include "tsrm_config.nw.h"
#else
# include <tsrm_config.h>
# include "tsrm_config.h"
# include <sys/param.h>
#endif
#if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
# include <alloca.h>
#ifdef TSRM_WIN32
#include <malloc.h>
#endif
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# ifndef HAVE_ALLOCA_H
# if HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
@@ -40,41 +42,19 @@ char *alloca ();
#endif
#ifndef MAXPATHLEN
# if _WIN32
# include "win32/ioutil.h"
# define MAXPATHLEN PHP_WIN32_IOUTIL_MAXPATHLEN
# elif PATH_MAX
# 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)
# define tsrm_do_alloca(p) alloca(p)
# define tsrm_free_alloca(p)
#else
# define TSRM_ALLOCA_FLAG(name)
# define tsrm_do_alloca(p, use_heap) malloc(p)
# define tsrm_free_alloca(p, use_heap) free(p)
# define tsrm_do_alloca(p) malloc(p)
# define tsrm_free_alloca(p) free(p)
#endif
#endif /* TSRM_CONFIG_COMMON_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
+260
View File
@@ -0,0 +1,260 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2002 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.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> |
+----------------------------------------------------------------------+
*/
/* $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 : Venkat (30/4/02) */
#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);
/*consoleprintf ("PHP | popen: file path = %s, mode = %s\n", filePath, type);*/
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);
/*consoleprintf ("PHP | popen: pipe_open() returned %d\n", pipe_handle);*/
if (pipe_handle == -1)
return NULL;
#elif defined(USE_MKFIFO)
pipe_handle = mkfifo(filePath, mode);
consoleprintf ("PHP | popen: mkfifo() returned %d\n", pipe_handle);
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);
/*consoleprintf ("PHP | popen: NXFifoOpen() returned %d\n", err);*/
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);
consoleprintf ("PHP | popen: NXCopyEnv() returned %d\n", err);
if (err)
{
NXMemFree (env);
return NULL;
}
/* Separate commandline string into words */
consoleprintf ("PHP | popen: commandline = %s\n", commandline);
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);
}
consoleprintf ("PHP | popen: commandline string parsed into tokens\n");
/* 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;
/*
envSpec.esStdin.ssHandle =
envSpec.esStdout.ssHandle =
envSpec.esStderr.ssHandle = -1;
*/
envSpec.esStdin.ssPathCtx =
envSpec.esStdout.ssPathCtx =
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; */ /* Not used */
nameSpec.ssPathCtx = NULL; /* Not used */
nameSpec.ssPath = argv[0];
consoleprintf ("PHP | popen: environment setup\n");
err = NXVmSpawn(&nameSpec, &envSpec, 0, &newVM);
consoleprintf ("PHP | popen: NXVmSpawn() returned %d\n", err);
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]);
}
consoleprintf ("PHP | popen: all clean-up done, returning...\n");
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
+28
View File
@@ -0,0 +1,28 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2002 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.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> |
+----------------------------------------------------------------------+
*/
#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
+6 -15
View File
@@ -4,7 +4,7 @@
#include "tsrm_strtok_r.h"
static inline int in_character_class(char ch, const char *delim)
{/*{{{*/
{
while (*delim) {
if (*delim == ch) {
return 1;
@@ -12,10 +12,10 @@ static inline int in_character_class(char ch, const char *delim)
delim++;
}
return 0;
}/*}}}*/
}
TSRM_API char *tsrm_strtok_r(char *s, const char *delim, char **last)
{/*{{{*/
char *tsrm_strtok_r(char *s, const char *delim, char **last)
{
char *token;
if (s == NULL) {
@@ -41,7 +41,7 @@ TSRM_API char *tsrm_strtok_r(char *s, const char *delim, char **last)
*last = s + 1;
}
return token;
}/*}}}*/
}
#if 0
@@ -56,17 +56,8 @@ main()
printf ("Token = '%s'\n", token);
token = tsrm_strtok_r(NULL, "/\\", &last);
}
return 0;
}
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
+1 -3
View File
@@ -1,8 +1,6 @@
#ifndef TSRM_STRTOK_R
#define TSRM_STRTOK_R
#include "TSRM.h"
TSRM_API char *tsrm_strtok_r(char *s, const char *delim, char **last);
char *tsrm_strtok_r(char *s, const char *delim, char **last);
#endif
+864
View File
@@ -0,0 +1,864 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2002 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.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> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include "tsrm_virtual_cwd.h"
#include "tsrm_strtok_r.h"
#ifdef TSRM_WIN32
#include <io.h>
#include "tsrm_win32.h"
#endif
#ifdef NETWARE
/*#include "pipe.h"*/
#include "tsrm_nw.h"
#endif
#define VIRTUAL_CWD_DEBUG 0
#include "TSRM.h"
/* Only need mutex for popen() in Windows and NetWare, because it doesn't chdir() on UNIX */
#if (defined(TSRM_WIN32) || defined(NETWARE)) && defined(ZTS)
MUTEX_T cwd_mutex;
#endif
#ifdef ZTS
static ts_rsrc_id cwd_globals_id;
#else
static virtual_cwd_globals cwd_globals;
#endif
cwd_state main_cwd_state; /* True global */
#ifndef TSRM_WIN32
#include <unistd.h>
#else
#include <direct.h>
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode) ((mode) & _S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(mode) ((mode) & _S_IFREG)
#endif
#ifdef TSRM_WIN32
#include <tchar.h>
#define tsrm_strtok_r(a,b,c) _tcstok((a),(b))
#define TOKENIZER_STRING "/\\"
static int php_check_dots(const char *element, int n)
{
while (n-- > 0) if (element[n] != '.') break;
return (n != -1);
}
#define IS_DIRECTORY_UP(element, len) \
(len >= 2 && !php_check_dots(element, len))
#define IS_DIRECTORY_CURRENT(element, len) \
(len == 1 && ptr[0] == '.')
#elif defined(NETWARE)
/* NetWare has strtok() (in LibC) and allows both slashes in paths, like Windows --
but rest of the stuff is like Unix */
/* strtok() call in LibC is abending when used in a different address space -- hence using
PHP's version itself for now */
/*#define tsrm_strtok_r(a,b,c) strtok((a),(b))*/
#define TOKENIZER_STRING "/\\"
#else
#define TOKENIZER_STRING "/"
#endif
/* default macros */
#ifndef IS_DIRECTORY_UP
#define IS_DIRECTORY_UP(element, len) \
(len == 2 && memcmp(element, "..", 2) == 0)
#endif
#ifndef IS_DIRECTORY_CURRENT
#define IS_DIRECTORY_CURRENT(element, len) \
(len == 1 && ptr[0] == '.')
#endif
/* define this to check semantics */
#define IS_DIR_OK(s) (1)
#ifndef IS_DIR_OK
#define IS_DIR_OK(state) (php_is_dir_ok(state) == 0)
#endif
#define CWD_STATE_COPY(d, s) \
(d)->cwd_length = (s)->cwd_length; \
(d)->cwd = (char *) malloc((s)->cwd_length+1); \
memcpy((d)->cwd, (s)->cwd, (s)->cwd_length+1);
#define CWD_STATE_FREE(s) \
free((s)->cwd);
static int php_is_dir_ok(const cwd_state *state)
{
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
struct stat buf;
if (stat(state->cwd, &buf) == 0 && S_ISDIR(buf.st_mode))
#else
struct stat_libc buf;
if (stat(state->cwd, (struct stat*)(&buf)) == 0 && S_ISDIR(buf.st_mode))
#endif
return (0);
return (1);
}
static int php_is_file_ok(const cwd_state *state)
{
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
struct stat buf;
if (stat(state->cwd, &buf) == 0 && S_ISREG(buf.st_mode))
#else
struct stat_libc buf;
if (stat(state->cwd, (struct stat*)(&buf)) == 0 && S_ISREG(buf.st_mode))
#endif
return (0);
return (1);
}
static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
{
CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state);
}
static void cwd_globals_dtor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
{
CWD_STATE_FREE(&cwd_globals->cwd);
}
static char *tsrm_strndup(const char *s, size_t length)
{
char *p;
p = (char *) malloc(length+1);
if (!p) {
return (char *)NULL;
}
if (length) {
memcpy(p,s,length);
}
p[length]=0;
return p;
}
CWD_API void virtual_cwd_startup(void)
{
char cwd[MAXPATHLEN];
char *result;
result = getcwd(cwd, sizeof(cwd));
if (!result) {
cwd[0] = '\0';
}
main_cwd_state.cwd = strdup(cwd);
main_cwd_state.cwd_length = strlen(cwd);
#ifdef ZTS
ts_allocate_id(&cwd_globals_id, sizeof(virtual_cwd_globals), (ts_allocate_ctor) cwd_globals_ctor, (ts_allocate_dtor) cwd_globals_dtor);
#else
cwd_globals_ctor(&cwd_globals TSRMLS_CC);
#endif
#if defined(TSRM_WIN32) && defined(ZTS)
cwd_mutex = tsrm_mutex_alloc();
#endif
}
CWD_API void virtual_cwd_shutdown(void)
{
#ifndef ZTS
cwd_globals_dtor(&cwd_globals TSRMLS_CC);
#endif
#if defined(TSRM_WIN32) && defined(ZTS)
tsrm_mutex_free(cwd_mutex);
#endif
free(main_cwd_state.cwd); /* Don't use CWD_STATE_FREE because the non global states will probably use emalloc()/efree() */
}
CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC)
{
cwd_state *state;
state = &CWDG(cwd);
if (state->cwd_length == 0) {
char *retval;
*length = 1;
retval = (char *) malloc(2);
retval[0] = DEFAULT_SLASH;
retval[1] = '\0';
return retval;
}
#ifdef TSRM_WIN32
/* If we have something like C: */
if (state->cwd_length == 2 && state->cwd[state->cwd_length-1] == ':') {
char *retval;
*length = state->cwd_length+1;
retval = (char *) malloc(*length+1);
memcpy(retval, state->cwd, *length);
retval[*length-1] = DEFAULT_SLASH;
retval[*length] = '\0';
return retval;
}
#endif
*length = state->cwd_length;
return strdup(state->cwd);
}
/* Same semantics as UNIX getcwd() */
CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC)
{
size_t length;
char *cwd;
cwd = virtual_getcwd_ex(&length TSRMLS_CC);
if (buf == NULL) {
return cwd;
}
if (length > size-1) {
free(cwd);
errno = ERANGE; /* Is this OK? */
return NULL;
}
memcpy(buf, cwd, length+1);
free(cwd);
return buf;
}
/* Resolve path relatively to state and put the real path into state */
/* returns 0 for ok, 1 for error */
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path)
{
int path_length = strlen(path);
char *ptr, *path_copy;
char *tok = NULL;
int ptr_length;
cwd_state *old_state;
int ret = 0;
int copy_amount = -1;
char *free_path;
unsigned char is_absolute = 0;
#ifndef TSRM_WIN32
char resolved_path[MAXPATHLEN];
#endif
if (path_length == 0)
return (0);
#if !defined(TSRM_WIN32) && !defined(__BEOS__) && !defined(NETWARE)
if (IS_ABSOLUTE_PATH(path, path_length)) {
if (realpath(path, resolved_path)) {
path = resolved_path;
path_length = strlen(path);
}
} else { /* Concat current directory with relative path and then run realpath() on it */
char *tmp;
char *ptr;
ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/"));
if (!tmp) {
return 1;
}
memcpy(ptr, state->cwd, state->cwd_length);
ptr += state->cwd_length;
*ptr++ = DEFAULT_SLASH;
memcpy(ptr, path, path_length);
ptr += path_length;
*ptr = '\0';
if (realpath(tmp, resolved_path)) {
path = resolved_path;
path_length = strlen(path);
}
free(tmp);
}
#endif
free_path = path_copy = tsrm_strndup(path, path_length);
old_state = (cwd_state *) malloc(sizeof(cwd_state));
CWD_STATE_COPY(old_state, state);
#if VIRTUAL_CWD_DEBUG
fprintf(stderr,"cwd = %s path = %s\n", state->cwd, path);
#endif
if (IS_ABSOLUTE_PATH(path_copy, path_length)) {
/* COPY_WHEN_ABSOLUTE needs to account for volume name that is unique to NetWare absolute paths */
#ifndef NETWARE
copy_amount = COPY_WHEN_ABSOLUTE;
#else
copy_amount = COPY_WHEN_ABSOLUTE(path_copy);
#endif
is_absolute = 1;
#ifdef TSRM_WIN32
} else if (IS_UNC_PATH(path_copy, path_length)) {
copy_amount = 2;
is_absolute = 1;
} else if (IS_SLASH(path_copy[0])) {
copy_amount = 2;
#endif
}
if (copy_amount != -1) {
state->cwd = (char *) realloc(state->cwd, copy_amount + 1);
if (copy_amount) {
if (is_absolute) {
memcpy(state->cwd, path_copy, copy_amount);
path_copy += copy_amount;
} else {
memcpy(state->cwd, old_state->cwd, copy_amount);
}
}
state->cwd[copy_amount] = '\0';
state->cwd_length = copy_amount;
}
ptr = tsrm_strtok_r(path_copy, TOKENIZER_STRING, &tok);
while (ptr) {
ptr_length = strlen(ptr);
if (IS_DIRECTORY_UP(ptr, ptr_length)) {
char save;
save = DEFAULT_SLASH;
#define PREVIOUS state->cwd[state->cwd_length - 1]
while (IS_ABSOLUTE_PATH(state->cwd, state->cwd_length) &&
!IS_SLASH(PREVIOUS)) {
save = PREVIOUS;
PREVIOUS = '\0';
state->cwd_length--;
}
if (!IS_ABSOLUTE_PATH(state->cwd, state->cwd_length)) {
state->cwd[state->cwd_length++] = save;
state->cwd[state->cwd_length] = '\0';
} else {
PREVIOUS = '\0';
state->cwd_length--;
}
} else if (!IS_DIRECTORY_CURRENT(ptr, ptr_length)) {
state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1+1);
#ifdef TSRM_WIN32
/* Windows 9x will consider C:\\Foo as a network path. Avoid it. */
if ((state->cwd[state->cwd_length-1]!='\\' && state->cwd[state->cwd_length-1]!='/') ||
IsDBCSLeadByte(state->cwd[state->cwd_length-2])) {
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
}
#elif defined(NETWARE)
/* If the token is a volume name, it will have colon at the end -- so, no slash before it */
if (ptr[ptr_length-1] != ':') {
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
}
#else
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
#endif
memcpy(&state->cwd[state->cwd_length], ptr, ptr_length+1);
state->cwd_length += ptr_length;
}
ptr = tsrm_strtok_r(NULL, TOKENIZER_STRING, &tok);
}
/* COPY_WHEN_ABSOLUTE needs to account for volume name that is unique to NetWare absolute paths */
#ifndef NETWARE
if (state->cwd_length == COPY_WHEN_ABSOLUTE) {
#else
if (state->cwd_length == COPY_WHEN_ABSOLUTE(state->cwd)) {
#endif
state->cwd = (char *) realloc(state->cwd, state->cwd_length+1+1);
state->cwd[state->cwd_length] = DEFAULT_SLASH;
state->cwd[state->cwd_length+1] = '\0';
state->cwd_length++;
}
if (verify_path && verify_path(state)) {
CWD_STATE_FREE(state);
*state = *old_state;
ret = 1;
} else {
CWD_STATE_FREE(old_state);
ret = 0;
}
free(old_state);
free(free_path);
#if VIRTUAL_CWD_DEBUG
fprintf (stderr, "virtual_file_ex() = %s\n",state->cwd);
#endif
return (ret);
}
CWD_API int virtual_chdir(const char *path TSRMLS_DC)
{
return virtual_file_ex(&CWDG(cwd), path, php_is_dir_ok)?-1:0;
}
CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path TSRMLS_DC) TSRMLS_DC)
{
int length = strlen(path);
char *temp;
int retval;
if (length == 0) {
return 1; /* Can't cd to empty string */
}
while(--length >= 0 && !IS_SLASH(path[length])) {
}
if (length == -1) {
/* No directory only file name */
errno = ENOENT;
return -1;
}
/* COPY_WHEN_ABSOLUTE needs to account for volume name that is unique to NetWare absolute paths */
#ifndef NETWARE
if (length == COPY_WHEN_ABSOLUTE && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */
#else
if (length == COPY_WHEN_ABSOLUTE(path) && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */
#endif
length++;
}
temp = (char *) tsrm_do_alloca(length+1);
memcpy(temp, path, length);
temp[length] = 0;
#if VIRTUAL_CWD_DEBUG
fprintf (stderr, "Changing directory to %s\n", temp);
#endif
retval = p_chdir(temp TSRMLS_CC);
tsrm_free_alloca(temp);
return retval;
}
CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC)
{
cwd_state new_state;
int retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
retval = virtual_file_ex(&new_state, path, NULL);
if (!retval) {
int len = new_state.cwd_length>MAXPATHLEN-1?MAXPATHLEN-1:new_state.cwd_length;
memcpy(real_path, new_state.cwd, len);
real_path[len] = '\0';
return real_path;
}
return NULL;
}
CWD_API int virtual_filepath_ex(const char *path, char **filepath, verify_path_func verify_path TSRMLS_DC)
{
cwd_state new_state;
int retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
retval = virtual_file_ex(&new_state, path, verify_path);
*filepath = new_state.cwd;
return retval;
}
CWD_API int virtual_filepath(const char *path, char **filepath TSRMLS_DC)
{
return virtual_filepath_ex(path, filepath, php_is_file_ok TSRMLS_CC);
}
CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC)
{
cwd_state new_state;
FILE *f;
if (path[0] == '\0') { /* Fail to open empty path */
return NULL;
}
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL);
f = fopen(new_state.cwd, mode);
CWD_STATE_FREE(&new_state);
return f;
}
#if HAVE_UTIME
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC)
{
cwd_state new_state;
int ret;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, filename, NULL);
ret = utime(new_state.cwd, buf);
CWD_STATE_FREE(&new_state);
return ret;
}
#endif
CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC)
{
cwd_state new_state;
int ret;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, filename, NULL);
ret = chmod(new_state.cwd, mode);
CWD_STATE_FREE(&new_state);
return ret;
}
#if !defined(TSRM_WIN32) && !defined(NETWARE)
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_DC)
{
cwd_state new_state;
int ret;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, filename, NULL);
ret = chown(new_state.cwd, owner, group);
CWD_STATE_FREE(&new_state);
return ret;
}
#endif
CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...)
{
cwd_state new_state;
int f;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL);
if (flags & O_CREAT) {
mode_t mode;
va_list arg;
va_start(arg, flags);
mode = (mode_t) va_arg(arg, int);
va_end(arg);
f = open(new_state.cwd, flags, mode);
} else {
f = open(new_state.cwd, flags);
}
CWD_STATE_FREE(&new_state);
return f;
}
CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC)
{
cwd_state new_state;
int f;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL);
f = creat(new_state.cwd, mode);
CWD_STATE_FREE(&new_state);
return f;
}
CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC)
{
cwd_state old_state;
cwd_state new_state;
int retval;
CWD_STATE_COPY(&old_state, &CWDG(cwd));
virtual_file_ex(&old_state, oldname, NULL);
oldname = old_state.cwd;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, newname, NULL);
newname = new_state.cwd;
retval = rename(oldname, newname);
CWD_STATE_FREE(&old_state);
CWD_STATE_FREE(&new_state);
return retval;
}
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC)
{
cwd_state new_state;
int retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL);
retval = stat(new_state.cwd, buf);
CWD_STATE_FREE(&new_state);
return retval;
}
#else
CWD_API int virtual_stat(const char *path, struct stat_libc *buf TSRMLS_DC)
{
cwd_state new_state;
int retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL);
retval = stat(new_state.cwd, (struct stat*)buf);
CWD_STATE_FREE(&new_state);
return retval;
}
#endif
#if !defined(TSRM_WIN32) && !defined(NETWARE)
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC)
{
cwd_state new_state;
int retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL);
retval = lstat(new_state.cwd, buf);
CWD_STATE_FREE(&new_state);
return retval;
}
#endif
CWD_API int virtual_unlink(const char *path TSRMLS_DC)
{
cwd_state new_state;
int retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL);
retval = unlink(new_state.cwd);
CWD_STATE_FREE(&new_state);
return retval;
}
CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC)
{
cwd_state new_state;
int retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, pathname, NULL);
#ifdef TSRM_WIN32
retval = mkdir(new_state.cwd);
#else
retval = mkdir(new_state.cwd, mode);
#endif
CWD_STATE_FREE(&new_state);
return retval;
}
CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC)
{
cwd_state new_state;
int retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, pathname, NULL);
retval = rmdir(new_state.cwd);
CWD_STATE_FREE(&new_state);
return retval;
}
#ifdef TSRM_WIN32
DIR *opendir(const char *name);
#endif
CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC)
{
cwd_state new_state;
DIR *retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, pathname, NULL);
retval = opendir(new_state.cwd);
CWD_STATE_FREE(&new_state);
return retval;
}
#ifdef TSRM_WIN32
/* On Windows the trick of prepending "cd cwd; " doesn't work so we need to perform
a real chdir() and mutex it
*/
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
{
char prev_cwd[MAXPATHLEN];
char *getcwd_result;
FILE *retval;
getcwd_result = getcwd(prev_cwd, MAXPATHLEN);
if (!getcwd_result) {
return NULL;
}
#ifdef ZTS
tsrm_mutex_lock(cwd_mutex);
#endif
chdir(CWDG(cwd).cwd);
retval = popen(command, type);
chdir(prev_cwd);
#ifdef ZTS
tsrm_mutex_unlock(cwd_mutex);
#endif
return retval;
}
#elif defined(NETWARE)
/* On NetWare, the trick of prepending "cd cwd; " doesn't work so we need to perform
a VCWD_CHDIR() and mutex it
*/
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
{
char prev_cwd[MAXPATHLEN];
char *getcwd_result;
FILE *retval;
getcwd_result = VCWD_GETCWD(prev_cwd, MAXPATHLEN);
if (!getcwd_result) {
return NULL;
}
#ifdef ZTS
tsrm_mutex_lock(cwd_mutex);
#endif
VCWD_CHDIR(CWDG(cwd).cwd);
retval = popen(command, type);
VCWD_CHDIR(prev_cwd);
#ifdef ZTS
tsrm_mutex_unlock(cwd_mutex);
#endif
return retval;
}
#else /* Unix */
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
{
int command_length;
char *command_line;
char *ptr;
FILE *retval;
command_length = strlen(command);
ptr = command_line = (char *) malloc(command_length + sizeof("cd ; ") + CWDG(cwd).cwd_length+1);
if (!command_line) {
return NULL;
}
memcpy(ptr, "cd ", sizeof("cd ")-1);
ptr += sizeof("cd ")-1;
if (CWDG(cwd).cwd_length == 0) {
*ptr++ = DEFAULT_SLASH;
} else {
memcpy(ptr, CWDG(cwd).cwd, CWDG(cwd).cwd_length);
ptr += CWDG(cwd).cwd_length;
}
*ptr++ = ' ';
*ptr++ = ';';
*ptr++ = ' ';
memcpy(ptr, command, command_length+1);
retval = popen(command_line, type);
free(command_line);
return retval;
}
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
+241
View File
@@ -0,0 +1,241 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2002 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.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> |
+----------------------------------------------------------------------+
*/
/* $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
#ifndef TSRM_WIN32
#include <unistd.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))))
#define COPY_WHEN_ABSOLUTE 2
#define IS_ABSOLUTE_PATH(path, len) \
(len >= 2 && isalpha(path[0]) && path[1] == ':')
#define IS_UNC_PATH(path, len) \
(len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1]))
#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 COPY_WHEN_ABSOLUTE(path) \
(strchr(path, ':') - path + 1) /* Take the volume name which ends with a colon */
#define IS_ABSOLUTE_PATH(path, len) \
(strchr(path, ':') != NULL) /* Colon indicates volume name */
#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 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
#else
#define CWD_API
#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);
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC);
#else
CWD_API int virtual_stat(const char *path, struct stat_libc *buf TSRMLS_DC);
#endif
#if !defined(TSRM_WIN32) && !defined(NETWARE)
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC);
#endif
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);
#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 TSRMLS_DC);
#endif
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path);
typedef struct _virtual_cwd_globals {
cwd_state cwd;
} virtual_cwd_globals;
#ifdef ZTS
# define CWDG(v) TSRMG(cwd_globals_id, virtual_cwd_globals *, v)
#else
# define CWDG(v) (cwd_globals.v)
#endif
/* 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)
#if !defined(TSRM_WIN32) && !defined(NETWARE)
#define VCWD_LSTAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
#else
#define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
#endif
#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)
#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 TSRMLS_CC)
#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)
#define VCWD_RENAME(oldname, newname) rename(oldname, newname)
#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) 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) && !defined(NETWARE)
#define VCWD_REALPATH(path, real_path) realpath(path, real_path)
#else
#define VCWD_REALPATH(path, real_path) strcpy(real_path, path)
#endif
#if HAVE_UTIME
#define VCWD_UTIME(path, time) utime(path, time)
#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)
#endif
#endif
#endif /* VIRTUAL_CWD_H */
+88 -560
View File
@@ -1,13 +1,13 @@
/*
+----------------------------------------------------------------------+
| PHP Version 7 |
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2018 The PHP Group |
| Copyright (c) 1997-2002 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| This source file is subject to version 2.02 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 |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.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. |
@@ -16,22 +16,20 @@
+----------------------------------------------------------------------+
*/
/* $Id$ */
#include <stdlib.h>
#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 <windows.h>
#include "tsrm_win32.h"
#include "zend_virtual_cwd.h"
#include "win32/ioutil.h"
#ifdef ZTS
static ts_rsrc_id win32_globals_id;
@@ -39,30 +37,17 @@ static ts_rsrc_id win32_globals_id;
static tsrm_win32_globals win32_globals;
#endif
static void tsrm_win32_ctor(tsrm_win32_globals *globals)
{/*{{{*/
#ifdef ZTS
TSRMLS_CACHE_UPDATE();
#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("cmd.exe");
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)
{/*{{{*/
static void tsrm_win32_dtor(tsrm_win32_globals *globals TSRMLS_DC)
{
shm_pair *ptr;
if (globals->process) {
@@ -80,329 +65,56 @@ static void tsrm_win32_dtor(tsrm_win32_globals *globals)
}
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);
tsrm_win32_ctor(&win32_globals TSRMLS_CC);
#endif
}/*}}}*/
}
TSRM_API void tsrm_win32_shutdown(void)
{/*{{{*/
{
#ifndef ZTS
tsrm_win32_dtor(&win32_globals);
tsrm_win32_dtor(&win32_globals TSRMLS_CC);
#endif
}/*}}}*/
}
char * tsrm_win32_get_path_sid_key(const char *pathname, size_t pathname_len, size_t *key_len)
{/*{{{*/
PSID pSid = TWG(impersonation_token_sid);
char *ptcSid = NULL;
char *bucket_key = NULL;
size_t ptc_sid_len;
if (!pSid) {
*key_len = pathname_len;
return pathname;
}
if (!ConvertSidToStringSid(pSid, &ptcSid)) {
*key_len = 0;
return NULL;
}
ptc_sid_len = strlen(ptcSid);
*key_len = pathname_len + ptc_sid_len;
bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *key_len + 1);
if (!bucket_key) {
LocalFree(ptcSid);
*key_len = 0;
return NULL;
}
memcpy(bucket_key, ptcSid, ptc_sid_len);
memcpy(bucket_key + ptc_sid_len, pathname, pathname_len + 1);
LocalFree(ptcSid);
return bucket_key;
}/*}}}*/
PSID tsrm_win32_get_token_sid(HANDLE hToken)
{/*{{{*/
DWORD dwLength = 0;
PTOKEN_USER pTokenUser = NULL;
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)
{/*{{{*/
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;
realpath_cache_bucket * bucket = NULL;
char real_path[MAXPATHLEN] = {0};
if(!IS_ABSOLUTE_PATH(pathname, strlen(pathname)+1)) {
if(tsrm_realpath(pathname, real_path) == NULL) {
SET_ERRNO_FROM_WIN32_CODE(ERROR_FILE_NOT_FOUND);
return -1;
}
pathname = real_path;
}
PHP_WIN32_IOUTIL_INIT_W(pathname)
if (!pathw) {
return -1;
}
/* Either access call failed, or the mode was asking for a specific check.*/
int ret = php_win32_ioutil_access_w(pathw, mode);
if (0 > ret || X_OK == mode || F_OK == mode) {
PHP_WIN32_IOUTIL_CLEANUP_W()
return ret;
}
/* 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)) {
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);
if(bucket == NULL && !real_path[0]) {
/* We used the pathname directly. Call tsrm_realpath */
/* so that entry is created in realpath cache */
if(tsrm_realpath(pathname, real_path) != NULL) {
pathname = real_path;
bucket = realpath_cache_lookup(pathname, strlen(pathname), t);
PHP_WIN32_IOUTIL_REINIT_W(pathname);
}
}
}
/* 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(GetFileSecurityW(pathw, sec_info, NULL, 0, &sec_desc_length)) {
goto Finished;
}
psec_desc = (BYTE *)malloc(sec_desc_length);
if(psec_desc == NULL ||
!GetFileSecurityW(pathw, 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);
}
PHP_WIN32_IOUTIL_CLEANUP_W()
if(fAccess == FALSE) {
errno = EACCES;
return errno;
} else {
return 0;
}
}/*}}}*/
static process_pair *process_get(FILE *stream)
{/*{{{*/
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(key_t key, void *addr)
{/*{{{*/
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;
@@ -417,111 +129,56 @@ static shm_pair *shm_get(key_t key, void *addr)
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)++;
memset(ptr, 0, sizeof(*ptr));
return ptr;
}/*}}}*/
}
static HANDLE dupHandle(HANDLE fh, BOOL inherit)
{/*{{{*/
static HANDLE dupHandle(HANDLE fh, BOOL inherit) {
HANDLE copy, self = GetCurrentProcess();
if (!DuplicateHandle(self, fh, self, &copy, 0, inherit, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE)) {
return NULL;
}
return copy;
}/*}}}*/
}
TSRM_API FILE *popen(const char *command, const char *type)
{/*{{{*/
return popen_ex(command, type, NULL, NULL);
}/*}}}*/
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env)
{/*{{{*/
{
FILE *stream = NULL;
int fno, type_len, read, mode;
STARTUPINFOW startup;
int fno, str_len = strlen(type), read, mode;
STARTUPINFO startup;
PROCESS_INFORMATION process;
SECURITY_ATTRIBUTES security;
HANDLE in, out;
DWORD dwCreateFlags = 0;
BOOL res;
char *cmd;
process_pair *proc;
char *cmd = NULL;
wchar_t *cmdw = NULL, *cwdw = NULL, *envw = NULL;
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 = (int)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++;
}
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c ")+2);
if (!cmd) {
return NULL;
}
sprintf(cmd, "%s /c \"%s\"", TWG(comspec), command);
cmdw = php_win32_cp_any_to_w(cmd);
if (!cmdw) {
free(cmd);
return NULL;
}
if (cwd) {
cwdw = php_win32_ioutil_any_to_w(cwd);
if (!cwdw) {
free(cmd);
free(cmdw);
return NULL;
}
}
TSRMLS_FETCH();
security.nLength = sizeof(SECURITY_ATTRIBUTES);
security.bInheritHandle = TRUE;
security.lpSecurityDescriptor = NULL;
if (!type_len || !CreatePipe(&in, &out, &security, 2048L)) {
free(cmdw);
free(cwdw);
free(cmd);
if (!str_len || !CreatePipe(&in, &out, &security, 2048L)) {
return NULL;
}
memset(&startup, 0, sizeof(STARTUPINFOW));
memset(&startup, 0, sizeof(STARTUPINFO));
memset(&process, 0, sizeof(PROCESS_INFORMATION));
startup.cb = sizeof(STARTUPINFOW);
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;
mode = ((str_len == 2) && (type[1] == 'b')) ? O_BINARY : O_TEXT;
if (read) {
in = dupHandle(in, FALSE);
@@ -533,56 +190,21 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd,
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;
}
}
envw = php_win32_cp_env_any_to_w(env);
if (envw) {
dwCreateFlags |= CREATE_UNICODE_ENVIRONMENT;
} else {
if (env) {
free(cmd);
free(cmdw);
free(cwdw);
return NULL;
}
}
if (asuser) {
res = CreateProcessAsUserW(token_user, NULL, cmdw, &security, &security, security.bInheritHandle, dwCreateFlags, envw, cwdw, &startup, &process);
CloseHandle(token_user);
} else {
res = CreateProcessW(NULL, cmdw, &security, &security, security.bInheritHandle, dwCreateFlags, envw, cwdw, &startup, &process);
}
free(cmd);
free(cmdw);
free(cwdw);
free(envw);
if (!res) {
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c "));
sprintf(cmd, "%s /c %s", TWG(comspec), command);
if (!CreateProcess(NULL, cmd, &security, &security, security.bInheritHandle, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &process)) {
return NULL;
}
free(cmd);
CloseHandle(process.hThread);
proc = process_get(NULL);
proc = process_get(NULL TSRMLS_CC);
if (read) {
fno = _open_osfhandle((tsrm_intptr_t)in, _O_RDONLY | mode);
fno = _open_osfhandle((long)in, _O_RDONLY | mode);
CloseHandle(out);
} else {
fno = _open_osfhandle((tsrm_intptr_t)out, _O_WRONLY | mode);
fno = _open_osfhandle((long)out, _O_WRONLY | mode);
CloseHandle(in);
}
@@ -590,19 +212,20 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd,
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)) == NULL) {
if ((process = process_get(stream TSRMLS_CC)) == NULL) {
return 0;
}
fflush(process->stream);
fclose(process->stream);
fclose(process->stream);
WaitForSingleObject(process->prochnd, INFINITE);
GetExitCodeProcess(process->prochnd, &termstat);
@@ -610,66 +233,45 @@ TSRM_API int pclose(FILE *stream)
CloseHandle(process->prochnd);
return termstat;
}/*}}}*/
}
TSRM_API int shmget(key_t key, size_t size, int flags)
{/*{{{*/
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;
snprintf(shm_segment, sizeof(shm_segment), "TSRM_SHM_SEGMENT:%d", key);
snprintf(shm_info, sizeof(shm_info), "TSRM_SHM_DESCRIPTOR:%d", key);
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 ((!shm_handle && !info_handle)) {
if (flags & IPC_EXCL) {
return -1;
}
if (flags & IPC_CREAT) {
#if SIZEOF_SIZE_T == 8
DWORD high = size >> 32;
DWORD low = (DWORD)size;
#else
DWORD high = 0;
DWORD low = size;
#endif
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, high, low, shm_segment);
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) {
if (shm_handle) {
CloseHandle(shm_handle);
}
if (info_handle) {
CloseHandle(info_handle);
}
return -1;
}
} else {
if (flags & IPC_EXCL) {
if (shm_handle) {
CloseHandle(shm_handle);
}
if (info_handle) {
CloseHandle(info_handle);
}
if ((!shm_handle || !info_handle)) {
return -1;
}
}
shm = shm_get(key, NULL);
if (!shm) {
CloseHandle(shm_handle);
CloseHandle(info_handle);
return -1;
}
shm->segment = shm_handle;
shm->info = info_handle;
shm->descriptor = MapViewOfFileEx(shm->info, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
if (NULL != shm->descriptor && created) {
if (created) {
shm->descriptor->shm_perm.key = key;
shm->descriptor->shm_segsz = size;
shm->descriptor->shm_ctime = time(NULL);
@@ -683,43 +285,35 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
shm->descriptor->shm_perm.mode = shm->descriptor->shm_perm.seq = 0;
}
if (NULL != shm->descriptor && (shm->descriptor->shm_perm.key != key || size > shm->descriptor->shm_segsz)) {
if (NULL != shm->segment) {
CloseHandle(shm->segment);
}
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->addr = MapViewOfFileEx(shm->segment, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
if (NULL == shm->addr) {
int err = GetLastError();
SET_ERRNO_FROM_WIN32_CODE(err);
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) {
@@ -731,10 +325,9 @@ TSRM_API int shmdt(const void *shmaddr)
shm->descriptor->shm_nattch--;
return UnmapViewOfFile(shm->addr) ? 0 : -1;
}/*}}}*/
}
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf)
{/*{{{*/
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf) {
shm_pair *shm = shm_get(key, NULL);
if (!shm->segment) {
@@ -762,70 +355,5 @@ TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf)
default:
return -1;
}
}/*}}}*/
#if HAVE_UTIME
static zend_always_inline void UnixTimeToFileTime(time_t t, LPFILETIME pft) /* {{{ */
{
// Note that LONGLONG is a 64-bit value
LONGLONG ll;
ll = t * 10000000LL + 116444736000000000LL;
pft->dwLowDateTime = (DWORD)ll;
pft->dwHighDateTime = ll >> 32;
}
/* }}} */
TSRM_API int win32_utime(const char *filename, struct utimbuf *buf) /* {{{ */
{
FILETIME mtime, atime;
HANDLE hFile;
PHP_WIN32_IOUTIL_INIT_W(filename)
if (!pathw) {
return -1;
}
hFile = CreateFileW(pathw, GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL,
OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL);
PHP_WIN32_IOUTIL_CLEANUP_W()
/* OPEN_ALWAYS mode sets the last error to ERROR_ALREADY_EXISTS but
the CreateFile operation succeeds */
if (GetLastError() == ERROR_ALREADY_EXISTS) {
SetLastError(0);
}
if ( hFile == INVALID_HANDLE_VALUE ) {
return -1;
}
if (!buf) {
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &mtime);
atime = mtime;
} else {
UnixTimeToFileTime(buf->modtime, &mtime);
UnixTimeToFileTime(buf->actime, &atime);
}
if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
CloseHandle(hFile);
return -1;
}
CloseHandle(hFile);
return 1;
}
/* }}} */
#endif
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
#endif
+16 -29
View File
@@ -1,13 +1,13 @@
/*
+----------------------------------------------------------------------+
| PHP Version 7 |
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2018 The PHP Group |
| Copyright (c) 1997-2002 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| This source file is subject to version 2.02 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 |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.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. |
@@ -16,18 +16,18 @@
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef TSRM_WIN32_H
#define TSRM_WIN32_H
#include "TSRM.h"
#ifdef TSRM_WIN32
#include <windows.h>
#if HAVE_UTIME
# include <sys/utime.h>
#endif
#include "win32/ipc.h"
struct ipc_perm {
key_t key;
int key;
unsigned short uid;
unsigned short gid;
unsigned short cuid;
@@ -38,7 +38,7 @@ struct ipc_perm {
struct shmid_ds {
struct ipc_perm shm_perm;
size_t shm_segsz;
int shm_segsz;
time_t shm_atime;
time_t shm_dtime;
time_t shm_ctime;
@@ -65,17 +65,16 @@ typedef struct {
int process_size;
int shm_size;
char *comspec;
HANDLE impersonation_token;
PSID impersonation_token_sid;
} tsrm_win32_globals;
#ifdef ZTS
# define TWG(v) TSRMG_STATIC(win32_globals_id, tsrm_win32_globals *, v)
TSRMLS_CACHE_EXTERN()
# define TWG(v) TSRMG(win32_globals_id, tsrm_win32_globals *, v)
#else
# define TWG(v) (win32_globals.v)
#endif
#endif
#define IPC_PRIVATE 0
#define IPC_CREAT 00001000
#define IPC_EXCL 00002000
@@ -93,28 +92,16 @@ TSRMLS_CACHE_EXTERN()
#define SHM_RND FILE_MAP_WRITE
#define SHM_REMAP FILE_MAP_COPY
char * tsrm_win32_get_path_sid_key(const char *pathname, size_t pathname_len, size_t *key_len);
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);
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);
TSRM_API int win32_utime(const char *filename, struct utimbuf *buf);
TSRM_API int shmget(key_t key, size_t size, int flags);
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);
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
#endif
-757
View File
@@ -1,757 +0,0 @@
PHP 7.3 UPGRADE NOTES
1. Backward Incompatible Changes
2. New Features
3. Changes in SAPI modules
4. Deprecated Functionality
5. Changed Functions
6. New Functions
7. New Classes and Interfaces
8. Removed Extensions and SAPIs
9. Other Changes to Extensions
10. New Global Constants
11. Changes to INI File Handling
12. Windows Support
13. Other Changes
========================================
1. Backward Incompatible Changes
========================================
Core:
. The ext_skel utility has been completely redesigned with new options and
some old options removed. This is now written in PHP and has no external
dependencies.
. Support for BeOS has been dropped.
. Exceptions thrown due to automatic conversion of warnings into exceptions
in EH_THROW mode (e.g. some DateTime exceptions) no longer populate
error_get_last() state. As such, they now work the same way as manually
thrown exceptions.
. TypeError now reports wrong types as `int` and `bool` instead of `integer`
and `boolean`.
. Due to the introduction of flexible heredoc/nowdoc syntax (see New Features
section), doc strings that contain the ending label inside their body may
cause syntax errors or change in interpretation. For example in
$str = <<<FOO
abcdefg
FOO
FOO;
the indented occurrence of "FOO" did not previously have any special
meaning. Now it will be interpreted as the end of the heredoc string and
the following "FOO;" will cause a syntax error. This issue can always be
resolved by choosing an ending label that does not occur within the contents
of the string.
. "continue" statements targeting "switch" control flow structures will now
generate a warning. In PHP such "continue" statements are equivalent to
"break", while they behave as "continue 2" in other languages.
while ($foo) {
switch ($bar) {
case "baz":
continue;
// Warning: "continue" targeting switch is equivalent to
// "break". Did you mean to use "continue 2"?
}
}
. Array accesses of type $obj["123"], where $obj implements ArrayAccess and
"123" is an integer string literal will no longer result in an implicit
conversion to integer, i.e., $obj->offsetGet("123") will be called instead
of $obj->offsetGet(123). This matches existing behavior for non-literals.
The behavior of arrays is not affected in any way, they continue to
implicitly convert integeral string keys to integers.
. In PHP, static properties are shared between inheriting classes, unless the
static property is explicitly overridden in a child class. However, due to
an implementation artifact it was possible to separate the static properties
by assigning a reference. This loophole has been fixed.
class Test {
public static $x = 0;
}
class Test2 extends Test { }
Test2::$x = &$x;
$x = 1;
var_dump(Test::$x, Test2::$x);
// Previously: int(0), int(1)
// Now: int(1), int(1)
. References returned by array and property accesses are now unwrapped as
part of the access. This means that it is no longer possible to modify the
reference between the access and the use of the accessed value:
$arr = [1];
$ref =& $arr[0];
var_dump($arr[0] + ($arr[0] = 2));
// Previously: int(4), Now: int(3)
This makes the behavior of references and non-references consistent. Please
note that reading and writing a value inside a single expression remains
undefined behavior and may change again in the future.
. Argument unpacking stopped working with Traversables with non-integer keys.
The following code worked in PHP 7.0-7.2 by accident.
function foo(...$args) {
var_dump($args);
}
function gen() {
yield 1.23 => 123;
}
foo(...gen());
Now it generates an exception.
BCMath:
. All warnings thrown by BCMath functions are now using PHP's error handling.
Formerly some warnings have directly been written to stderr.
. bcmul() and bcpow() now return numbers with the requested scale. Formerly,
the returned numbers may have omitted trailing decimal zeroes.
IMAP:
rsh/ssh logins are disabled by default. Use imap.enable_insecure_rsh if you want
to enable them. Note that the IMAP library does not filter mailbox names before
passing them to rsh/ssh command, thus passing untrusted data to this function
with rsh/ssh enabled is insecure.
MBString:
. Due to added support for named captures, mb_ereg_*() patterns using named
captures will behave differently. In particular named captures will be part
of matches and mb_ereg_replace() will interpret additional syntax. See
"New Features" section for more information.
mysqli:
. Prepared statements now properly report the fractional seconds for DATETIME/
TIME/TIMESTAMP columns with decimals specifier (e.g. TIMESTAMP(6) when using
microseconds). Formerly, the fractional seconds part was simply omitted from
the returned values.
PDO/MySQL:
. Prepared statements now properly report the fractional seconds for DATETIME/
TIME/TIMESTAMP columns with decimals specifier (e.g. TIMESTAMP(6) when using
microseconds). Formerly, the fractional seconds part was simply omitted from
the returned values.
Please note that this only affects the usage of PDO_MYSQL with emulated
prepares turned off (e.g. using the native preparation functionality).
Statements using connections having PDO::ATTR_EMULATE_PREPARES=true (which
is the default) were not affected by the bug fixed and have already been
getting the proper fractional seconds values from the engine.
Reflection:
. Reflection export to string now uses `int` and `bool` instead of `integer`
and `boolean`.
SPL:
. If an SPL autoloader throws an exception, following autoloaders will not be
executed. Previously all autoloaders were executed and exceptions were
chained.
SimpleXML:
. Mathematic operations involving SimpleXML objects will now treat the text as
an integer or float, whichever is more appropriate. Previously values were
treated as integers unconditionally.
Standard:
. Undefined variables passed to compact() will now be reported as a notice.
. getimagesize() and related functions now report the mime type of BMP images
as image/bmp instead of image/x-ms-bmp, since the former has been registered
with the IANA (see RFC 7903).
. stream_socket_get_name() will now return IPv6 addresses wrapped in brackets.
For example "[::1]:1337" will be returned instead of "::1:1337".
========================================
2. New Features
========================================
Core:
. Implemented flexible heredoc and nowdoc syntax: The closing marker for doc
strings is no longer required to be followed by a semicolon or newline.
Additionally the closing marker may be indented, in which case the
indentation will be stripped from all lines in the doc string.
(RFC: https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes)
. Array destructuring now supports reference assignments using the syntax
[&$a, [$b, &$c]] = $d. The same is also supported for list().
(RFC: https://wiki.php.net/rfc/list_reference_assignment)
. instanceof now allows literals as the first operand,
in which case the result is always FALSE.
. A new CompileError exception has been added, from which ParseError inherits.
A small number of compilation errors will now throw a CompileError instead
of generating a fatal error. Currently this only affects compilation errors
that may be thrown by token_get_all() in TOKEN_PARSE mode, but more errors
may be converted in the future.
. Trailing commas in function and method calls are now allowed.
(RFC: https://wiki.php.net/rfc/trailing-comma-function-calls)
BCMath:
. bcscale() can now also be used as getter to retrieve the current scale in use.
MBString:
. Support for full case-mapping and case-folding has been added. Unlike simple
case-mapping, full case-mapping may change the length of the string. For
example:
mb_strtoupper("Straße")
// Produces STRAßE on PHP 7.2
// Produces STRASSE on PHP 7.3
The different casing mapping and folding modes are available through
mb_convert_case():
. MB_CASE_LOWER (used by mb_strtolower)
. MB_CASE_UPPER (used by mb_strtoupper)
. MB_CASE_TITLE
. MB_CASE_FOLD
. MB_CASE_LOWER_SIMPLE
. MB_CASE_UPPER_SIMPLE
. MB_CASE_TITLE_SIMPLE
. MB_CASE_FOLD_SIMPLE (used by case-insensitive operations)
Only unconditional, language agnostic full case-mapping is performed.
. Case-insensitive string operations now use case-folding instead of case-
mapping during comparisons. This means that more characters will be
considered (case insensitively) equal now.
. mb_convert_case() with MB_CASE_TITLE now performs title-case conversion
based on the Cased and CaseIgnorable derived Unicode properties. In
particular this also improves handling of quotes and apostophes.
. Data tables have been updated for Unicode 11.
. Mbstring now correctly supports strings larger than 2GB.
. Performance of the mbstring extension has been significantly improved
across the board. The largest improvements are in case conversion functions.
. mb_ereg_*() functions now support named captures. Matching functions like
mb_ereg() will now return named captures both using their group number and
their name, similar to PCRE:
mb_ereg('(?<word>\w+)', '国', $matches);
// => [0 => "国", 1 => "国", "word" => "国"];
Additionally, mb_ereg_replace() now supports the \k<> and \k'' notations
to reference named captures in the replacement string:
mb_ereg_replace('\s*(?<word>\w+)\s*', "_\k<word>_\k'word'_", ' foo ');
// => "_foo_foo_"
\k<> and \k'' can also be used for numbered references, which also works
with group numbers greater than 9.
readline:
. Support for the completion_append_character and completion_suppress_append
options has been added to readline_info(). These options are only available
if PHP is linked against libreadline (rather than libedit).
Standard:
. The --with-password-argon2[=dir] configure argument now provides support for
both Argon2i and Argon2id hashes in the password_hash(), password_verify(),
password_get_info(), and password_needs_rehash() functions. Passwords may be
hashed and verified using the PASSWORD_ARGON2ID constant.
Support for both Argon2i and Argon2id in the password_* functions now requires
PHP be linked against libargon2 reference library >= 20161029.
(RFC: https://wiki.php.net/rfc/argon2_password_hash_enhancements).
LDAP:
. Full support for LDAP Controls has been added to LDAP querying functions
and ldap_parse_result
========================================
3. Changes in SAPI modules
========================================
phpdbg:
. The unused constants PHPDBG_FILE, PHPDBG_METHOD, PHPDBG_LINENO and
PHPDBG_FUNC have been removed.
FPM:
. A new global option log_limit has been added. It can be used for setting
log limit for logged line which allows to log messages longer than 1024
characters without wrapping. It also fixes various wrapping issues.
. A new global option log_buffering has been added. It allows an experimental
logging without extra buffering.
. A new pool option decorate_workers_output has been added. It allows
disabling output decoration for workers output when catch_workers_output
enabled.
. The getallheaders() function is now also available.
. In PHP 7.3.11 a new pool option
request_terminate_timeout_track_finished has been added. When enabled,
request_terminate_timeout will also apply after fastcgi_finish_request()
has been called, as well as during execution of shutdown functions.
========================================
4. Deprecated Functionality
========================================
Core:
. The declaration of case-insensitive constants has been deprecated. Passing
true as the third argument to define() will now generate a deprecation
warning. The use of case-insensitive constants with a case that differs from
the declaration is also deprecated.
(RFC: https://wiki.php.net/rfc/case_insensitive_constant_deprecation)
. Declaring a function called assert() inside a namespace is deprecated.
The assert() function is subject to special handling by the engine, which
may lead to inconsistent behavior when defining a namespaced function with
the same name.
Filter:
. The explicit usage of the constants FILTER_FLAG_SCHEME_REQUIRED and
FILTER_FLAG_HOST_REQUIRED is now deprecated; both are implied for
FILTER_VALIDATE_URL anyway.
GD:
. image2wbmp() has been deprecated.
Intl:
. Usage of the Normalizer::NONE form throws a deprecation warning, if PHP is
linked with ICU >= 56.
Mbstring:
. The following undocumented mbereg_*() aliases have been deprecated. Use the
corresponding mb_ereg_*() variants instead.
. mbregex_encoding()
. mbereg()
. mberegi()
. mbereg_replace()
. mberegi_replace()
. mbsplit()
. mbereg_match()
. mbereg_search()
. mbereg_search_pos()
. mbereg_search_regs()
. mbereg_search_init()
. mbereg_search_getregs()
. mbereg_search_getpos()
. mbereg_search_setpos()
PDO ODBC:
. The pdo_odbc.db2_instance_name ini setting has been formally deprecated. It
has already been deprecated in the documentation since PHP 5.1.1.
Standard:
. Passing a non-string needle to string search functions is deprecated. In the
future the needle will be interpreted as a string instead of an ASCII codepoint.
Depending on the intended behavior, you should either explicitly cast the
needle to string or perform an explicit call to chr(). The following functions
are affected:
. strpos()
. strrpos()
. stripos()
. strripos()
. strstr()
. strchr()
. strrchr()
. stristr()
. The fgetss() function and the string.strip_tags stream filter have been deprecated.
This also affects the SplFileObject::fgetss() method and gzgetss() function.
========================================
5. Changed Functions
========================================
JSON:
. A new flag has been added, JSON_THROW_ON_ERROR, which can be used with
json_decode() or json_encode() and causes these functions to throw a
JsonException upon an error, instead of setting the global error state that
is retrieved with json_last_error(). JSON_PARTIAL_OUTPUT_ON_ERROR takes
precedence over JSON_THROW_ON_ERROR.
(RFC: https://wiki.php.net/rfc/json_throw_on_error)
Session:
. session_set_cookie_params() now also supports the following signature:
session_set_cookie_params(array $options)
where $options is an associative array which may have any of the keys
"lifetime", "path", "domain", "secure", "httponly" and "samesite".
Accordingly, the return value of session_get_cookie_params() now also has an
element with the key "samesite".
Standard:
. debug_zval_dump() was changed to display recursive arrays and objects
in the same way as var_dump(). Now, it doesn't display them twice.
. array_push() and array_unshift() can now also be called with a single
argument, which is particularly convenient wrt. the spread operator.
. setcookie() and setrawcookie() now also support the following signature:
set(raw)cookie(string $name, [string $value, [array $options]])
where $options is an associative array which may have any of the keys
"expires", "path", "domain", "secure", "httponly" and "samesite".
PCRE:
. preg_quote() now also escapes the '#' character.
LDAP:
. Added a serverctrls parameter to send controls to the server in ldap_add,
ldap_mod_replace, ldap_mod_add, ldap_mod_del, ldap_rename,
ldap_compare, ldap_delete, ldap_modify_batch,
ldap_search, ldap_list, ldap_read
. Added an out parameter to get controls from the server in ldap_parse_result
. Fixed support for LDAP_OPT_SERVER_CONTROLS and LDAP_OPT_CLIENT_CONTROLS in
ldap_get_option and ldap_set_option.
========================================
6. New Functions
========================================
Core:
. Added monotonic timer function hrtime([bool get_as_num]). It returns an
array of the form [seconds, nanoseconds] with the timestamp starting at
an unspecified point in the past. If the optional argument is passed as
true, the return value is an integer on 64-bit systems or float on
32-bit systems, representing the nanoseconds. The timestamp is not
adjustable and is not related to wall clock or time of day. The timers
are available under Linux, FreeBSD, Windows, Mac, SunOS, AIX and their
derivatives. If no required timers are provided by a corresponding
platform, the function returns false.
. Added net_get_interfaces() to retrieve an array of available network
interfaces including several details.
. Added the gc_status() function to retrieve status information regarding the
cyclic GC.
Date:
. Added the DateTime::createFromImmutable() method, which mirrors
DateTimeImmutable::createFromMutable().
FPM:
. Added fpm_get_status() function which returns FPM status info array.
GMP:
. Added gmp_binomial(n, k) for calculating binomial coefficients.
. Added gmp_lcm(a, b) for calculating the least common multiple.
. Added gmp_perfect_power(a) to check if number is a perfect power.
. Added gmp_kronecker(a, b) to compute the Kronecker symbol.
Intl:
. Added void Spoofchecker::setRestrictionLevel(int $level) method, available
when linked with ICU >= 58.1. Levels are represented as class constants
- Spoofchecker::ASCII
- Spoofchecker::HIGHLY_RESTRICTIVE
- Spoofchecker::MODERATELY_RESTRICTIVE
- Spoofchecker::MINIMALLY_RESTRICTIVE
- Spoofchecker::UNRESTRICTIVE
- Spoofchecker::SINGLE_SCRIPT_RESTRICTIVE
For the detailed documentation on the restriction levels, see
URestrictionLevel under
http://icu-project.org/apiref/icu4c/uspoof_8h.html
. Added Normalizer::getRawDecomposition() and normalizer_get_raw_decomposition(),
to retrieve the Decomposition_Mapping property of a character.
LDAP:
. Added ldap_exop_refresh() to conveniently perform a Refresh extended
operation.
OpenSSL:
. Added openssl_pkey_derive that derives a shared secret for DH, ECDH and
possibly other future algorithms supported by EVP_PKEY_derive.
Sockets:
. Added functions to import/export the WSAPROTOCOL_INFO info struct. This
implementation complements the already supported SCM_RIGHTS as in
man 3 cmsg and is Windows specific. For the import/export, the default
system securities apply for the SHM reading/writing. The socket becomes
invalid, when the last reference to it is closed.
- socket_wsaprotocol_info_export(resource $sock, int $pid) - exports the
WSAPROTOCOL_INFO structure into shared memory and returns an identifier
to be used for the import, or false on failure. The exported ID is
only valid for the dedicated PID.
- socket_wsaprotocol_info_import(string $id) - returns a duplicated
socket as per the passed identifier, or false on failure.
- socket_wsaprotocol_info_release(string $id) - releases the shared memory
corresponding to the passed identifier.
Standard:
. Added is_countable() function, to check whether a value may be passed to
count().
(RFC: https://wiki.php.net/rfc/is-countable)
. Added array_key_first() and array_key_last() which retrieve the first and
last key of an array, respectively.
(RFC: <https://wiki.php.net/rfc/array_key_first_last>)
LDAP:
. Added functions ldap_add_ext, ldap_bind_ext, ldap_delete_ext, ldap_mod_add_ext,
ldap_mod_replace_ext, ldap_mod_del_ext, ldap_rename_ext
which gives access to the result object to be able to parse it
with ldap_parse_result and get more information than just success/failure.
========================================
7. New Classes and Interfaces
========================================
JSON:
. JsonException
========================================
8. Removed Extensions and SAPIs
========================================
========================================
9. Other Changes to Extensions
========================================
Curl:
. libcurl >= 7.15.5 is now required.
Filter:
. FILTER_VALIDATE_FLOAT now also supports a `thousand` option, which
defines the set of allowed thousand separator chars. The default (`"',."`)
is fully backward compatible with former PHP versions.
. FILTER_SANITIZE_ADD_SLASHES has been added as an alias of the 'magic_quotes'
filter (FILTER_SANITIZE_MAGIC_QUOTES). The 'magic_quotes' filter is subject
to removal in future versions of PHP.
FTP:
. Set default transfer mode to binary
Intl:
. Normalizer::NONE is deprecated, when PHP is linked with ICU >= 56
. Introduced Normalizer::FORM_KC_CF as Normalizer::normalize() argument
for NFKC_Casefold normalization, available when linked with ICU >= 56
MBString:
. The configuration option --with-libmbfl is no longer available.
ODBC:
. Support for ODBCRouter has been removed.
. Support for Birdstep has been removed.
OpenSSL:
. The min_proto_version and max_proto_version ssl stream options as well as
related constants for possible TLS protocol values have been added.
See <https://github.com/php/php-src/pull/3317>.
PCRE:
. The PCRE extension has been upgraded to PCRE2, which may cause minor
behavioral changes (for instance, character ranges in classes are now more
strictly interpreted), and augments the existing regular expression syntax.
See <https://wiki.php.net/rfc/pcre2-migration> for details.
PDO_DBLIB:
. Added the attribute PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS to enable automatic
skipping of empty rowsets.
. Exposed the TDS version via the PDO::DBLIB_ATTR_TDS_VERSION attribute.
. DATETIME2 columns are now treated like DATETIME columns.
PDO_SQLite:
. SQLite3 databases can now be opened in read-only mode by setting the
new PDO::SQLITE_ATTR_OPEN_FLAGS attribute to PDO::SQLITE_READONLY.
Standard:
. var_export() now exports stdClass objects as an array casted to an object
(`(object) array( ... )`), rather than using the nonexistent method
stdClass::__setState().
Tidy:
. Building against tidyp (<https://github.com/petdance/tidyp>) is now also
supported transparently. Since tidyp offers no API to get the release date,
tidy_get_release() and tidy::getRelease() return 'unknown' in this case.
XML:
. The return value of the `xml_set_external_entity_ref_handler()` callback is
now also heeded if the extension has been built against libxml. Formerly,
the return value has been ignored, and parsing did never stop.
Zip:
. Building against the bundled libzip is discouraged, but still possible by
adding `--without-libzip` to the configuration.
zlib:
. Added the zlib/level context option for the compress.zlib wrapper to
facilitate setting the desired compression level.
========================================
10. New Global Constants
========================================
Curl:
. CURLAUTH_BEARER
. CURLAUTH_GSSAPI
. CURLE_WEIRD_SERVER_REPLY
. CURLINFO_APPCONNECT_TIME_T
. CURLINFO_CONNECT_TIME_T
. CURLINFO_CONTENT_LENGTH_DOWNLOAD_T
. CURLINFO_CONTENT_LENGTH_UPLOAD_T
. CURLINFO_FILETIME_T
. CURLINFO_HTTP_VERSION
. CURLINFO_NAMELOOKUP_TIME_T
. CURLINFO_PRETRANSFER_TIME_T
. CURLINFO_PROTOCOL
. CURLINFO_PROXY_SSL_VERIFYRESULT
. CURLINFO_REDIRECT_TIME_T
. CURLINFO_SCHEME
. CURLINFO_SIZE_DOWNLOAD_T
. CURLINFO_SIZE_UPLOAD_T
. CURLINFO_SPEED_DOWNLOAD_T
. CURLINFO_SPEED_UPLOAD_T
. CURLINFO_STARTTRANSFER_TIME_T
. CURLINFO_TOTAL_TIME_T
. CURL_LOCK_DATA_CONNECT
. CURL_LOCK_DATA_PSL
. CURL_MAX_READ_SIZE
. CURLOPT_ABSTRACT_UNIX_SOCKET
. CURLOPT_DISALLOW_USERNAME_IN_URL
. CURLOPT_DNS_SHUFFLE_ADDRESSES
. CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS
. CURLOPT_HAPROXYPROTOCOL
. CURLOPT_KEEP_SENDING_ON_ERROR
. CURLOPT_PRE_PROXY
. CURLOPT_PROXY_CAINFO
. CURLOPT_PROXY_CAPATH
. CURLOPT_PROXY_CRLFILE
. CURLOPT_PROXY_KEYPASSWD
. CURLOPT_PROXY_PINNEDPUBLICKEY
. CURLOPT_PROXY_SSLCERT
. CURLOPT_PROXY_SSLCERTTYPE
. CURLOPT_PROXY_SSL_CIPHER_LIST
. CURLOPT_PROXY_SSLKEY
. CURLOPT_PROXY_SSLKEYTYPE
. CURLOPT_PROXY_SSL_OPTIONS
. CURLOPT_PROXY_SSL_VERIFYHOST
. CURLOPT_PROXY_SSL_VERIFYPEER
. CURLOPT_PROXY_SSLVERSION
. CURLOPT_PROXY_TLS13_CIPHERS
. CURLOPT_PROXY_TLSAUTH_PASSWORD
. CURLOPT_PROXY_TLSAUTH_TYPE
. CURLOPT_PROXY_TLSAUTH_USERNAME
. CURLOPT_REQUEST_TARGET
. CURLOPT_SOCKS5_AUTH
. CURLOPT_SSH_COMPRESSION
. CURLOPT_SUPPRESS_CONNECT_HEADERS
. CURLOPT_TIMEVALUE_LARGE
. CURLOPT_TLS13_CIPHERS
. CURLPROXY_HTTPS
. CURLSSH_AUTH_GSSAPI
. CURL_SSLVERSION_MAX_DEFAULT
. CURL_SSLVERSION_MAX_NONE
. CURL_SSLVERSION_MAX_TLSv1_0
. CURL_SSLVERSION_MAX_TLSv1_1
. CURL_SSLVERSION_MAX_TLSv1_2
. CURL_SSLVERSION_MAX_TLSv1_3
. CURL_SSLVERSION_TLSv1_3
. CURL_VERSION_ALTSVC
. CURL_VERSION_ASYNCHDNS
. CURL_VERSION_BROTLI
. CURL_VERSION_CONV
. CURL_VERSION_CURLDEBUG
. CURL_VERSION_DEBUG
. CURL_VERSION_GSSAPI
. CURL_VERSION_GSSNEGOTIATE
. CURL_VERSION_HTTPS_PROXY
. CURL_VERSION_IDN
. CURL_VERSION_LARGEFILE
. CURL_VERSION_MULTI_SSL
. CURL_VERSION_NTLM
. CURL_VERSION_NTLM_WB
. CURL_VERSION_PSL
. CURL_VERSION_SPNEGO
. CURL_VERSION_SSPI
. CURL_VERSION_TLSAUTH_SRP
Filter:
. FILTER_SANITIZE_ADD_SLASHES
JSON:
. JSON_THROW_ON_ERROR
OpenSSL:
. STREAM_CRYPTO_PROTO_SSLv3
. STREAM_CRYPTO_PROTO_TLSv1_0
. STREAM_CRYPTO_PROTO_TLSv1_1
. STREAM_CRYPTO_PROTO_TLSv1_2
MBString:
. MB_CASE_FOLD
. MB_CASE_LOWER_SIMPLE
. MB_CASE_UPPER_SIMPLE
. MB_CASE_TITLE_SIMPLE
. MB_CASE_FOLD_SIMPLE
PGSQL:
. Requires Postgres 9.3
- PGSQL_DIAG_SCHEMA_NAME
- PGSQL_DIAG_TABLE_NAME
- PGSQL_DIAG_COLUMN_NAME
- PGSQL_DIAG_DATATYPE_NAME
- PGSQL_DIAG_CONSTRAINT_NAME
. Requires Postgres 9.6
- PGSQL_DIAG_SEVERITY_NONLOCALIZED
Standard:
. PASSWORD_ARGON2ID
LDAP:
. LDAP_CONTROL_MANAGEDSAIT
. LDAP_CONTROL_PROXY_AUTHZ
. LDAP_CONTROL_SUBENTRIES
. LDAP_CONTROL_VALUESRETURNFILTER
. LDAP_CONTROL_ASSERT
. LDAP_CONTROL_PRE_READ
. LDAP_CONTROL_POST_READ
. LDAP_CONTROL_SORTREQUEST
. LDAP_CONTROL_SORTRESPONSE
. LDAP_CONTROL_PAGEDRESULTS
. LDAP_CONTROL_AUTHZID_REQUEST
. LDAP_CONTROL_AUTHZID_RESPONSE
. LDAP_CONTROL_SYNC
. LDAP_CONTROL_SYNC_STATE
. LDAP_CONTROL_SYNC_DONE
. LDAP_CONTROL_DONTUSECOPY
. LDAP_CONTROL_PASSWORDPOLICYREQUEST
. LDAP_CONTROL_PASSWORDPOLICYRESPONSE
. LDAP_CONTROL_X_INCREMENTAL_VALUES
. LDAP_CONTROL_X_DOMAIN_SCOPE
. LDAP_CONTROL_X_PERMISSIVE_MODIFY
. LDAP_CONTROL_X_SEARCH_OPTIONS
. LDAP_CONTROL_X_TREE_DELETE
. LDAP_CONTROL_X_EXTENDED_DN
. LDAP_CONTROL_VLVREQUEST
. LDAP_CONTROL_VLVRESPONSE
========================================
11. Changes to INI File Handling
========================================
- birdstep.max_links
. This INI directive has been removed.
- opcache.inherited_hack
. This INI directive has been removed. The value has already been ignored
since PHP 5.3.0.
- session.cookie_samesite
. New INI option to allow to set the SameSite directive for cookies. Defaults
to "" (empty string), so no SameSite directive is set. Can be set to "Lax"
or "Strict", which sets the respective SameSite directive.
- syslog.facility
- New INI to set syslog facility which specifies what type of program is
logging the message. It is used only when error_log is set to syslog.
- syslog.filter
. New INI to set syslog filter type to filter the logged messages. There are
3 supported filter types - all, no-ctrl and ascii. It is used only when
error_log is set to syslog.
- syslog.ident
. New INI to set syslog ident string which is prepended to every message. It
is used only when error_log is set syslog.
- mbstring.regex_stack_limit
. New INI directive (since 7.3.5) limiting stack depth of mbstring/oniguruma
regular expressions.
========================================
12. Windows Support
========================================
- Core
. File descriptors are opened in shared read/write/delete mode by default.
This effectively maps the UNIX semantics and allows to delete files with
handles in use. It is not 100% same, some platform differences still
persist. After the deletion, the filename entry is blocked, until all
the opened handles to it are closed.
========================================
13. Other Changes
========================================
. The cyclic GC has been enhanced, which may result in considerable performance
improvements.
-208
View File
@@ -1,208 +0,0 @@
PHP 7.3 INTERNALS UPGRADE NOTES
1. Internal API changes
a. array_init() and array_init_size()
b. Run-time constant operand addressing
c. Array/Object recursion protection
d. HASH_FLAG_PERSISTENT
e. AST and IS_CONSTANT
f. GC_REFCOUNT()
g. zend_get_parameters()
h. zend_register_persistent_resource()
i. RAND_RANGE()
j. cast_object() with _IS_NUMBER
k. zend_fcall_info_cache.initialized
l. php_hrtime_current()
m. zend_cpu_supports()
n. IS_TYPE_COPYABLE
o. IS_UNUSED
p. VM instruction operands (FETCH_CLASS, FETCH_CONSTANT, CATCH)
q. sapi_cli_single_write()
r. php_url
s. zend_function.reserved[]
t. zif_handler
u. GC_G
v. php_add[c]slashes
w. zend_class_entry.iterator_funcs
x. Class declaration opcodes (DECLARE_INHERITED_CLASS ...)
y. zend_constant
z. HAVE_ST_BLKSIZE and HAVE_ST_RDEV
aa. RETSIGTYPE
bb. php_setcookie
2. Build system changes
a. Unix build system changes
b. Windows build system changes
3. Module changes
========================
1. Internal API changes
========================
a. array_init() and array_init_size() are not functions anymore.
They don't return any values.
b. In 64-bit builds PHP-7.2 and below used relative run-time constant operand
addressing. E.g. opline->op1.constant kept an offset from start of literals
table - op_array->literals. To speedup access op_array->literals was cached
in execute_data->literals. So the resulting address calculated as
EX(literals) + opline->op1.constant.
Now at run-time literals allocated close to opcodes, and addressed
relatively from current opline. This eliminates load of EX(literals) on
each constant access as well as EX(literals) initialization on each call.
As result some related macros were removed (ZEND_EX_USE_LITERALS,
EX_LOAD_LITERALS, EX_LITERALS, RT_CONSTANT_EX, EX_CONSTANT) or changed
(RT_CONSTANT, ZEND_PASS_TWO_UPDATE_CONSTANT, ZEND_PASS_TWO_UNDO_CONSTANT).
This change may affect only some "system" extensions. EX_LITERALS,
RT_CONSTANT_EX, EX_CONSTANT should be substituted by RT_CONSTANT, and now
use "opline" (instead of "op_array") as first argument.
c. Protection from recursion during processing circular data structures was
refactored. HashTable.nApplyCount and IS_OBJ_APPLY_COUNT are replaced by
single flag GC_PROTECTED. Corresponding macros Z_OBJ_APPLY_COUNT,
Z_OBJ_INC_APPLY_COUNT, Z_OBJ_DEC_APPLY_COUNT, ZEND_HASH_GET_APPLY_COUNT,
ZEND_HASH_INC_APPLY_COUNT, ZEND_HASH_DEC_APPLY_COUNT are replaced with
GC_IS_RECURSIVE, GC_PROTECT_RECURSION, GC_UNPROTECT_RECURSION,
Z_IS_RECURSIVE, Z_PROTECT_RECURSION, Z_UNPROTECT_RECURSION.
HASH_FLAG_APPLY_PROTECTION flag and ZEND_HASH_APPLY_PROTECTION() macro
are removed. All mutable arrays should use recursion protection.
Corresponding checks should be replaced by Z_REFCOUNTED() or
!(GC_FLAGS(p) & GC_IMMUTABLE).
d. HASH_FLAG_PERSISTENT renamed into IS_ARRAY_PERSISTENT and moved into
GC_FLAGS (to be consistent with IS_STR_PERSISTENT).
e. zend_ast_ref structure is changed to use only one allocation.
zend_ast_copy() now returns zend_ast_ref (instead of zend_asr).
zend_ast_destroy_and_free() is removed. ZVAL_NEW_AST() is replaced
by ZVAL_AST().
IS_CONSTANT type and Z_CONST_FLAGS() are removed. Now constants are always
represented using IS_CONSTANT_AST (ZEND_AST_CONSTANT kind). AST node
attributes are used instead of constant flags. IS_TYPE_CONSTANT flag is
removed, but Z_CONSTANT() macro is kept for compatibility.
f. GC_REFCOUNT() is turned into inline function and can't be modified direcly.
All reference-counting operations should be done through corresponding
macros GC_SET_REFCOUNT(), GC_ADDREF() and GC_DELREF().
GC_REFCOUNT(p)++ should be changed into GC_ADDREF(p),
GC_REFCOUNT(p)-- into GC_DELREF(p),
GC_REFCOUNT(p) = 1 into GC_SET_REFCOUNT(p, 1).
g. The zend_get_parameters() and zend_get_parameters_ex() functions were
removed. Instead zend_parse_parameters() should be used.
h. New functions zend_register_persistent_resource() or
zend_register_persistent_resource_ex() should beused to register
persistent resources, instead of manual insertion into EG(persistent_list).
i. The RAND_RANGE() macro has been removed. php_mt_rand_range() should be
used instead.
j. The cast_object() object handler now also accepts the _IS_NUMBER type. The
handler should return either an integer or float value in this case,
whichever is more appropriate.
k. zend_fcall_info_cache.initialized is removed. zend_fcall_info_cache is
initialized if zend_fcall_info_cache.function_handler is set.
l. php_hrtime_current() delivers the number of nanoseconds since an uncertain
point in the past.
m. zend_cpu_supports() determines if a feature is supported by current cpu.
Also serial inline zend_cpu_supports_xxx() are added, which is designed for
ifunc resolver function, as resolver function should not depend on any
external function.
n. IS_TYPE_COPYABLE flag is removed. IS_STRING zvals didn't need to be
duplication by zval_copy_ctor(), ZVAL_DUP() and SEPARATE_ZVAL*() macros.
Interned strings didn't set IS_TYPE_COPYABLE, so they aren't affected at
all. Now instead of checking for IS_TYPE_COPYABLE, engine checks for
IS_ARRAY type (it may be IS_TYPE_REFCOUNTED or not). All the related
macros: Z_COPYABLE..., Z_IMMUTABLE... are kept for compatibility.
o. IS_UNUSED became zero and can't be used as a bitmask (there were no such
usages in PHP sources).
p. Operands of few VM instructions were changed
- FETCH_CLASS op1<fetch-flags>, op2<name>, result<var>
- FETCH_CONSTANT op1<fetch-flags>, op2<name>, result<tmp>
- CATCH ext<last-flag>, op1<name>, op2<jump_addr>, result<cv>
q. sapi_cli_single_write() now returns ssize_t instead of size_t.
r. fields of php_url struct change from char * to zend_string *
s. Special purpose zend_functions marked by ZEND_ACC_CALL_VIA_TRAMPOLINE or
ZEND_ACC_FAKE_CLOSURE flags use reserved[0] for internal purpose.
Third party extensions must not modify reserved[] fields of these functions.
t. For internal functions the typedef zif_handler has been introduced. It is
recommended to use this from now on, instead of defining own handler types.
u. The GC globals (GC_G) are now private. Use the new zend_gc_get_status() to
retrieve status information of the GC.
v. The should_free argument of the php_add[c]slashes functions has been
removed. It is now always the caller's responsibility to free the passed
string.
w. zend_class_entry.iterator_funcs have been replaced by iterator_funcs_ptr.
You don't have to set its value, setting parent.funcs in the get_iterator
function is enough.
x. Class declaration opcode formats were changed
- DECLARE_INHERITED_CLASS and DECLARE_ANON_INHERITED_CLASS now encode parent
class name in second operand directly (as IS_CONST operand). Previously,
parent class was fetched by the prior FETCH_CLASS opcode.
- ADD_INTERFACE and ADD_TRAIT don't use run-time cache to keep interface or
trait. These instructions are executed once, and caching is useless.
y. zend_constant.flags and zend_constant.module_number are packed into
reserved space inside zend_constant.value. They should be accessed using
ZEND_CONSTANT_FLAGS(), ZEND_CONSTANT_MODULE_NUMBER() and
ZEND_CONSTANT_SET_FLAGS() macros.
z. HAVE_ST_BLKSIZE must be replaced with HAVE_STRUCT_STAT_ST_BLKSIZE and
HAVE_ST_RDEV must be replaced with HAVE_STRUCT_STAT_ST_RDEV.
aa. RETSIGTYPE has been removed from the generated php_config.h and should be
replaced with void.
bb. php_setcookie() now expects an additional samesite argument, and the
url_encode parameter has been moved to the end. The signature is now:
int php_setcookie(zend_string *name, zend_string *value, time_t expires,
zend_string *path, zend_string *domain, int secure,
int httponly, zend_string *samesite, int url_encode);
========================
2. Build system changes
========================
a. Unix build system changes
- PHP_PROG_LEX, TSRM_CHECK_GCC_ARG, and LIBZEND_CPLUSPLUS_CHECKS Autoconf
macros have been removed.
- Minimum Autoconf version is 2.68+ for generating the configure script.
b. Windows build system changes
- ZEND_WIN32_FORCE_INLINE doesn't affect C++ anymore. zend_always_inline is
still usable in C++, but anything else inlining related is up to
compiler.
- ZEND_WIN32_KEEP_INLINE was removed, it was only needed for C++
convenience and is now default behavior with C++.
- New configure option --enable-native-intrinsics accepts a list of the
intrinsic optimizations to enable. It affects both the code generation
and the explicit optimizations guarded by preprocessor macros.
- The configure option --with-codegen-arch accepts only ia32 as a value.
Use it, to produce builds suitable for older processors without SSE2 or
even SSE support.
========================
3. Module changes
========================
-56
View File
@@ -1,56 +0,0 @@
--------------------------------------------------------------------
The Zend Engine License, Version 2.00
Copyright (c) 1999-2006 Zend Technologies Ltd. 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 names "Zend" and "Zend Engine" must not be used to endorse
or promote products derived from this software without prior
permission from Zend Technologies Ltd. For written permission,
please contact license@zend.com.
4. Zend Technologies Ltd. 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 Zend Technologies Ltd. No one other than Zend
Technologies Ltd. has the right to modify the terms applicable
to covered code created under this License.
5. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes the Zend Engine, freely available at
http://www.zend.com"
6. All advertising materials mentioning features or use of this
software must display the following acknowledgment:
"The Zend Engine is freely available at http://www.zend.com"
THIS SOFTWARE IS PROVIDED BY ZEND TECHNOLOGIES LTD. ``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 ZEND
TECHNOLOGIES LTD. 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.
--------------------------------------------------------------------
-55
View File
@@ -1,55 +0,0 @@
## Process this file with automake to produce Makefile.in -*- makefile -*-
#CLEANFILES = zend_language_parser.c zend_language_parser.h zend_language_scanner.c zend_language_parser.output zend_ini_parser.c zend_ini_parser.h zend_ini_scanner.c zend_ini_parser.output
AUTOMAKE_OPTIONS=foreign
noinst_LTLIBRARIES=libZend.la
libZend_la_SOURCES=\
zend_language_parser.y zend_language_scanner.l \
zend_ini_parser.y zend_ini_scanner.l \
zend_alloc.c zend_compile.c zend_constants.c \
zend_execute.c zend_execute_API.c zend_highlight.c zend_llist.c \
zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
zend_list.c zend_builtin_functions.c zend_sprintf.c \
zend_ini.c zend_sort.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_generators.c zend_virtual_cwd.c zend_ast.c zend_smart_str.c zend_cpuinfo.c
libZend_la_CFLAGS = -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1
libZend_la_LDFLAGS =
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
# automake isn't too clever about "non-standard" use of lex and yacc
$(libZend_la_OBJECTS): zend_language_parser.h
zend_ini_scanner.lo: zend_ini_parser.h
# Language parser/scanner rules
zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
$(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt $(srcdir)/zend_language_scanner_defs.h -o$@ $(srcdir)/zend_language_scanner.l
zend_language_parser.h: zend_language_parser.c
zend_language_parser.c: $(srcdir)/zend_language_parser.y
$(YACC) -p zend -v -d $(srcdir)/zend_language_parser.y -o zend_language_parser.c
# INI parser/scanner rules
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) --no-generation-date --case-inverted -cbdFt $(srcdir)/zend_ini_scanner_defs.h -o$@ $(srcdir)/zend_ini_scanner.l
zend_ini_parser.h: zend_ini_parser.c
depend:
zend_execute.lo: $(srcdir)/zend_execute.c
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) $(INLINE_CFLAGS) -c $(srcdir)/zend_execute.c
-1
View File
@@ -1 +0,0 @@
Zend/zend_execute.lo: $(srcdir)/zend_vm_execute.h $(srcdir)/zend_vm_opcodes.h
-43
View File
@@ -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.
-102
View File
@@ -1,102 +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 calls 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
-616
View File
@@ -1,616 +0,0 @@
dnl
dnl This file contains Zend specific autoconf functions.
dnl
AC_DEFUN([LIBZEND_CHECK_INT_TYPE],[
AC_MSG_CHECKING(for $1)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#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_BASIC_CHECKS],[
AC_REQUIRE([AC_PROG_YACC])
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_PROG_CC_C_O])
AC_REQUIRE([AC_HEADER_STDC])
LIBZEND_BISON_CHECK
dnl Ugly hack to get around a problem with gcc on AIX.
if test "$CC" = "gcc" -a "$ac_cv_prog_cc_g" = "yes" -a \
"`uname -sv`" = "AIX 4"; then
CFLAGS=`echo $CFLAGS | sed -e 's/-g//'`
fi
dnl Hack to work around a Mac OS X cpp problem
dnl Known versions needing this workaround are 5.3 and 5.4
if test "$ac_cv_prog_gcc" = "yes" -a "`uname -s`" = "Rhapsody"; then
CPPFLAGS="$CPPFLAGS -traditional-cpp"
fi
AC_CHECK_HEADERS(
inttypes.h \
stdint.h \
limits.h \
malloc.h \
string.h \
unistd.h \
stdarg.h \
sys/types.h \
sys/time.h \
signal.h \
unix.h \
stdlib.h \
cpuid.h \
dlfcn.h)
AC_TYPE_SIZE_T
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],[
dnl
dnl Ugly hack to check if dlsym() requires a leading underscore in symbol name.
dnl
AC_MSG_CHECKING([whether dlsym() requires a leading underscore in symbol names])
_LT_AC_TRY_DLOPEN_SELF([
AC_MSG_RESULT(no)
], [
AC_MSG_RESULT(yes)
AC_DEFINE(DLSYM_NEEDS_UNDERSCORE, 1, [Define if dlsym() requires a leading underscore in symbol names. ])
], [
AC_MSG_RESULT(no)
], [])
])
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_ZEND_BROKEN_SPRINTF
AC_CHECK_DECLS([isfinite, isnan, isinf], [], [], [[#include <math.h>]])
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_RUN_IFELSE([AC_LANG_SOURCE([[
#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_ARG_ENABLE(debug,
[ --enable-debug Compile with debugging symbols],[
ZEND_DEBUG=$enableval
],[
ZEND_DEBUG=no
])
])
AC_DEFUN([LIBZEND_OTHER_CHECKS],[
AC_ARG_ENABLE(maintainer-zts,
[ --enable-maintainer-zts Enable thread safety - for code maintainers only!!],[
ZEND_MAINTAINER_ZTS=$enableval
],[
ZEND_MAINTAINER_ZTS=no
])
AC_ARG_ENABLE(inline-optimization,
[ --disable-inline-optimization
If building zend_execute.lo fails, try this switch],[
ZEND_INLINE_OPTIMIZATION=$enableval
],[
ZEND_INLINE_OPTIMIZATION=yes
])
AC_MSG_CHECKING(whether to enable thread-safety)
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 Zend debugging)
AC_MSG_RESULT($ZEND_DEBUG)
if test "$ZEND_DEBUG" = "yes"; then
AC_DEFINE(ZEND_DEBUG,1,[ ])
echo " $CFLAGS" | grep ' -g' >/dev/null || DEBUG_CFLAGS="-g"
if test "$CFLAGS" = "-g -O2"; then
CFLAGS=-g
fi
test -n "$GCC" && DEBUG_CFLAGS="$DEBUG_CFLAGS -Wall"
test -n "$GCC" && test "$USE_MAINTAINER_MODE" = "yes" && \
DEBUG_CFLAGS="$DEBUG_CFLAGS -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations"
else
AC_DEFINE(ZEND_DEBUG,0,[ ])
fi
test -n "$DEBUG_CFLAGS" && CFLAGS="$CFLAGS $DEBUG_CFLAGS"
if test "$ZEND_MAINTAINER_ZTS" = "yes"; then
AC_DEFINE(ZTS,1,[ ])
CFLAGS="$CFLAGS -DZTS"
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]*//`
else
INLINE_CFLAGS="$CFLAGS"
fi
changequote([,])
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.
AC_MSG_CHECKING(for MM alignment and log values)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
typedef union _mm_align_test {
void *ptr;
double dbl;
long lng;
} mm_align_test;
#if (defined (__GNUC__) && __GNUC__ >= 2)
#define ZEND_MM_ALIGNMENT (__alignof__ (mm_align_test))
#else
#define ZEND_MM_ALIGNMENT (sizeof(mm_align_test))
#endif
int main()
{
int i = ZEND_MM_ALIGNMENT;
int zeros = 0;
FILE *fp;
while (i & ~0x1) {
zeros++;
i = i >> 1;
}
fp = fopen("conftest.zend", "w");
fprintf(fp, "%d %d\n", ZEND_MM_ALIGNMENT, zeros);
fclose(fp);
exit(0);
}
]])], [
LIBZEND_MM_ALIGN=`cat conftest.zend | cut -d ' ' -f 1`
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_RUN_IFELSE([AC_LANG_SOURCE([[
#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_RUN_IFELSE([AC_LANG_SOURCE([[
#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,
[ --disable-zend-signals whether to enable zend signal handling],[
ZEND_SIGNALS=$enableval
],[
ZEND_SIGNALS=yes
])
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_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)
fi
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
AC_ARG_ENABLE(gcc-global-regs,
[ --disable-gcc-global-regs
whether to enable GCC global register variables],[
ZEND_GCC_GLOBAL_REGS=$enableval
],[
ZEND_GCC_GLOBAL_REGS=yes
])
AC_MSG_CHECKING(for global register variables support)
if test "$ZEND_GCC_GLOBAL_REGS" != "no"; then
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#if defined(__GNUC__)
# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#else
# define ZEND_GCC_VERSION 0
#endif
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(i386)
# define ZEND_VM_FP_GLOBAL_REG "%esi"
# define ZEND_VM_IP_GLOBAL_REG "%edi"
#elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__x86_64__)
# define ZEND_VM_FP_GLOBAL_REG "%r14"
# define ZEND_VM_IP_GLOBAL_REG "%r15"
#elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__powerpc64__)
# define ZEND_VM_FP_GLOBAL_REG "r28"
# define ZEND_VM_IP_GLOBAL_REG "r29"
#elif defined(__IBMC__) && ZEND_GCC_VERSION >= 4002 && defined(__powerpc64__)
# define ZEND_VM_FP_GLOBAL_REG "r28"
# define ZEND_VM_IP_GLOBAL_REG "r29"
#else
# error "global register variables are not supported"
#endif
typedef int (*opcode_handler_t)(void);
register void *FP __asm__(ZEND_VM_FP_GLOBAL_REG);
register const opcode_handler_t *IP __asm__(ZEND_VM_IP_GLOBAL_REG);
int emu(const opcode_handler_t *ip, void *fp) {
const opcode_handler_t *orig_ip = IP;
void *orig_fp = FP;
IP = ip;
FP = fp;
while ((*ip)());
FP = orig_fp;
IP = orig_ip;
}
]], [[
]])], [
ZEND_GCC_GLOBAL_REGS=yes
], [
ZEND_GCC_GLOBAL_REGS=no
])
fi
if test "$ZEND_GCC_GLOBAL_REGS" = "yes"; then
AC_DEFINE([HAVE_GCC_GLOBAL_REGS], 1, [Define if the target system has support for global register variables])
else
HAVE_GCC_GLOBAL_REGS=no
fi
AC_MSG_RESULT($ZEND_GCC_GLOBAL_REGS)
dnl
dnl Check if atof() accepts NAN
dnl
AC_CACHE_CHECK(whether atof() accepts NAN, ac_cv_atof_accept_nan,[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <math.h>
#include <stdlib.h>
#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
int main(int argc, char** argv)
{
return zend_isnan(atof("NAN")) ? 0 : 1;
}
]])],[
ac_cv_atof_accept_nan=yes
],[
ac_cv_atof_accept_nan=no
],[
ac_cv_atof_accept_nan=no
])])
if test "$ac_cv_atof_accept_nan" = "yes"; then
AC_DEFINE([HAVE_ATOF_ACCEPTS_NAN], 1, [whether atof() accepts NAN])
fi
dnl
dnl Check if atof() accepts INF
dnl
AC_CACHE_CHECK(whether atof() accepts INF, ac_cv_atof_accept_inf,[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <math.h>
#include <stdlib.h>
#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
int main(int argc, char** argv)
{
return zend_isinf(atof("INF")) && zend_isinf(atof("-INF")) ? 0 : 1;
}
]])],[
ac_cv_atof_accept_inf=yes
],[
ac_cv_atof_accept_inf=no
],[
ac_cv_atof_accept_inf=no
])])
if test "$ac_cv_atof_accept_inf" = "yes"; then
AC_DEFINE([HAVE_ATOF_ACCEPTS_INF], 1, [whether atof() accepts INF])
fi
dnl
dnl Check if HUGE_VAL == INF
dnl
AC_CACHE_CHECK(whether HUGE_VAL == INF, ac_cv_huge_val_inf,[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <math.h>
#include <stdlib.h>
#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
int main(int argc, char** argv)
{
return zend_isinf(HUGE_VAL) ? 0 : 1;
}
]])],[
ac_cv_huge_val_inf=yes
],[
ac_cv_huge_val_inf=no
],[
ac_cv_huge_val_inf=yes
])])
dnl This is the most probable fallback so we assume yes in case of cross compile.
if test "$ac_cv_huge_val_inf" = "yes"; then
AC_DEFINE([HAVE_HUGE_VAL_INF], 1, [whether HUGE_VAL == INF])
fi
dnl
dnl Check if HUGE_VAL + -HUGEVAL == NAN
dnl
AC_CACHE_CHECK(whether HUGE_VAL + -HUGEVAL == NAN, ac_cv_huge_val_nan,[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <math.h>
#include <stdlib.h>
#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
int main(int argc, char** argv)
{
#if defined(__sparc__) && !(__GNUC__ >= 3)
/* prevent bug #27830 */
return 1;
#else
return zend_isnan(HUGE_VAL + -HUGE_VAL) ? 0 : 1;
#endif
}
]])],[
ac_cv_huge_val_nan=yes
],[
ac_cv_huge_val_nan=no
],[
ac_cv_huge_val_nan=yes
])])
dnl This is the most probable fallback so we assume yes in case of cross compile.
if test "$ac_cv_huge_val_nan" = "yes"; then
AC_DEFINE([HAVE_HUGE_VAL_NAN], 1, [whether HUGE_VAL + -HUGEVAL == NAN])
fi
dnl
dnl Check whether __cpuid_count is available
dnl
AC_CACHE_CHECK(whether __cpuid_count is available, ac_cv_cpuid_count_available, [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <cpuid.h>
]], [[
unsigned eax, ebx, ecx, edx;
__cpuid_count(0, 0, eax, ebx, ecx, edx);
]])], [
ac_cv_cpuid_count_available=yes
], [
ac_cv_cpuid_count_available=no
])])
if test "$ac_cv_cpuid_count_available" = "yes"; then
AC_DEFINE([HAVE_CPUID_COUNT], 1, [whether __cpuid_count is available])
fi
-225
View File
@@ -1,225 +0,0 @@
dnl This file contains local autoconf functions.
AC_DEFUN([LIBZEND_BISON_CHECK],[
# we only support certain bison versions;
# min: 2.4 (i.e. 204, major * 100 + minor for easier comparison)
bison_version_min="204"
# non-working versions, e.g. "3.0 3.2";
# remove "none" when introducing the first incompatible bison version an
# separate any following additions by spaces
bison_version_exclude=""
# 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=`$YACC --version 2> /dev/null | grep 'GNU Bison' | cut -d ' ' -f 4 | $SED -e 's/\./ /g' | tr -d a-z`
php_cv_bison_version=invalid
if test -n "$bison_version_vars"; then
set $bison_version_vars
bison_version="${1}.${2}"
bison_version_num="`expr ${1} \* 100 + ${2}`"
if test $bison_version_num -ge $bison_version_min; then
php_cv_bison_version="$bison_version (ok)"
for bison_check_version in $bison_version_exclude; do
if test "$bison_version" = "$bison_check_version"; then
php_cv_bison_version=invalid
break
fi
done
fi
fi
])
fi
case $php_cv_bison_version in
""|invalid[)]
bison_msg="This bison version is not supported for regeneration of the Zend/PHP parsers (found: $bison_version, min: $bison_version_min, excluded: $bison_version_exclude)."
AC_MSG_WARN([$bison_msg])
YACC="exit 0;"
;;
esac
])
AC_DEFUN([ZEND_FP_EXCEPT],[
AC_CACHE_CHECK(whether fp_except is defined, ac_cv_type_fp_except,[
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <floatingpoint.h>
]],[[
fp_except x = (fp_except) 0;
]])],[
ac_cv_type_fp_except=yes
],[
ac_cv_type_fp_except=no
])])
if test "$ac_cv_type_fp_except" = "yes"; then
AC_DEFINE(HAVE_FP_EXCEPT, 1, [whether floatingpoint.h defines fp_except])
fi
])
dnl
dnl Check for broken sprintf()
dnl
AC_DEFUN([AC_ZEND_BROKEN_SPRINTF],[
AC_CACHE_CHECK(whether sprintf is broken, ac_cv_broken_sprintf,[
AC_RUN_IFELSE([AC_LANG_SOURCE([[main() {char buf[20];exit(sprintf(buf,"testing 123")!=11); }]])],[
ac_cv_broken_sprintf=no
],[
ac_cv_broken_sprintf=yes
],[
ac_cv_broken_sprintf=no
])
])
if test "$ac_cv_broken_sprintf" = "yes"; then
ac_result=1
else
ac_result=0
fi
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_RUN_IFELSE([AC_LANG_SOURCE([[
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, 1, [Define if processor uses big-endian word])
fi
])
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_LINK_IFELSE([AC_LANG_PROGRAM([[
#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_LINK_IFELSE([AC_LANG_PROGRAM([[
#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_LINK_IFELSE([AC_LANG_PROGRAM([[
#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_LINK_IFELSE([AC_LANG_PROGRAM([[
#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_LINK_IFELSE([AC_LANG_PROGRAM([[
/* 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
View File
@@ -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 gethrtime()
{
$hrtime = hrtime();
return (($hrtime[0]*1000000000 + $hrtime[1]) / 1000000000);
}
function start_test()
{
ob_start();
return gethrtime();
}
function end_test($start, $name)
{
global $total;
$end = gethrtime();
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 gethrtime();
}
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();
?>
-41
View File
@@ -1,41 +0,0 @@
# Makefile to generate build tools
#
# Standard usage:
# make -f build.mk
#
# Written by Sascha Schumann
LT_TARGETS = ltmain.sh ltconfig
config_h_in = zend_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.ac acinclude.m4
aclocal
$(config_h_in): configure.ac
# explicitly remove target since autoheader does not seem to work
# correctly otherwise (timestamps are not updated)
@rm -f $@
autoheader
configure: aclocal.m4 configure.ac
autoconf
-32
View File
@@ -1,32 +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
-133
View File
@@ -1,133 +0,0 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(zend.c)
AM_INIT_AUTOMAKE(zend, 0.80A, nodefine)
AM_CONFIG_HEADER(zend_config.h)
AM_SANITY_CHECK
AM_MAINTAINER_MODE
AC_PROG_CC
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
])
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>
#ifndef zend_isnan
#if HAVE_DECL_ISNAN && (!defined(__cplusplus) || __cplusplus < 201103L)
#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) ((a) != (a))
#endif
#endif
#if HAVE_DECL_ISINF && (!defined(__cplusplus) || __cplusplus < 201103L)
#define zend_isinf(a) isinf(a)
#elif defined(INFINITY)
/* Might not work, but is required by ISO C99 */
#define zend_isinf(a) (((a)==INFINITY || (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
#if HAVE_DECL_ISFINITE && (!defined(__cplusplus) || __cplusplus < 201103L)
#define zend_finite(a) isfinite(a)
#elif defined(HAVE_FINITE)
#define zend_finite(a) finite(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 */
])
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
LIBZEND_LIBDL_CHECKS
LIBZEND_DLSYM_CHECK
AM_PROG_LIBTOOL
if test "$enable_debug" != "yes"; then
AM_SET_LIBTOOL_VARIABLE([--silent])
fi
dnl
dnl Check for /usr/pkg/{lib,include} which is where NetBSD puts binary
dnl and source packages. This should be harmless on other OSs.
dnl
if test -d /usr/pkg/include -a -d /usr/pkg/lib ; then
CFLAGS="$CFLAGS -I/usr/pkg/include"
LDFLAGS="$LDFLAGS -L/usr/pkg/lib"
fi
LIBZEND_ENABLE_DEBUG
LIBZEND_OTHER_CHECKS
ZEND_EXTRA_LIBS="$LIBS"
LIBS=""
AC_SUBST(ZEND_EXTRA_LIBS)
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
# Local Variables:
# tab-width: 4
# End:
-17
View File
@@ -1,17 +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: |
+----------------------------------------------------------------------+
*/
-358
View File
@@ -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 gethrtime()
{
$hrtime = hrtime();
return (($hrtime[0]*1000000000 + $hrtime[1]) / 1000000000);
}
function start_test()
{
ob_start();
return gethrtime();
}
function end_test($start, $name, $overhead = null)
{
global $total;
global $last_time;
$end = gethrtime();
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 gethrtime();
}
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");
-59
View File
@@ -1,59 +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);
try {
test2();
} catch (Throwable $e) {
echo "Exception: " . $e->getMessage() . "\n";
}
test3(1,2);
call_user_func("test1");
try {
call_user_func("test3", 1);
} catch (Throwable $e) {
echo "Exception: " . $e->getMessage() . "\n";
}
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)
Exception: Too few arguments to function test2(), 0 passed in %s001.php on line 18 and exactly 1 expected
int(2)
int(0)
Exception: Too few arguments to function test3(), 1 passed in %s001.php on line 27 and exactly 2 expected
int(2)
int(1)
Warning: func_num_args(): Called from the global scope - no function context in %s on line %d
int(-1)
Done
-101
View File
@@ -1,101 +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);
try {
test2();
} catch (Throwable $e) {
echo "Exception: " . $e->getMessage() . "\n";
}
test3(1,2);
call_user_func("test1");
try {
call_user_func("test3", 1);
} catch (Throwable $e) {
echo "Exception: " . $e->getMessage() . "\n";
}
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)
Exception: Too few arguments to function test2(), 0 passed in %s002.php on line %d and exactly 1 expected
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)
Exception: Too few arguments to function test3(), 1 passed in %s002.php on line %d and exactly 2 expected
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
-81
View File
@@ -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);
try {
test2();
} catch (Throwable $e) {
echo "Exception: " . $e->getMessage() . "\n";
}
test3(1,2);
call_user_func("test1");
try {
call_user_func("test3", 1);
} catch (Throwable $e) {
echo "Exception: " . $e->getMessage() . "\n";
}
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)
}
Exception: Too few arguments to function test2(), 0 passed in %s003.php on line %d and exactly 1 expected
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}
array(0) {
}
Exception: Too few arguments to function test3(), 1 passed in %s003.php on line %d and exactly 2 expected
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
-25
View File
@@ -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
-27
View File
@@ -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
-31
View File
@@ -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
-65
View File
@@ -1,65 +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
Deprecated: The each() function is deprecated. This message will be suppressed on further calls in %s on line %d
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
-53
View File
@@ -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", fopen(__FILE__, 'r')));
var_dump(define("test2", 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 bool, 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)
bool(true)
bool(true)
Warning: Constants may only evaluate to scalar values, arrays or resources in %s on line %d
bool(false)
int(1)
int(2)
int(3)
Done
-57
View File
@@ -1,57 +0,0 @@
--TEST--
get_class() tests
--FILE--
<?php
class foo {
function bar () {
var_dump(get_class());
}
function testNull ()
{
var_dump(get_class(null));
}
}
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));
$f1->testNull();
echo "Done\n";
?>
--EXPECTF--
Deprecated: Non-static method foo::bar() should not be called statically in %s on line %d
string(3) "foo"
Deprecated: 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"
Warning: get_class() expects parameter 1 to be object, null given in %s on line %d
bool(false)
Done
-59
View File
@@ -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";
?>
--EXPECT--
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
-89
View File
@@ -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
-34
View File
@@ -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
-34
View File
@@ -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
-3
View File
@@ -1,3 +0,0 @@
<?php
/* dummy file for 014.phpt */
?>
-52
View File
@@ -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
-37
View File
@@ -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
-12
View File
@@ -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
Loaded 100 of 21138 files, more files were not shown because too many files have changed in this diff. Show more