Compare commits

..
455 Commits
Author SHA1 Message Date
SVN Migration a5e8df44b1 This commit was manufactured by cvs2svn to create tag 'php_4_3_1'. 2003-02-16 14:48:28 +00:00
foobar 50febaf842 BFN 2003-02-16 14:48:27 +00:00
foobar 8c93651a60 revert this 2003-02-15 22:56:04 +00:00
foobar 9d6e343cc5 Revert this. 2003-02-15 22:51:43 +00:00
foobar 0f41757dfa - correct version plus the fix. 2003-02-15 21:41:38 +00:00
Edin Kadribasic cec89cfd76 New version number. 2003-02-15 21:37:42 +00:00
SVN Migration 652c5076f2 This commit was manufactured by cvs2svn to create branch 'PHP_4_3_1'. 2002-12-27 04:47:48 +00:00
Ilia Alshanetsky 8ef253d9dc MFH 2002-12-27 04:47:45 +00:00
Andrei Zmievski d91ac3b7b8 Go with 4.3.0. 2002-12-27 04:07:19 +00:00
08f7cfae71 Update. 2002-12-27 04:02:52 +00:00
dd734b5a5d update 2002-12-27 04:00:09 +00:00
Sterling Hughes d8b14bd700 mfh 2002-12-27 03:22:42 +00:00
Andrei Zmievski 4e395f36af MFH 2002-12-27 03:22:13 +00:00
Edin Kadribasic b9ad07ca0b MFB:
Mention the fact that zlib extension is now built-in in win32 distro.
2002-12-27 03:17:17 +00:00
Georg Richter 6497cc956c ISO-8601 bug, typo 2002-12-27 00:21:17 +00:00
Ilia Alshanetsky ee3e6f12ae MFH 2002-12-27 00:09:35 +00:00
Derick Rethans 4f7f46d0b8 All on one line 2002-12-26 23:41:59 +00:00
Derick Rethans 991ca2274f - update credits 2002-12-26 23:39:51 +00:00
Georg Richter b72ea915ab added Wez, Ilia and myself 2002-12-26 23:36:57 +00:00
Wez Furlong 055f1f483e MFH: get_meta_tags() stream leak 2002-12-26 22:36:21 +00:00
Georg Richter a493c51949 fixed some compiler warnings when using external libmysqlclient 4.x 2002-12-26 13:47:59 +00:00
Edin Kadribasic 45cb9dc7b1 Made ZLIB extension built in on Windows. Fixes #21139.
# Approved by the release master.
# Will merge this patch into HEAD a bit later.
2002-12-26 13:27:08 +00:00
George Schlossnagle 45f5605f38 mfh (bug #21177) 2002-12-25 21:14:55 +00:00
Derick Rethans 6c3558c2ac - MFH: Test for bug #21182 2002-12-25 20:11:38 +00:00
SVN Migration 0dd36fd9f5 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-12-25 20:08:37 +00:00
Moriyoshi Koizumi d07f529652 Fixed bug #21182 2002-12-25 20:00:12 +00:00
Stefan Esser cb6d34ee25 MFH 2002-12-24 23:50:21 +00:00
Stefan Esser 00cc762934 MFH 2002-12-24 23:30:51 +00:00
Melvyn Sopacua 409f64d09d MFH: crash fix in glob() with no results 2002-12-24 15:04:10 +00:00
Stefan Esser 5367710045 MFH 2002-12-23 08:51:16 +00:00
Stefan Esser e5343487ac MFH: fix compile error with IRIX compiler 2002-12-23 08:43:13 +00:00
Edin Kadribasic f0e94729bf Ignore the new name of the binary built. Allows cvsclean to work again
in sapi/cgi.
2002-12-23 03:34:23 +00:00
Wez Furlong 673dee58ad fpos_t should have been off_t.
Noticed by Philip Olson.
2002-12-23 02:55:29 +00:00
Ilia Alshanetsky 9b16b3d7b8 MFH 2002-12-22 20:58:27 +00:00
Ilia Alshanetsky 51a711b609 MFH (fix for bug #21146).
# Approved by Andrei
2002-12-22 19:45:21 +00:00
Moriyoshi Koizumi 022e5db8ec MFH: php_error => php_error_docref 2002-12-22 19:16:42 +00:00
Moriyoshi Koizumi a29eb8c1d2 MFH: WS fix 2002-12-22 19:06:29 +00:00
Moriyoshi Koizumi c16bb3d7c9 MFH 2002-12-22 19:03:14 +00:00
Wez Furlong aaba243f41 MFH fix for Bug #21131 2002-12-22 18:21:55 +00:00
SVN Migration 41226129d7 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-12-22 18:06:28 +00:00
Wez Furlong 17384705d3 MFH:
A Simple fix for Bug #12360 (fsockopen timeout doesn't work).

Analysis:
On systems with HAVE_GETADDRINFO and IPV6 support, php_hostconnect would
attempt to connect to each possible address that matched the requested IP.

If the remote host:port combination are dropping packets this would cause the
first connection to timeout (after waiting for the full timeout duration).

PHP would then attempt the second address and wait the full duration again.

Solution:
If the first connection attempt times out, abort the connection loop.
2002-12-22 13:58:41 +00:00
Stig Bakken 5e489050e1 MFH 2002-12-22 01:43:20 +00:00
Frank M. Kromann 4100b87e38 MFH 2002-12-21 22:44:38 +00:00
Edin Kadribasic 5f6f1ab107 Updated list of bundled windows extensions compiled by
Christoph Grottolo <cg@gordimer.net>
2002-12-21 22:16:35 +00:00
Edin Kadribasic de713235ed Reflect recent changes to the build process. 2002-12-21 22:03:46 +00:00
Moriyoshi Koizumi 6e2cd3fcfe MFH: Made auth information inaccessible under safe mode 2002-12-21 21:52:41 +00:00
Melvyn Sopacua b686c05f3b There won't be a warning/fix on this, so remove the test 2002-12-21 21:01:26 +00:00
Ilia Alshanetsky 174f00fe03 Bug fixing news 2002-12-21 20:36:14 +00:00
Ilia Alshanetsky 4f1947c729 MFH 2002-12-21 20:34:36 +00:00
Andrei Zmievski 50c811c210 *** empty log message *** 2002-12-21 20:11:05 +00:00
Andrei Zmievski 614614c89e Make PHP_AUTH_* variables not available in safe mode under Apache. Patch by
Philip Olson.
2002-12-21 20:09:09 +00:00
Derick Rethans 4de8da30d0 - Fix typo 2002-12-21 17:46:32 +00:00
Melvyn Sopacua 2e23a75ff4 Skip the test, until a proper descision is made 2002-12-21 16:54:07 +00:00
Andrei Zmievski 02a5c36cb9 Back to -dev. 2002-12-21 01:34:15 +00:00
Andrei Zmievski f380b6b5da Go with RC4. 2002-12-21 01:30:20 +00:00
Andrei Zmievski 641bf4653a MFH 2002-12-21 01:20:32 +00:00
Marcus Boerger fd7b8ff912 MFH: as discussed 2002-12-20 20:25:19 +00:00
Stefan Esser 4dd722e870 MFH 2002-12-20 19:37:45 +00:00
Frank M. Kromann 25e38548cb MFH 2002-12-20 18:41:19 +00:00
Frank M. Kromann d8f5916a72 MFH 2002-12-20 17:39:30 +00:00
Marcus Boerger b27ae49ada Avoid compiler warnings 2002-12-20 17:03:37 +00:00
Andrei Zmievski 7c9dd72b76 MFH 2002-12-20 16:47:15 +00:00
Marcus Boerger 95b4b3ea3e MFH 2002-12-20 16:37:44 +00:00
Moriyoshi Koizumi 2615ec3dee MFH 2002-12-20 15:52:49 +00:00
Sterling Hughes e4871a4a2c mfh 2002-12-20 15:45:53 +00:00
Edin Kadribasic 0dbe08cba2 Make sure cli install dir is created before trying to install in it. 2002-12-20 10:04:55 +00:00
Ilia Alshanetsky f81e612976 MFH 2002-12-20 03:44:41 +00:00
Melvyn Sopacua 2e828c812c Fix libtool detection 2002-12-20 00:25:56 +00:00
Wez Furlong 3748fb07e8 MFH fix for bug #21077.
(proc_open problems with BSD)
2002-12-19 20:34:34 +00:00
Edin Kadribasic 251c2a2383 Making windows build system changes according to proposal:
http://news.php.net/article.php?group=php.dev&article=92682
2002-12-19 18:11:58 +00:00
Ilia Alshanetsky 6cf87a7740 MFH 2002-12-19 17:07:24 +00:00
Edin Kadribasic 83638d2232 Making build system changes according to proposal:
http://news.php.net/article.php?group=php.dev&article=92682
2002-12-19 16:55:57 +00:00
Moriyoshi Koizumi af69bece5b MFH 2002-12-19 15:29:38 +00:00
Edin Kadribasic 58637340e8 Removed libtool library from link which is no longer needed. This fixes
windows build.
2002-12-19 10:37:45 +00:00
Edin Kadribasic a3d0b7e43f Reverted previous patch as suggested by Andi. (reopening #20539). 2002-12-19 00:11:32 +00:00
Moriyoshi Koizumi 07391c8f28 MFH 2002-12-18 23:08:22 +00:00
Moriyoshi Koizumi 90741703de MFH: added a test case for bug #20539 2002-12-18 22:55:16 +00:00
SVN Migration a962c4e340 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-12-18 22:54:35 +00:00
Frank M. Kromann 20da71fb75 MFH 2002-12-18 07:06:36 +00:00
Derick Rethans e8295e70af - MFH 2002-12-17 19:08:01 +00:00
Moriyoshi Koizumi 8954a0486c MFH: iconv extension is no longer experimental 2002-12-17 13:34:23 +00:00
Marcus Boerger c36139bd55 MFH 2002-12-16 17:53:15 +00:00
Marcus Boerger 41335dc90f MFH 2002-12-16 15:54:04 +00:00
Ilia Alshanetsky 33ccce8047 MFH 2002-12-16 15:44:06 +00:00
Ilia Alshanetsky 5b71dbb4e2 MFH (memory leak). 2002-12-16 15:30:51 +00:00
Marcus Boerger 375cf41b62 MFH: that silly dot 2002-12-16 14:55:26 +00:00
Marcus Boerger f142b06770 MFH 2002-12-16 14:48:20 +00:00
Derick Rethans e88e587c30 - Fix typo 2002-12-16 09:11:15 +00:00
Derick Rethans 15c23426d8 - Update NEWS 2002-12-16 09:10:17 +00:00
Derick Rethans bd59a23e0a - Fix bug #21039
#- This is somewhat of a hack, and thus I will not merge it to HEAD, as
#  I've lots of other commits waiting for that.
2002-12-16 09:03:11 +00:00
Marcus Boerger ddc78bc5c0 MFH 2002-12-14 19:53:52 +00:00
Marcus Boerger 8cd8c85017 MFH: bugfix: #21010 2002-12-14 17:50:57 +00:00
foobar d88973feba Fixed bug: #20995 2002-12-14 09:32:49 +00:00
Melvyn Sopacua 5410ce07eb MFH 2002-12-13 18:46:14 +00:00
SVN Migration 4e855de5ae This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-12-13 18:40:40 +00:00
Vlad Krupin 9053c5eadd MFH fix for bug 19727 2002-12-13 16:54:49 +00:00
Marcus Boerger 016d0be3e0 MFH 2002-12-13 13:34:37 +00:00
Marcus Boerger 97b8a7cd4d MFH 2002-12-13 12:06:00 +00:00
Stig Bakken 37f5e2f175 MFH 2002-12-13 02:22:41 +00:00
Stig Bakken 40ebc2a27b MFH 2002-12-13 02:14:26 +00:00
Moriyoshi Koizumi 80f831e167 Forgot to prepend "SKIP" 2002-12-12 21:44:27 +00:00
Moriyoshi Koizumi 7e85b2bdde MFH 2002-12-12 21:42:51 +00:00
SVN Migration 6cd84e1a15 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-12-12 21:42:18 +00:00
Stefan Esser f65be7ff50 MFH: finally?! correct 2002-12-12 21:31:57 +00:00
Ilia Alshanetsky 7095c25d75 MFH 2002-12-12 21:17:55 +00:00
Ilia Alshanetsky 7df75cd38f MFH 2002-12-12 18:51:02 +00:00
Ilia Alshanetsky 58613036fb Fixed ZTS build. 2002-12-12 18:36:44 +00:00
Wez Furlong 27cdd59feb Fix some issues with the return value from pclose and proc_close,
and bogus seek-on-pipe warnings when used with fpassthru.
2002-12-12 17:44:48 +00:00
Ilia Alshanetsky 9baa62f093 MFH 2002-12-12 16:14:07 +00:00
Wez Furlong e651db5cf1 MFH more entropy "fix" 2002-12-12 15:51:11 +00:00
Ilia Alshanetsky 0314da12d0 MFH 2002-12-12 14:52:09 +00:00
Wez Furlong 4789b8eb3b Collect streams related changes into one place, as requested by Jani. 2002-12-12 14:39:07 +00:00
Marcus Boerger e549631cee MFH 2002-12-12 14:16:16 +00:00
Ilia Alshanetsky 5d0ac38b24 MFH 2002-12-12 13:52:37 +00:00
Wez Furlong a50bd94a0e MFH #20936 fix 2002-12-12 13:46:29 +00:00
Moriyoshi Koizumi fc410b16fc MFH 2002-12-12 13:46:10 +00:00
Ilia Alshanetsky e730be9eec MFH 2002-12-12 13:45:34 +00:00
SVN Migration a55180af39 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-12-12 13:38:20 +00:00
Moriyoshi Koizumi 21f011822d MFH: Fixed bug #20934 (htmlspecialchars returns latin1 from UTF-8) 2002-12-12 13:27:17 +00:00
Marcus Boerger 9e7b94e7c1 MFH 2002-12-12 13:23:28 +00:00
Marcus Boerger 16eac635ae MFH: ws, php_error_docref, typeconversion for cygwin 2002-12-12 13:21:25 +00:00
Marcus Boerger 41ffdb4fc4 MFH 2002-12-12 13:14:40 +00:00
Edin Kadribasic 508a9c3ebd Fixed bug #20485 (added flags to windows build to compile DOM/XSLT). 2002-12-12 10:09:17 +00:00
Ilia Alshanetsky a840f429e7 MFH (make imagecreatefromxpm() unavailable when bundled GD is used) 2002-12-11 23:30:23 +00:00
Ilia Alshanetsky 359a28fc69 MFH 2002-12-11 22:37:35 +00:00
Derick Rethans ebb708b068 - Make it also work when you press enter instead of typing 'y' 2002-12-11 20:10:57 +00:00
Ilia Alshanetsky d6fed23482 MFH 2002-12-11 20:08:02 +00:00
Andrei Zmievski 27c7538eb2 Back to -dev. 2002-12-11 18:57:24 +00:00
Andrei Zmievski 9aee6dce1a Go for RC3. 2002-12-11 18:52:20 +00:00
Ilia Alshanetsky 9147eae986 MFH 2002-12-11 17:39:42 +00:00
SVN Migration be0abad331 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-12-11 17:38:29 +00:00
Ilia Alshanetsky 47fa22b5cf MFH 2002-12-11 16:49:27 +00:00
foobar b85d1443b7 MFH 2002-12-11 15:16:29 +00:00
foobar afae8d98c5 MFH 2002-12-11 14:45:46 +00:00
foobar 373784fb86 missing file 2002-12-11 14:43:04 +00:00
Rui Hirokawa 51b63d6b5a fixed lack of variable initialization bug. 2002-12-11 14:41:09 +00:00
Marcus Boerger 6003d9ad36 MFH 2002-12-11 10:37:53 +00:00
Edin Kadribasic 120f6a9bf2 MFH: Fix for #20539 (patch by Moriyoshi Koizumi). 2002-12-11 10:29:07 +00:00
foobar 9ba824a27a MFH 2002-12-11 08:54:22 +00:00
foobar ccde6eef9c MFH: fix from 3.23.54 2002-12-11 08:52:17 +00:00
foobar 93f50df68d MFH: Fix for bug #20928 2002-12-11 08:42:07 +00:00
Ilia Alshanetsky 4cc3aa052d MFH 2002-12-11 02:51:26 +00:00
Ilia Alshanetsky b9c7ee9733 MFH 2002-12-11 00:32:37 +00:00
Marcus Boerger 0b3d1b1e47 MFH 2002-12-10 23:03:24 +00:00
Wez Furlong bd77e7d0f8 No longer experimental. 2002-12-10 22:20:55 +00:00
Wez Furlong 5d9bc065f5 Fix proto and avoid potential segfault on an error. 2002-12-10 22:04:44 +00:00
Stefan Esser 147e4bc66f MFH 2002-12-10 20:19:13 +00:00
Marcus Boerger d71fc18027 MFH 2002-12-10 20:12:38 +00:00
Ilia Alshanetsky 065b04628f MFH 2002-12-10 18:01:33 +00:00
Edin Kadribasic b2131fd973 Fix ZTS build. 2002-12-10 16:56:23 +00:00
Ilia Alshanetsky 507b8cd4ba Fix for bug #20831. 2002-12-10 16:37:48 +00:00
foobar 3fbd4431f9 MFH: added the version check 2002-12-10 16:34:48 +00:00
Edin Kadribasic 12cbd70562 Improve UNC path detection. 2002-12-10 16:18:59 +00:00
Ilia Alshanetsky c69e47414c MFH 2002-12-10 15:59:17 +00:00
Stefan Esser e085d9bccb MFH 2002-12-10 15:41:39 +00:00
Ilia Alshanetsky a7047d2243 MFH 2002-12-10 15:37:33 +00:00
Marcus Boerger a984c1329f MFH 2002-12-10 14:35:36 +00:00
Ilia Alshanetsky db403663f7 MFH 2002-12-10 00:10:37 +00:00
foobar 75a30c7233 MFH 2002-12-09 19:16:12 +00:00
Ilia Alshanetsky fdc3a171dc MFH 2002-12-09 18:45:37 +00:00
Wez Furlong f57ac2fa05 Centralize the fopencookie test. 2002-12-09 18:28:03 +00:00
Wez Furlong b2a98beaee No need to compile this code if curl streams are not enabled, which they
cannot be in 4.3 (configure option is disabled and they don't work yet anyway).
2002-12-09 18:25:37 +00:00
Marcus Boerger 753450e21e MFH: '-' modifier (bug #20282, #20858) 2002-12-09 18:07:23 +00:00
Melvyn Sopacua c81b7d7156 MFH: fix make install target on Cygwin 2002-12-09 17:25:01 +00:00
Wez Furlong f116d23398 MFH: fopencookie for BSD patch 2002-12-09 16:22:06 +00:00
Edin Kadribasic 0d9704fa7b Fixed crash in socket_read on windows #20894 (patch by Wez Furlong). 2002-12-09 11:29:31 +00:00
Wez Furlong 5650d9fdd1 Fix for bug #20831; include() from UNC paths does not work. 2002-12-09 10:34:32 +00:00
Timm Friebe da3e324e7f - MFH 2002-12-08 15:40:18 +00:00
Ilia Alshanetsky 7cf0a8601a MFH 2002-12-07 16:16:09 +00:00
Ilia Alshanetsky e2e2111b1c MFH 2002-12-07 16:06:40 +00:00
foobar 55320820ba Bug fixes for new stuff do not belong in NEWS.. 2002-12-07 12:12:24 +00:00
Sander Roobol 9af1962986 MFH 2002-12-07 11:21:52 +00:00
Frank M. Kromann 675d254b15 MFH 2002-12-07 06:05:52 +00:00
Ilia Alshanetsky 9901a6f0cd MFH 2002-12-07 00:48:21 +00:00
Frank M. Kromann 3a70279b7d MFH 2002-12-06 22:57:47 +00:00
Ilia Alshanetsky ae635f837b MFH 2002-12-06 17:46:40 +00:00
SVN Migration e8fe75a589 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-12-06 17:46:27 +00:00
Ilia Alshanetsky 14dbf42db8 MFH 2002-12-06 17:36:25 +00:00
Sebastian Bergmann 5c29f19331 MFH 2002-12-06 06:09:44 +00:00
Ilia Alshanetsky c185f97956 MFH 2002-12-06 06:08:21 +00:00
Stig Bakken 1652d1f3b4 MFH 2002-12-06 00:10:40 +00:00
Ilia Alshanetsky 02f9791e19 Fixed memory leaks inside heb_number_to_chars(). 2002-12-05 23:19:03 +00:00
Marcus Boerger a27d6d90ec MFH 2002-12-05 23:19:02 +00:00
Ilia Alshanetsky 89d758c378 MFH 2002-12-05 22:46:40 +00:00
Marcus Boerger 335786915a MFH 2002-12-05 22:15:37 +00:00
Marcus Boerger c8ac633540 MFH 2002-12-05 21:09:19 +00:00
Marcus Boerger 81b7c2abc1 MFH: both the check and php_error in the comment 2002-12-05 21:02:02 +00:00
Marcus Boerger a2aed8eff2 MFH 2002-12-05 20:42:05 +00:00
Marcus Boerger e931611837 MFH 2002-12-05 20:14:09 +00:00
Ilia Alshanetsky 898b8673ed MFH 2002-12-05 20:05:20 +00:00
Marcus Boerger 58d49c3af9 MFH 2002-12-05 20:02:21 +00:00
SVN Migration dcfe521fce This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-12-05 20:01:20 +00:00
Marcus Boerger 434d35cf62 MFH 2002-12-05 19:50:40 +00:00
Derick Rethans 6cf9a9015d MFH:
- Renamed snmpv3_* to snmp3_*
- Conversion to php_error_docref
- Whitespace fixes
2002-12-05 19:33:43 +00:00
Marcus Boerger 11eb34e8ee MFH: Remove unnecessary code here 2002-12-05 15:52:35 +00:00
foobar 4eccd8094e MFH 2002-12-05 15:46:41 +00:00
Marcus Boerger f3fba1ee12 MFH: swc & zlib\nMFH: return FALSE 2002-12-05 12:47:22 +00:00
Marcus Boerger 802968443e Fix aggregation with ZE2 in PHP4.3\n#I will not MFB it since aggregation should move to ZEndEngine 2002-12-05 12:44:21 +00:00
Marcus Boerger d50bdd0a16 MFH 2002-12-05 11:38:13 +00:00
Ilia Alshanetsky 80960e148b MFH (build fix, when xpm support is not avaliable). 2002-12-04 23:43:06 +00:00
Ilia Alshanetsky fcbde2dad4 MFH 2002-12-04 21:07:10 +00:00
SVN Migration 9f85f6d66a This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-12-04 21:04:08 +00:00
Ilia Alshanetsky 5ed73ea30b Fixed a typo. 2002-12-04 17:31:23 +00:00
Ilia Alshanetsky 2cf6676651 MFH 2002-12-04 17:29:57 +00:00
Ilia Alshanetsky 2e2e65b576 MFH (truecolor fixes + gdImageTrueColorToPalette() fix). 2002-12-04 17:28:55 +00:00
Moriyoshi Koizumi ebcfd99797 Forgot to merge this part 2002-12-04 17:12:20 +00:00
Moriyoshi Koizumi 3d4145a7e3 MFH 2002-12-04 17:02:20 +00:00
SVN Migration fb93430ba6 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-12-04 17:01:08 +00:00
Moriyoshi Koizumi ba122bc645 MFH: bug fix news 2002-12-04 16:54:59 +00:00
Moriyoshi Koizumi 6e8529a62b MFH: fixed segfaults in array_walk() when keys are passed to cb by reference 2002-12-04 16:44:24 +00:00
Sebastian Bergmann 680d2326a6 MFH 2002-12-04 08:34:24 +00:00
Sebastian Bergmann a6673450df MFH 2002-12-04 08:28:05 +00:00
Frank M. Kromann af51b8fd42 MFH
# Changed php_error() to php_error_docref()
2002-12-03 19:39:54 +00:00
Ilia Alshanetsky 4c1ca75177 MFH 2002-12-03 19:25:55 +00:00
Frank M. Kromann d58428d3bd MFH
# Changed php_error() to php_error_docref()
2002-12-03 19:19:45 +00:00
Frank M. Kromann 03a87edd97 MFH
# Bug #19370
# Allow stored procedures to return multiple results.
2002-12-03 18:59:38 +00:00
Frank M. Kromann 5454f01e04 MFH
# Bug #17593
# Make sure any pending data is released from the server when freeing the result
2002-12-03 18:07:57 +00:00
Edin Kadribasic d88510d0b9 MFH: Allocating enough memory to hold values.
Fix crash when certan stored procedures was called. This caused
     the free_result function to free memory not yet allocated.
2002-12-03 16:09:14 +00:00
Moriyoshi Koizumi bfd27eda54 MFH: fixed leaks in array_walk() 2002-12-03 15:02:55 +00:00
foobar fd65c1661b MFH: Need these libraries for static build 2002-12-03 11:34:33 +00:00
foobar bdf7cdd073 MFH: Fixed build with iPlanet LDAP SDK 5.x 2002-12-03 09:36:31 +00:00
Jason Greene e0018cc874 MFH 2002-12-03 05:46:53 +00:00
Ilia Alshanetsky 314c4c6874 MFH 2002-12-02 07:03:37 +00:00
Ilia Alshanetsky 9ea095c41c MFH 2002-12-02 06:45:57 +00:00
Ilia Alshanetsky 3da7a2c23e MFH 2002-12-02 06:35:51 +00:00
Shane Caraveo f4e68f2504 MFH 2002-12-02 05:25:55 +00:00
Shane Caraveo dab83e9889 MFH 2002-12-02 02:21:01 +00:00
Shane Caraveo e1b7458984 MFH 2002-12-01 23:30:22 +00:00
Shane Caraveo c16d330371 MFH 2002-12-01 23:15:31 +00:00
Frank M. Kromann 8963c524d7 MFH 2002-11-30 21:52:36 +00:00
Ilia Alshanetsky 77b9675c4b MFH 2002-11-30 19:13:28 +00:00
Marcus Boerger bd45fa6a8f MFH: Bug #20433 2002-11-30 18:39:31 +00:00
Christian Stocker 31ee5eca0d MFH (fixed big bad memory leak in xpath objects.) 2002-11-30 10:52:04 +00:00
Moriyoshi Koizumi c5bcca7bab MFH 2002-11-29 18:35:17 +00:00
Sander Roobol 1ec334a99f MFH 2002-11-29 18:05:22 +00:00
Yasuo Ohgaki 073788340b MFH 2002-11-29 17:19:05 +00:00
Derick Rethans 0d90cd59dc - Fix memleak (patch by Oleg.Roitburd@lycos-europe.com)
#- I don't merge this to HEAD right away, as my current development tree
#  has a lot of modifications, of course I did this change there too.
2002-11-29 15:57:39 +00:00
Martin Kraemer fd52bf2bd8 Portability: In C sources, do not use C++ comments 2002-11-29 14:07:28 +00:00
Wez Furlong 61463cbc2a Take this out of here so that the dir can be pruned on checkout. 2002-11-29 13:39:29 +00:00
Christian Stocker f902cf4675 MFH
fix for bug #20389  (no trailing slash in configure option)
2002-11-29 13:32:50 +00:00
Martin Kraemer 9f83137631 Portability fixes (MFH) 2002-11-29 11:15:43 +00:00
Christian Stocker 7c811718a7 MFH
relative xpath queries are already possible
  (use $ctx->xpath_eval($xpath,$contextnode) )
2002-11-29 08:30:05 +00:00
Ilia Alshanetsky 5d51f8ee55 MFH 2002-11-28 14:14:06 +00:00
Sterling Hughes fe3200ed07 MFH 2002-11-27 20:32:26 +00:00
Frank M. Kromann 8c16118248 MFH 2002-11-27 18:54:54 +00:00
Andrei Zmievski b2e297ed27 Back to -dev 2002-11-27 18:53:04 +00:00
Andrei Zmievski 2ebb360d0e Update version to RC2. 2002-11-27 18:51:00 +00:00
Sterling Hughes cc2abd5275 fix memleak 2002-11-27 18:35:43 +00:00
Ilia Alshanetsky 4ec67e7df3 MFH 2002-11-27 06:20:37 +00:00
Frank M. Kromann 3033a27023 MFH 2002-11-27 04:07:02 +00:00
Marcus Boerger ed264ac576 MFH: remove comment 2002-11-27 02:43:21 +00:00
Marcus Boerger 0394a52b81 MFH: Canon fix 2002-11-27 02:38:37 +00:00
Stig Bakken 5301c168e4 MFH 2002-11-27 01:01:25 +00:00
Frank M. Kromann 5ec97e6b22 Convert 0D 0D 0A line breaks to 0D 0A 2002-11-27 00:40:13 +00:00
Frank M. Kromann 3bd2828386 MFH 2002-11-27 00:36:14 +00:00
Stig Bakken 3cc7a5f2a8 MFH 2002-11-26 23:18:08 +00:00
Moriyoshi Koizumi b71f73322a MFH: improved the error reporting portion of array_walk() 2002-11-26 22:14:11 +00:00
Moriyoshi Koizumi 8f73c27ca6 MFH: prevent too many error reports from being displayed 2002-11-26 21:54:33 +00:00
Stig Bakken 1fc6e75705 MFH 2002-11-26 21:53:43 +00:00
Moriyoshi Koizumi 974e2188cc MFH: Fixed incorrect error messages of array_walk() 2002-11-26 21:35:52 +00:00
Stig Bakken aae2d28e7f MFH 2002-11-26 18:24:30 +00:00
Christian Stocker 106c57d48f MFH (Fix for Bug #20639 DomElement->get_elements_by_tagname() doesn't work) 2002-11-26 15:39:13 +00:00
SVN Migration 7801f96096 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-26 12:06:00 +00:00
Yasuo Ohgaki a5d3a242d1 MFH 2002-11-26 02:15:58 +00:00
Stig Bakken 1800daed83 MFH 2002-11-26 01:34:31 +00:00
Stig Bakken 1fc9449e0d MFH 2002-11-26 01:33:36 +00:00
Stig Bakken 9ebf68f5f8 MFH 2002-11-25 23:52:56 +00:00
Ilia Alshanetsky 33b0617d99 Set serialize_handler to php to prevent test failures. 2002-11-25 23:19:19 +00:00
Ilia Alshanetsky e9b28977a5 MFH (fixed a compile failure when --with-xpm-dir is used). 2002-11-25 23:12:15 +00:00
Stefan Esser c15ae34535 MFH 2002-11-25 22:58:26 +00:00
Ilia Alshanetsky 529bfcae52 MFH 2002-11-25 22:01:46 +00:00
Rui Hirokawa d70ac295c4 simplified and a bug fixed in korean encoding conversion table. 2002-11-25 15:23:01 +00:00
Moriyoshi Koizumi d15c493713 Added a further test on mb_parse_str() 2002-11-24 19:48:17 +00:00
Moriyoshi Koizumi 07bec98624 Fixed mb_parse_str() bug pointed out by Yasuo. 2002-11-24 19:21:58 +00:00
foobar f389c07436 fix typo (; instead of :) 2002-11-24 05:14:17 +00:00
Derick Rethans fb90dd014c - MFH: Adjust tests for removed old_function() in Zend Engine 2 2002-11-23 22:08:40 +00:00
Marcus Boerger 3a90b70eac MFH 2002-11-23 21:12:31 +00:00
Marcus Boerger d4cfbfd310 MFH
#This includes the " to ' change but not the added settings which 4.3
#doesn't have.
2002-11-23 17:50:37 +00:00
Moriyoshi Koizumi cd8d0410fd Fixed tab positions
# a bit too late to be notified :)
2002-11-23 11:26:13 +00:00
Moriyoshi Koizumi 2c95d3c427 MFH (imagecolordeallocate() fix) 2002-11-23 05:20:43 +00:00
Marcus Boerger 4c85a6c5ba Fix memleak in debug mode 2002-11-23 01:17:39 +00:00
Marcus Boerger a623b65a98 MFH: Testing default behaviour 2002-11-23 00:56:21 +00:00
SVN Migration 5bc9ba45bf This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-23 00:54:05 +00:00
Rui Hirokawa b4664a5796 fixed some bugs in korean encoding conversion. 2002-11-22 23:37:17 +00:00
Ilia Alshanetsky e7a0f547f8 Added missing declaration. 2002-11-22 22:30:38 +00:00
Ilia Alshanetsky 2ec9fdbe8d MFH 2002-11-22 21:52:59 +00:00
Stefan Esser 293086db3f MFH 2002-11-22 19:35:43 +00:00
Marcus Boerger 435d875a02 MFH 2002-11-22 15:53:01 +00:00
Edin Kadribasic 14d6306385 MFH: Avoid possible buffer overflow. 2002-11-22 15:47:44 +00:00
Marcus Boerger 8ae87f8762 MFH 2002-11-22 15:13:10 +00:00
Edin Kadribasic 9e7f020233 Don't send default http status (200) (Thanks to Sascha Schumann for idea). 2002-11-22 13:50:40 +00:00
Stefan Esser 45bf902713 MFH: sha1() test 2002-11-22 11:04:10 +00:00
Edin Kadribasic 837d371f50 MFH: Fixed bug #19207 by adding cgi.rfc2616_headers config directive. 2002-11-22 10:16:36 +00:00
Sander Roobol 0debfe1163 MFH
@Made bcmath extension thread safe. (Sander)
2002-11-22 09:27:08 +00:00
Ilia Alshanetsky 3652c75a5d MFH 2002-11-22 00:09:30 +00:00
SVN Migration 8d9de08fc9 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-22 00:08:58 +00:00
Ilia Alshanetsky 78d474a58e MFH 2002-11-21 23:51:57 +00:00
Melvyn Sopacua 07b7ac10b6 MFH Fix bug #20518 2002-11-21 23:33:01 +00:00
Melvyn Sopacua 08fa24dd93 test for bug #20518 2002-11-21 23:31:45 +00:00
SVN Migration 47d920fd66 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-21 23:27:39 +00:00
Moriyoshi Koizumi af153a37f0 MFH (added missing mb_internal_encoding()) 2002-11-21 18:19:27 +00:00
Moriyoshi Koizumi e6c6bdc2d9 MFH (removed unnecessary \n) 2002-11-21 17:36:57 +00:00
Marcus Boerger 594e183737 MFH 2002-11-21 16:50:55 +00:00
Rui Hirokawa 2832208fc5 mbstring is supporting CJK + some other encodings. 2002-11-21 16:21:33 +00:00
Rui Hirokawa 769be40253 fixed incorrect encoding conversion in korean. 2002-11-21 16:18:17 +00:00
Sander Roobol c31d9b7850 MFH 2002-11-21 16:16:58 +00:00
Sander Roobol 6e9a4ec6e6 MFH 2002-11-21 15:25:51 +00:00
SVN Migration 179effddf3 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-21 15:24:46 +00:00
Moriyoshi Koizumi 6c0b8b370b Fixed yet another mb_parse_str() bug
# This is reported by Ilia. Thanks!
2002-11-21 14:51:26 +00:00
Hartmut Holzgraefe 7f6afc578c MFH 2002-11-21 10:53:18 +00:00
foobar 82ac093b6b MFH, as requested by georg 2002-11-20 23:01:02 +00:00
Derick Rethans 20c0cd2a88 - MFH: Add an error message to the ini handlers 2002-11-20 17:49:57 +00:00
Ilia Alshanetsky caa461e493 MFH 2002-11-20 16:08:36 +00:00
SVN Migration 558795b066 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-20 15:56:57 +00:00
Ilia Alshanetsky 755958ac16 MFH 2002-11-20 06:53:33 +00:00
SVN Migration 00beb9dbce This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-20 06:48:59 +00:00
Wez Furlong 5302361ece Be pedantic with the return value 2002-11-19 21:11:03 +00:00
Wez Furlong f96922968f Add this test for gzreading non-compressed data. 2002-11-19 20:13:24 +00:00
Wez Furlong 26a1202ee0 Remove a memset I added while debugging 2002-11-19 20:04:15 +00:00
Wez Furlong 915c446634 Resolve some problems with zlib streams, mostly related to opening the
stream with an invalid mode.
There still seem to be some issues when reading from non-compressed files.
Investigation continues.
2002-11-19 18:34:55 +00:00
Moriyoshi Koizumi be66394313 MFH 2002-11-19 16:57:18 +00:00
SVN Migration 6eee55fde4 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-19 16:56:44 +00:00
Edin Kadribasic 8a86509e4b Update Credits 2002-11-19 15:11:33 +00:00
Derick Rethans 610e0c36ec - MFH 2002-11-19 14:54:45 +00:00
SVN Migration dbaedcda20 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-19 14:53:32 +00:00
Edin Kadribasic 7c79b7026b MFH (Fix for linking warnings on windows). 2002-11-19 14:53:11 +00:00
Derick Rethans 248fcb16be - Fix safemode relating pear install problems 2002-11-19 14:43:42 +00:00
Marcus Boerger cda63e432c MFH 2002-11-19 14:13:40 +00:00
Derick Rethans bc6120892a - MFH: Cybermut removal 2002-11-19 10:12:52 +00:00
Derick Rethans 5eae9a11dd - MFH 2002-11-19 08:21:38 +00:00
Stig Bakken 89f833b5d0 MFH 2002-11-19 02:23:28 +00:00
Edin Kadribasic 8ab3132acb MFH (fix windows build) 2002-11-19 01:07:09 +00:00
Moriyoshi Koizumi b35690c4b9 MFH (binary mode fix) 2002-11-18 21:23:11 +00:00
Moriyoshi Koizumi d1245e43e4 MFH (fixed possible leaks) 2002-11-18 21:16:24 +00:00
Marcus Boerger 98bd51e9ad MFH
-Added colordepth for png
-Added tests for width/heidth for unsigned/signed problems
2002-11-18 16:55:35 +00:00
Marcus Boerger 8455b5b0c1 MFH: Added colordepth for png\n 2002-11-18 16:53:04 +00:00
SVN Migration 29ec528c42 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-18 16:51:03 +00:00
Marcus Boerger abe964d237 Fixing unsigned/signed problems (and i thought about it before...)\n 2002-11-18 15:50:49 +00:00
Derick Rethans 7a974d0ef1 - MFH 2002-11-18 15:46:01 +00:00
Ilia Alshanetsky 33b6f2a71a Fix bug #20442. 2002-11-18 13:30:18 +00:00
Derick Rethans 4b6f7554c0 - Remove e*() memory function calls from the branch 2002-11-18 13:00:52 +00:00
Wez Furlong bfaac17306 wb -> r+b 2002-11-18 12:43:00 +00:00
Edin Kadribasic 4f0b31cf5d MFH (fribidi is not available on windows yet). 2002-11-18 12:16:59 +00:00
Wez Furlong d7ded80028 Amend info about mbstring enabled by default (no longer true). 2002-11-18 11:53:11 +00:00
Wez Furlong 2c11564d0a MFH other temp file mode fixes and Id tag. 2002-11-18 11:50:36 +00:00
Wez Furlong d6ee6ce580 Remove redundant info line (all wrappers are listed near the start of
the phpinfo page).
2002-11-18 11:03:38 +00:00
foobar 941047121f MFH; Fixed bug: #20458 (--with-qtdom=shared broken) 2002-11-18 05:06:45 +00:00
foobar 72b7ea5d77 MFH: Added error message if browscap location is not set in php.ini 2002-11-18 03:24:33 +00:00
Ilia Alshanetsky 59a18f6a83 MFH 2002-11-18 03:16:45 +00:00
foobar d708e20b12 MFH 2002-11-18 00:43:48 +00:00
Wez Furlong 81bf1d581d Add missing Id tag. 2002-11-17 23:16:45 +00:00
Wez Furlong 463ccd8283 Revise stream shutdown procedure. 2002-11-17 23:08:40 +00:00
Ilia Alshanetsky d9e33dbaec MFH 2002-11-17 22:53:35 +00:00
Ilia Alshanetsky 9831d1492d MFH 2002-11-17 21:58:12 +00:00
Ilia Alshanetsky cb228e9002 MFH 2002-11-17 20:19:28 +00:00
Derick Rethans 48099d9569 - Fix memory problem for real this time. 2002-11-17 19:40:38 +00:00
Wez Furlong 0b717a898b s/off64t/off64_t/ 2002-11-17 19:28:57 +00:00
Wez Furlong 8a19278ac8 Fix fopencookie detection for newer versions of glibc.
The GNU people strike again with their useless docs; fopencookie does NOT
use "fpos_t *" as documented :/
Additionally, it appears that the the libio layer buffers in chunks of 8KB,
so our test needs to exploit this in order to function correctly.
Thanks to Derick for doing some groundwork.
2002-11-17 19:14:49 +00:00
Zeev Suraski 241a5e6798 MFH - unify error_reporting handling through the INI subsystem 2002-11-17 13:32:44 +00:00
Derick Rethans 21c8c2ba44 - Fix memory allocation problem in bundled GD (reported by Brian Havard) 2002-11-17 13:10:36 +00:00
Marcus Boerger b59c0d1274 MFH: Conversion fix by Michael Mauch 2002-11-17 09:28:56 +00:00
Wez Furlong 3d4fe01bb6 Avoid a potential double fclose(). 2002-11-17 01:06:31 +00:00
Ilia Alshanetsky da110d3f59 Fix compile warning. 2002-11-17 00:11:19 +00:00
Wez Furlong 01a12a109a Remove debugging printf 2002-11-17 00:08:42 +00:00
Ilia Alshanetsky f201adbbdb MFH 2002-11-17 00:07:33 +00:00
Marcus Boerger 416fb87dff MFH: Force float for the float test 2002-11-16 23:47:30 +00:00
Wez Furlong 8d2075dd85 initialize this member so that it doesn't segfault on shutdown... 2002-11-16 23:35:30 +00:00
Wez Furlong 03851bac05 php_stream_fopen_tmpfile now uses php_open_temporary_file rather than
tmpfile().
tmpfile() under win32 will try to use the root directory; the default
IIS settings prohibit access to the root directory, which renders tmpfile()
useless.
PHP's tmpfile() streams are correctly cleaned up and unlinked when closed
(or at request shutdown).  However, if the stream is cast and passed to
a third party library, the temporary file may linger.
This is unfortunate, since streams uses this process internally for handling
the casting of user-streams.
--> some more work is needed on this, but this can be done more easily under
Linux.
2002-11-16 22:59:55 +00:00
Wez Furlong 4ef373153a Change "wb" -> "r+b" for win32.
The difference is staggering - I've spent hours tracking this down.
It should probably be made the same for all platforms.
2002-11-16 22:52:22 +00:00
Marcus Boerger 854c4614e9 MFH 2002-11-16 17:30:10 +00:00
Ilia Alshanetsky a5f2931544 MFH 2002-11-16 17:26:48 +00:00
Marcus Boerger b17bfef199 MFH: Make getimagesize more robust against corrupt files 2002-11-16 17:03:49 +00:00
Wez Furlong f06e6a7802 This is not needed here. 2002-11-16 16:13:25 +00:00
Wez Furlong 32733912f1 Remove debugging line... 2002-11-16 11:40:07 +00:00
Wez Furlong c52b6d3fc0 Make include/require of user-streams work on systems without fopencookie. 2002-11-16 11:39:36 +00:00
Sebastian Bergmann f6534cb075 MFH 2002-11-16 08:32:11 +00:00
Stig Bakken 1574ad43b2 MFH 2002-11-15 23:21:42 +00:00
Marcus Boerger 6e05f972a1 MFH: When --enable-dba is used then include builtin modules unless
--without-xxx is not used.
2002-11-15 21:30:51 +00:00
Marcus Boerger af3aa7d9fc MFH: Added test for bug 14383 2002-11-15 16:45:57 +00:00
Marcus Boerger 037483602a MFH: simplify and show skip reason 2002-11-15 16:43:43 +00:00
Marcus Boerger 9ba6732230 MFH: show correct result 2002-11-15 16:42:04 +00:00
Marcus Boerger d190f54321 MFH: new syntax 2002-11-15 16:40:30 +00:00
Marcus Boerger 608a52b9b9 MFH: info about handler used and use flatfile if available 2002-11-15 16:39:36 +00:00
Marcus Boerger 8a185f8107 MFH: deprecate ext/db 2002-11-15 16:37:51 +00:00
Ilia Alshanetsky f6fec8adf1 Revert of previous patch ad requested by Andi. 2002-11-15 16:36:59 +00:00
Moriyoshi Koizumi d7ac826f89 MFH 2002-11-15 16:36:23 +00:00
Ilia Alshanetsky d88ac3a972 MFH (symlinks + ZTS). 2002-11-15 16:34:54 +00:00
Marcus Boerger aaf5c39690 MFH: SKIP and INFO result from --SKIPIF-- 2002-11-15 16:34:07 +00:00
Moriyoshi Koizumi 07e278c9d4 MFH.
# thanks Jani
2002-11-15 16:30:53 +00:00
Moriyoshi Koizumi f48a7e5f78 MFH 2002-11-15 16:29:03 +00:00
Marcus Boerger 16ea198a13 MFH
-Allow skip in upper letters.
-Add 'info' result to --SKIPIF-- -> see following dba commits
2002-11-15 16:13:10 +00:00
Moriyoshi Koizumi 1e219b65bf MFH 2002-11-15 15:59:57 +00:00
SVN Migration ec36147dbf This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-15 15:59:08 +00:00
Moriyoshi Koizumi e31196d184 MFH 2002-11-15 15:35:22 +00:00
Moriyoshi Koizumi cea50a67e1 MFH 2002-11-15 14:55:07 +00:00
Moriyoshi Koizumi 41a0f1c59b MFH 2002-11-15 14:50:33 +00:00
Marcus Boerger 9c5c168394 MFH: Only show the first results 2002-11-15 14:48:55 +00:00
Marcus Boerger 0f5232c5d2 Correction
#Why does it mix up things again?...i do not know
2002-11-15 14:27:37 +00:00
Moriyoshi Koizumi a920cec9aa MFH 2002-11-15 14:27:12 +00:00
Marcus Boerger dd68136bd9 MFH: Show Zend version 2002-11-15 14:24:20 +00:00
Marcus Boerger 174c207381 MFH: Showing memleaks for a memleak test is a good idea 2002-11-15 11:57:50 +00:00
Marcus Boerger f16e2e6650 MFH: Fix segfaults (check ext/domxml/tests/domxml002.phpt) 2002-11-15 11:07:34 +00:00
Derick Rethans bbcb203900 - MFH: removed restore_connection_defaults for pconnects (discussed on
php-dev@)
       bug #19529 closed
       bug #12513 reopened
2002-11-15 10:44:23 +00:00
Sander Roobol 40e65a119d MFH 2002-11-15 10:39:19 +00:00
foobar e58c52ae7e MFH 2002-11-15 07:23:26 +00:00
foobar bd49c212c3 clean the mess.. 2002-11-15 07:18:20 +00:00
Moriyoshi Koizumi 03222e4d82 MFH 2002-11-15 02:18:12 +00:00
Andrei Zmievski 54e893af56 MFH 2002-11-15 00:33:18 +00:00
Stig Bakken 07075670c3 MFH 2002-11-14 23:26:27 +00:00
Moriyoshi Koizumi a6df543348 MFH 2002-11-14 23:08:54 +00:00
Stig Bakken 857e1a6b30 MFH 2002-11-14 22:51:21 +00:00
Moriyoshi Koizumi 05eadd933c MFH 2002-11-14 22:40:11 +00:00
SVN Migration 4c5cf3125f This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-14 22:38:44 +00:00
Marcus Boerger 1fe950b9a6 MFH: Test updates 2002-11-14 22:08:30 +00:00
Marcus Boerger 54a2a9dd13 Correct last update
# i don't know why but somehow my files were mixed up or i cannot read
# anylonger - however it seems it's time to go sleeping now
2002-11-14 22:02:07 +00:00
Marcus Boerger 6df2d4c33c Add info: Add magic_quotes_runtime support 2002-11-14 21:53:12 +00:00
Marcus Boerger 5555b1c3a8 MFH: magic_quotes_runtime support is needed to have ext/dba being
superset of deprectaed ext/db
2002-11-14 21:52:22 +00:00
Moriyoshi Koizumi fcc8f8fbd0 MFH 2002-11-14 21:35:18 +00:00
Andrei Zmievski 2827407d43 MFH 2002-11-14 21:17:00 +00:00
Andrei Zmievski d9d34ae282 MFH 2002-11-14 21:09:47 +00:00
SVN Migration e3718c88b2 This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-14 21:09:42 +00:00
Marcus Boerger 4bab2c1afd MFH: Add magic_quotes_runtime which affects several tests 2002-11-14 21:03:22 +00:00
Melvyn Sopacua 7ad332abf8 MFH plus typo fix 2002-11-14 20:57:09 +00:00
Marcus Boerger 4b7ea20437 MFH: Only set the overwrites once (keep this in sync as long as possible) 2002-11-14 20:20:47 +00:00
Andrei Zmievski ea17af230a Back to 4.3.0-dev. 2002-11-14 19:16:30 +00:00
Ilia Alshanetsky ab37eae5cb MFH (disable safe_mode for test). 2002-11-14 18:38:25 +00:00
Marcus Boerger 1019c662a5 Missed that 2002-11-14 17:22:26 +00:00
Andrei Zmievski f16941595a Fix version. 2002-11-14 17:03:36 +00:00
Andrei Zmievski 46d3edd8c1 Go for RC1. 2002-11-14 16:47:03 +00:00
Stefan Esser 81cd0ebfa0 MFH 2002-11-14 16:40:27 +00:00
Ilia Alshanetsky 516eacd03f MFH (zts compile warning). 2002-11-14 16:33:18 +00:00
Ilia Alshanetsky df34134534 MFH (fic for bug #20423). 2002-11-14 16:21:15 +00:00
Marcus Boerger a022fb30d0 Info about gd changes 2002-11-14 14:57:23 +00:00
Marcus Boerger ded0b2efba MFH:
Fix locking behaviour: On some systems read during write is permitted but
most libraries are not capable of that. GDBM is system dependant so there
we only test  that we do not deadlock.
2002-11-14 14:40:43 +00:00
Marcus Boerger f3ba6741ec MFH: Info about closed bugs 2002-11-14 14:39:53 +00:00
Wez Furlong ed84676c15 Add note about shortcomings of this test. 2002-11-14 14:25:36 +00:00
Ilia Alshanetsky bcaf766768 MFH (skip conditions for tests) 2002-11-14 14:19:03 +00:00
Ilia Alshanetsky 5386b85b15 MFH (compile warning fix). 2002-11-14 14:06:49 +00:00
Wez Furlong d32b02e1ca MFB 2002-11-14 13:52:39 +00:00
Ilia Alshanetsky dde44ae7b2 Bug fix news. 2002-11-14 13:52:17 +00:00
Ilia Alshanetsky b12880ce40 MFH (fix for bug #19689). 2002-11-14 13:45:43 +00:00
Ilia Alshanetsky c60242c944 MFH (parse_url bug). 2002-11-14 13:44:24 +00:00
Edin Kadribasic 65995b5c4f MFH (fixes unix build of mbstring) 2002-11-14 13:37:26 +00:00
SVN Migration a8bb6a9eca This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-14 12:20:37 +00:00
Derick Rethans b391a7a372 - Fixed bug #20424 (stream_get_meta_data craches on a normal file stream).
(Derick, Wez)
2002-11-14 10:52:45 +00:00
James Cox 4a15ca11e7 MFH.. 2002-11-14 02:07:37 +00:00
James Cox cb8e121ca9 MFH 2002-11-14 01:57:20 +00:00
foobar 6caa25e9f6 MFH 2002-11-14 01:56:06 +00:00
foobar 6c46b47b75 Fixed bug: #20414, shared build did not work 2002-11-14 00:20:24 +00:00
Edin Kadribasic c03f73a3b3 Made mbstring compile on windows again. 2002-11-13 23:01:17 +00:00
Edin Kadribasic d483bd4ecc MFH (relly disable compilation of mbstring) 2002-11-13 21:38:57 +00:00
Edin Kadribasic 57c012b007 MFH (mbstring defines commented out to allow defining them elsewhere). 2002-11-13 21:37:27 +00:00
Stig Bakken 2eced40646 MFH: remove debug output 2002-11-13 20:38:24 +00:00
Derick Rethans 1102505d22 - MFH: moved ext/cybermut to PECL 2002-11-13 19:41:54 +00:00
SVN Migration e6659bd69f This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. 2002-11-13 16:30:51 +00:00
21058 changed files with 516207 additions and 3670002 deletions

No files matched your search

-60
View File
@@ -1,60 +0,0 @@
version: "{branch}.build.{build}"
image: Visual Studio 2019
branches:
except:
- PHP-5.6
- PHP-7.0
clone_depth: 64
skip_commits:
files:
- docs/*
- NEWS
- UPGRADING
- UPGRADING.INTERNALS
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: vs16
# 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
PARALLEL: -j2
- THREAD_SAFE: 1
OPCACHE: 1
PARALLEL: -j2
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,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
-645
View File
@@ -1,645 +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
set $tsrm_ls = _tsrm_ls_cache
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 < 12
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
printf "\nProperties "
set $ht = $zobj->properties
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
printf " {\n"
set $ht = &$zobj->ce->properties_info
set $k = 0
set $num = $ht->nNumUsed
while $k < $num
set $p = (Bucket*)($ht->arData + $k)
set $name = $p->key
set $prop = (zend_property_info*)$p->val.value.ptr
set $val = (zval*)((char*)$zobj + $prop->offset)
printf "%s => ", $name->val
printzv $val
set $k = $k + 1
end
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 "CONSTANT_AST"
end
if $type == 12
printf "indirect: "
____printzv $zvalue->value.zv $arg1
end
if $type == 13
printf "pointer: %p", $zvalue->value.ptr
end
if $type == 15
printf "_ERROR"
end
if $type == 16
printf "_BOOL"
end
if $type == 17
printf "_NUMBER"
end
if $type > 17
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
____print_str $p->key->val $p->key->len
printf " => "
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
-19
View File
@@ -1,19 +0,0 @@
# Replace $Id$ strings with 40-character hexadecimal blob object name.
/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
# A custom merge driver to avoid automatic merges. These are manually merged.
# See https://wiki.php.net/vcs/gitfaq
/NEWS merge=NEWS
/UPGRADING merge=NEWS
/UPGRADING.INTERNALS merge=NEWS
# Enable commit diffs for binary PHP test files. Some PHP test files include
# special characters, such as ASCII control characters. Git recognizes these as
# binary and wouldn't generate diffs.
*.phpt diff
-285
View File
@@ -1,285 +0,0 @@
# These files are generated during building or development and are intentionally
# untracked to ignore by Git. For other development environment specific files,
# such as editor configuration, a good practice is to exclude them using the
# .git/info/exclude in the cloned repository or a global .gitignore file.
# ------------------------------------------------------------------------------
# Common files ignored across the repository
# ------------------------------------------------------------------------------
# Backup copies created by various editors or development tools
*~
# Patches downloaded to patch files or to apply open source contributions
*.patch
# Swap files created by editors and tools to indicate a locked file
*.swp
# Various temporary generated files
*.tmp
# ------------------------------------------------------------------------------
# Generated by the PHP build system
# ------------------------------------------------------------------------------
# Archive library containing .o files, generated during build process
*.a
# Libtool library files generated during build process
*.la
# Directories created by Libtool for storing generated library files
.libs/
# Library object files generated during build process
*.lo
# Temporary library object files generated by compiler and libtool due to failure
*.loT
# Standard object files generated during build process
*.o
# Cache directories created by Autoconf tools
autom4te.cache/
# Cache file(s) generated by Autoconf's configure when run as `configure -C`
config.cache
# A log file(s) generated by Autoconf during *nix build system
config.log
# Helper(s) generated by *nix build system to save the last configure command
config.nice
# Generated by Autoconf's configure script for instantiating templates
config.status
# Main *nix build system configuration script(s) generated by Autoconf
configure
# Generated by `./configure` when test programs create temporary files
confdefs.h
conftest*
# Generated by configure scripts on all systems
/main/internal_functions.c
/main/internal_functions_cli.c
# The Libtool script(s) generated by the *nix build system
libtool
# Makefile(s) generated from Makefile fragment templates by `./configure`
Makefile
Makefile.fragments
Makefile.objects
# Directories for shared object files and headers generated by `./configure`
include/
libs/
modules/
# Used by build/gen_stub.php
build/PHP-Parser-*
# ------------------------------------------------------------------------------
# Configuration headers generated by the PHP build system
# ------------------------------------------------------------------------------
config.h
config.h.in
/ext/date/lib/timelib_config.h
/main/build-defs.h
/main/php_config.h.in
/main/php_config.h
/Zend/zend_config.h
# ------------------------------------------------------------------------------
# Manual (man 1 and 8) pages generated from templates for *nix alike systems
# ------------------------------------------------------------------------------
/ext/phar/phar.1
/ext/phar/phar.phar.1
/sapi/cgi/php-cgi.1
/sapi/cli/php.1
/sapi/fpm/php-fpm.1
/sapi/fpm/php-fpm.8
/sapi/phpdbg/phpdbg.1
/scripts/man1/*.1
# ------------------------------------------------------------------------------
# SAPIs specific ignores
# ------------------------------------------------------------------------------
/sapi/apache2handler/libphp.module
/sapi/fpm/fpm/php-cgi
/sapi/fpm/init.d.php-fpm
/sapi/fpm/php-fpm.conf
/sapi/fpm/php-fpm.service
/sapi/fpm/status.html
/sapi/fpm/www.conf
# ------------------------------------------------------------------------------
# Executable binaries and scripts generated during the build process
# ------------------------------------------------------------------------------
/ext/phar/phar.phar
/ext/phar/phar.php
/pear/install-pear-nozlib.phar
/sapi/cgi/php-cgi
/sapi/fpm/php-fpm
/sapi/phpdbg/phpdbg
/scripts/php-config
/scripts/phpize
php
# ------------------------------------------------------------------------------
# Lexer files generated by re2c
# ------------------------------------------------------------------------------
/ext/json/json_scanner.c
/ext/json/php_json_scanner_defs.h
/ext/pdo/pdo_sql_parser.c
/ext/phar/phar_path_check.c
/ext/standard/url_scanner_ex.c
/ext/standard/var_unserializer.c
/sapi/phpdbg/phpdbg_lexer.c
/Zend/zend_ini_scanner.c
/Zend/zend_ini_scanner_defs.h
/Zend/zend_language_scanner.c
/Zend/zend_language_scanner_defs.h
# ------------------------------------------------------------------------------
# PHP parser files generated by bison during the build process
# ------------------------------------------------------------------------------
/ext/json/json_parser.tab.h
/ext/json/json_parser.tab.c
/sapi/phpdbg/phpdbg_parser.c
/sapi/phpdbg/phpdbg_parser.h
/sapi/phpdbg/phpdbg_parser.output
/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
# ------------------------------------------------------------------------------
# Extensions files
# ------------------------------------------------------------------------------
# Miscellaneous extensions files
/ext/opcache/jit/zend_jit_x86.c
/ext/opcache/minilua
# Generated by `cd ext/name && phpize && ./configure`
/ext/*/build/
/ext/*/configure.ac
/ext/*/run-tests.php
# ------------------------------------------------------------------------------
# Generated by Windows build system
# ------------------------------------------------------------------------------
# Generated by `/buildconf.bat`
/configure.bat
/configure.js
# Generated by `/configure.(bat|js)` (architecture dependent)
/config.nice.bat
# NTS debug build x86
/Debug/
# ZTS debug build x86
/Debug_TS/
# NTS build x86
/Release/
# ZTS build x86
/Release_TS/
# Generated by x64 compiler, includes Debug, Debug_TS, Release, Release_TS
/x64/
# Miscellaneous files generated by Windows build system
/main/config.w32.h
/win32/build/deplister.exe
/win32/build/deplister.obj
/win32/*.aps
/win32/*.positions
/win32/*.suo
/win32/ext
/win32/syslog.reg
/win32/wsyslog.h
# Standard object files generated by Visual Studio
*.obj
# ------------------------------------------------------------------------------
# Tests
# ------------------------------------------------------------------------------
# Generated by `./run-tests.php` upon failure
**/tests/**/*.diff
**/tests/**/*.out*
**/tests/**/*.php
**/tests/**/*.exp
**/tests/**/*.log
**/tests/**/*.sh
# Generated by some test cases
**/tests/**/*.db
# Microsoft Access database created for passing to tests
/ext/pdo_odbc/tests/*.mdb
# Files generated by `./run-tests.php -m` when checking for memory leaks
**/tests/**/*.mem
# Test results generated by `./run-tests.php`
php_test_results_*.txt
# Temporary test information generated by `./run-tests.php`
/run-test-info.php
# Temporary POST data placeholder files generated by `./run-tests.php`
phpt.*
# Temporary PHP INI configuration file(s) for tests, generated by `make test`
tmp-php.ini
# ------------------------------------------------------------------------------
# Generated by GCC's gcov and LCOV via build/Makefile.gcov and gcov.php.net
# ------------------------------------------------------------------------------
*.gcda
*.gcno
/gcovr.xml
/gcovr_html/
/lcov_html/
/php_lcov.info
# ------------------------------------------------------------------------------
# Archives generated during the PHP release process
# ------------------------------------------------------------------------------
/*.tar.gz
/*.tar.bz2
/*.tar.xz
/*.tar.gz.asc
/*.tar.bz2.asc
/*.tar.xz.asc
# ------------------------------------------------------------------------------
# Generated by `./configure --enable-dtrace` for using DTrace framework
# ------------------------------------------------------------------------------
/ext/oci8/oci8_dtrace_gen.h
/ext/oci8/oci8_dtrace_gen.h.bak
/Zend/zend_dtrace_gen.h
/Zend/zend_dtrace_gen.h.bak
# ------------------------------------------------------------------------------
# Special cases to invert previous ignore patterns
# ------------------------------------------------------------------------------
!/ext/bcmath/libbcmath/src/config.h
!/ext/fileinfo/libmagic/config.h
!/ext/fileinfo/libmagic.patch
!/ext/fileinfo/magicdata.patch
!/ext/pcre/pcre2lib/config.h
!/win32/build/Makefile
-104
View File
@@ -1,104 +0,0 @@
git:
quiet: true
dist: bionic
language: c
os: linux
addons:
apt:
packages:
- locales
- language-pack-de
- re2c
- ccache
- mysql-server
- libaspell-dev
- libbz2-dev
- libcurl4-gnutls-dev
- libenchant-dev
- libfreetype6-dev
- libgmp-dev
- libicu-dev
- libjpeg-dev
- libkrb5-dev
- libonig-dev
- libpng-dev
- libpq-dev
- libpspell-dev
- libsasl2-dev
- libsqlite3-dev
- libsodium-dev
- libtidy-dev
- libwebp-dev
- libxml2-dev
- libxpm-dev
- libxslt1-dev
- libzip-dev
services:
- mysql
- postgresql
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
- PDO_PGSQL_TEST_DSN="pgsql:host=localhost port=5432 dbname=test user=postgres password="
- REPORT_EXIT_STATUS=1
jobs:
include:
- env: ENABLE_ZTS=0 ENABLE_DEBUG=0
arch: amd64
if: type = cron
- env: ENABLE_ZTS=1 ENABLE_DEBUG=1
arch: amd64
if: type = cron
- env: ENABLE_ZTS=1 ENABLE_DEBUG=1 SKIP_IO_CAPTURE_TESTS=1 ARM64=1
arch: arm64
if: type = cron
- env: ENABLE_ZTS=1 ENABLE_DEBUG=1 SKIP_IO_CAPTURE_TESTS=1 S390X=1
arch: s390x
if: type = cron
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_wait ./travis/compile.sh
# Setup Extensions
- ./travis/setup-mysql.sh
- ./travis/setup-pgsql.sh
# Run PHPs run-tests.php
script:
# ARM64 CI reports nproc=32, which is excessive.
- if [ -z "$ARM64" ]; then export JOBS=$(nproc); else export JOBS=16; fi
- ./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 opcache.protect_memory=1 -d opcache.jit_buffer_size=16M -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --show-slow 1000 --set-timeout 120 -j$JOBS
- sapi/cli/php -d extension_dir=`pwd`/modules -r 'dl("zend_test");'
after_success:
- ccache --show-stats
+294
View File
@@ -0,0 +1,294 @@
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.
Code Implementation
-------------------
[0] Document your code in source files and the manual. [tm]
[1] Functions that are given pointers to resources should not free them
For instance, function int mail(char *to, char *from) should NOT free
to and/or from.
Exceptions:
- The function's designated behavior is freeing that resource. E.g. efree()
- The function is given a boolean argument, that controls whether or not
the function may free its arguments (if true - the function must free its
arguments, if false - it must not)
- Low-level parser routines, that are tightly integrated with the token
cache and the bison code for minimum memory copying overhead.
[2] Functions that are tightly integrated with other functions within the
same module, and rely on each other non-trivial behavior, should be
documented as such and declared 'static'. They should be avoided if
possible.
[3] Use definitions and macros whenever possible, so that constants have
meaningful names and can be easily manipulated. The only exceptions
to this rule are 0 and 1, when used as false and true (respectively).
Any other use of a numeric constant to specify different behavior
or actions should be done through a #define.
[4] When writing functions that deal with strings, be sure to remember
that PHP holds the length property of each string, and that it
shouldn't be calculated with strlen(). Write your functions in a such
a way so that they'll take advantage of the length property, both
for efficiency and in order for them to be binary-safe.
Functions that change strings and obtain their new lengths while
doing so, should return that new length, so it doesn't have to be
recalculated with strlen() (e.g. php_addslashes())
[5] Use php_error_docref() group of functions 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.
It has been silently agreed to prefix every php_error() message with the
name of the current function if applicable:
php_error(E_WHATEVER, "%s(): Desc.", get_active_function_name(TSRMLS_C));
This can be done automatically using php_error_docref(). The first
parameter, docref, is either NULL or the URL of a page describing the
error in detail. In most cases you will pass NULL, to generate the URL
from the name of the function being executed:
php_error_docref(NULL TSRMLS_CC, E_WHATEVER, "Desc.");
If you pass a URL, it can either be a full URL beginning with "http://":
php_error_docref("http://externalsite.tld/page.ext#error"
TSRMLS_CC, E_WHATEVER, "Desc.");
Or the name of a manual page without file extension, but with an optional
target anchor. Or simply the anchor within the manual page of the current
function. When using function names you must replace '_' by '-':
php_error_docref("function.ext-func#error" TSRMLS_CC, E_WHATEVER, "Desc.");
To display one or two important parameters after the function name, use
php_error_docref1() or php_error_docref2(). For example, file functions
should display the name of the file opened:
php_error_docref1("function.fopen" TSRMLS_CC, filename,
E_WHATEVER, "Desc.");
php_error_docref2("function.fopen" TSRMLS_CC, filename, openmode,
E_WHATEVER, "Desc.");
Fixing ("unifying") existing php_error() message is a good thing [tm].
[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.
[7] 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.
[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.
[9] When commenting out code using a #if statement, do NOT use 0 only. Instead
use "<cvs username here>_0". For example, #if FOO_0, where FOO is your
cvs user foo. This allows easier tracking of why code was commented out,
especially in bundled libraries.
[10] 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
[11] Prefer emalloc(), efree(), estrdup(), etc. to their standard C library
counterparts. These functions implement an internal "safety-net"
mechanism that ensures the deallocation of any unfreed memory at the
end of a request. They also provide useful allocation and overflow
information while running in debug mode.
In almost all cases, memory returned to the engine must be allocated
using emalloc().
The use of malloc() should be limited to cases where a third-party
library may need to control or free the memory, or when the memory in
question needs to survive between multiple requests.
Naming Conventions
------------------
[1] Function names for user-level functions should be enclosed with in
the PHP_FUNCTION() macro. They should be in lowercase, with words
underscore delimited, with care taken to minimize the letter count.
Abbreviations should not be used when they greatly decrease the
readability of the function name itself.
Good:
'mcrypt_enc_self_test'
'mysql_list_fields'
Ok:
'mcrypt_module_get_algo_supported_key_sizes'
(could be 'mcrypt_mod_get_algo_sup_key_sizes'?)
'get_html_translation_table'
(could be 'html_get_trans_table'?)
Bad:
'hw_GetObjectByQueryCollObj'
'pg_setclientencoding'
'jf_n_s_i'
[2] If they are part of a "parent set" of functions, that parent should
be included in the user function name, and should be clearly related
to the parent program or function family. This should be in the form
of parent_*.
A family of 'foo' functions, for example:
Good:
'foo_select_bar'
'foo_insert_baz'
'foo_delete_baz'
Bad:
'fooselect_bar'
'fooinsertbaz'
'delete_foo_baz'
[3] Function names used by user functions should be prefixed
with "_php_", and followed by a word or an underscore-delimited list of
words, in lowercase letters, that describes the function. If applicable,
they should be declared 'static'.
[4] Variable names must be meaningful. One letter variable names must be
avoided, except for places where the variable has no real meaning or
a trivial meaning (e.g. for (i=0; i<100; i++) ...).
[5] Variable names should be in lowercase. Use underscores to separate
between words.
Syntax and indentation
----------------------
[1] Never use C++ style comments (i.e. // comment). Always use C-style
comments instead. PHP is written in C, and is aimed at compiling
under any ANSI-C compliant compiler. Even though many compilers
accept C++-style comments in C code, you have to ensure that your
code would compile with other compilers as well.
The only exception to this rule is code that is Win32-specific,
because the Win32 port is MS-Visual C++ specific, and this compiler
is known to accept C++-style comments in C code.
[2] Use K&R-style. Of course, we can't and don't want to
force anybody to use a style he or she is not used to, but,
at the very least, when you write code that goes into the core
of PHP or one of its standard modules, please maintain the K&R
style. This applies to just about everything, starting with
indentation and comment styles and up to function declaration
syntax.
(see also http://www.tuxedo.org/~esr/jargon/html/entry/indent-style.html)
[3] Be generous with whitespace and braces. Always prefer:
if (foo) {
bar;
}
to:
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
four spaces. It is important to maintain consistency in indenture so
that definitions, comments, and control structures line up correctly.
Documentation and Folding Hooks
-------------------------------
In order to make sure that the online documentation stays in line with
the code, each user-level function should have its user-level function
prototype before it along with a brief one-line description of what the
function does. It would look like this:
/* {{{ proto int abs(int number)
Returns the absolute value of the number */
PHP_FUNCTION(abs)
{
...
}
/* }}} */
The {{{ symbols are the default folding symbols for the folding mode in
Emacs and vim (set fdm=marker). Folding is very useful when dealing with
large files because you can scroll through the file quickly and just unfold
the function you wish to work on. The }}} at the end of each function marks
the end of the fold, and should be on a separate line.
The "proto" keyword there is just a helper for the doc/genfuncsummary script
which generates a full function summary. Having this keyword in front of the
function prototypes allows us to put folds elsewhere in the code without
messing up the function summary.
Optional arguments are written like this:
/* {{{ proto object imap_header(int stream_id, int msg_no [, int from_length [, int subject_length [, string default_host]]])
Returns a header object with the defined parameters */
And yes, please keep the prototype on a single line, even if that line
is massive.
New and Experimental Functions
-----------------------------------
To reduce the problems normally associated with the first public
implementation of a new set of functions, it has been suggested
that the first implementation include a file labeled 'EXPERIMENTAL'
in the function directory, and that the functions follow the
standard prefixing conventions during their initial implementation.
The file labelled 'EXPERIMENTAL' should include the following
information:
Any authoring information (known bugs, future directions of the module).
Ongoing status notes which may not be appropriate for CVS comments.
Aliases & Legacy Documentation
-----------------------------------
You may also have some deprecated aliases with close to duplicate
names, for example, somedb_select_result and somedb_selectresult. For
documentation purposes, these will only be documented by the most
current name, with the aliases listed in the documentation for
the parent function. For ease of reference, user-functions with
completely different names, that alias to the same function (such as
highlight_file and show_source), will be separately documented. The
proto should still be included, describing which function is aliased.
Backwards compatible functions and names should be maintained as long
as the code can be reasonably be kept as part of the codebase. See
/phpdoc/README for more information on documentation.
-320
View File
@@ -1,320 +0,0 @@
# PHP coding standards
This file lists several standards that any programmer adding or changing code in
PHP should follow. Since this file was added at a very late stage of the
development of PHP v3.0, the code base does not fully follow it, but new
features are going in that general direction. Many sections have been recoded to
use these rules.
## Code implementation
1. Document your code in source files and the manual. (tm)
2. Functions that are given pointers to resources should not free them.
For instance, `function int mail(char *to, char *from)` should NOT free to
and/or from.
Exceptions:
* The function's designated behavior is freeing that resource. E.g.
`efree()`
* The function is given a boolean argument, that controls whether or not the
function may free its arguments (if true - the function must free its
arguments, if false - it must not)
* Low-level parser routines, that are tightly integrated with the token
cache and the bison code for minimum memory copying overhead.
3. 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.
4. 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`.
5. 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 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()`).
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.
7. Use `PHP_*` macros in the PHP source, and `ZEND_*` macros in the Zend part of
the source. Although the `PHP_*` macros are mostly aliased to the `ZEND_*`
macros it gives a better understanding on what kind of macro you're calling.
8. 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.
9. 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.
10. 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
1. Function names for user-level functions should be enclosed with in the
`PHP_FUNCTION()` macro. They should be in lowercase, with words underscore
delimited, with care taken to minimize the letter count. Abbreviations
should not be used when they greatly decrease the readability of the
function name itself:
Good:
```php
str_word_count
array_key_exists
```
Ok:
```php
date_interval_create_from_date_string
// Could be 'date_intvl_create_from_date_str'?
get_html_translation_table()
// Could be 'html_get_trans_table'?
```
Bad:
```php
hw_GetObjectByQueryCollObj
pg_setclientencoding
jf_n_s_i
```
2. If they are part of a "parent set" of functions, that parent should be
included in the user function name, and should be clearly related to the
parent program or function family. This should be in the form of `parent_*`:
A family of `foo` functions, for example:
Good:
```php
foo_select_bar
foo_insert_baz
foo_delete_baz
```
Bad:
```php
fooselect_bar
fooinsertbaz
delete_foo_baz
```
3. Function names used by user functions should be prefixed with `_php_`, and
followed by a word or an underscore-delimited list of words, in lowercase
letters, that describes the function. If applicable, they should be declared
`static`.
4. Variable names must be meaningful. One letter variable names must be avoided,
except for places where the variable has no real meaning or a trivial
meaning (e.g. `for (i=0; i<100; i++) ...`).
5. Variable names should be in lowercase. Use underscores to separate between
words.
6. Method names follow the *studlyCaps* (also referred to as *bumpy case* or
*camel caps*) naming convention, with care taken to minimize the letter
count. The initial letter of the name is lowercase, and each letter that
starts a new `word` is capitalized:
Good:
```php
connect()
getData()
buildSomeWidget()
```
Bad:
```php
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:
```php
Curl
CurlResponse
HTTPStatusCode
URL
BTreeMap // B-tree Map
Id // Identifier
ID // Identity Document
Char // Character
Intl // Internationalization
Radar // Radio Detecting and Ranging
```
Bad:
```php
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`.
```c
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`.
```c
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 comments
instead. PHP is written in C, and is aimed at compiling under any ANSI-C
compliant compiler. Even though many compilers accept C++-style comments in
C code, you have to ensure that your code would compile with other compilers
as well. The only exception to this rule is code that is Win32-specific,
because the Win32 port is MS-Visual C++ specific, and this compiler is known
to accept C++-style comments in C code.
2. Use K&R-style. Of course, we can't and don't want to force anybody to use a
style he or she is not used to, but, at the very least, when you write code
that goes into the core of PHP or one of its standard modules, please
maintain the K&R style. This applies to just about everything, starting with
indentation and comment styles and up to function declaration syntax. Also
see [Indentstyle](http://www.catb.org/~esr/jargon/html/I/indent-style.html).
3. Be generous with whitespace and braces. Keep one empty line between the
variable declaration section and the statements in a block, as well as
between logical statement groups in a block. Maintain at least one empty
line between two functions, preferably two. Always prefer:
```c
if (foo) {
bar;
}
```
to:
```c
if(foo)bar;
```
4. When indenting, use the tab character. A tab is expected to represent four
spaces. It is important to maintain consistency in indenture so that
definitions, comments, and control structures line up correctly.
5. Preprocessor statements (`#if` and such) MUST start at column one. To indent
preprocessor directives you should put the `#` at the beginning of a line,
followed by any number of whitespace.
## Testing
1. Extensions should be well tested using `*.phpt` tests. Read about that at
[qa.php.net](https://qa.php.net/write-test.php) documentation.
## Folding hooks
Use `{{{` symbols for the folding mode in Emacs and vim (`set fdm=marker`).
Folding is very useful when dealing with large files because you can scroll
through the file quickly and just unfold the function you wish to work on.
The `}}}` at the end of each function marks the end of the fold, and should
be on a separate line.
```c
/* {{{ Returns the absolute value of the number */
PHP_FUNCTION(abs)
{
...
}
/* }}} */
```
## New and experimental functions
To reduce the problems normally associated with the first public implementation
of a new set of functions, it has been suggested that the first implementation
include a file labeled `EXPERIMENTAL` in the function directory, and that the
functions follow the standard prefixing conventions during their initial
implementation.
The file labelled `EXPERIMENTAL` should include the following information:
* Any authoring information (known bugs, future directions of the module).
* Ongoing status notes which may not be appropriate for 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.
## Aliases & legacy documentation
You may also have some deprecated aliases with close to duplicate names, for
example, `somedb_select_result` and `somedb_selectresult`. For documentation
purposes, these will only be documented by the most current name, with the
aliases listed in the documentation for the parent function. For ease of
reference, user-functions with completely different names, that alias to the
same function (such as `highlight_file` and `show_source`), will be separately
documented.
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.
-425
View File
@@ -1,425 +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.
You don't need any special access to download, build, debug and begin submitting
PHP or PECL code, tests or documentation. Once you've followed this guide and
had several contributions accepted, commit privileges are often quickly granted.
## Index
* [Pull requests](#pull-requests)
* [Filing bugs](#filing-bugs)
* [Feature requests](#feature-requests)
* [Writing tests](#writing-tests)
* [Writing documentation](#writing-documentation)
* [Getting help](#getting-help)
* [PHP source code directory structure](#php-source-code-directory-structure)
* [PHP internals](#php-internals)
* [PECL extensions](#pecl-extensions)
* [Checklist for submitting contribution](#checklist-for-submitting-contribution)
* [What happens after submitting contribution?](#what-happens-after-submitting-contribution)
* [What happens when your contribution is applied?](#what-happens-when-your-contribution-is-applied)
* [Git commit rules](#git-commit-rules)
* [Copyright and license headers](#copyright-and-license-headers)
## 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](https://www.php.net/supported-versions.php) are
supported). For example, at the time of writing, the lowest supported version is
PHP 7.3, which corresponds to the `PHP-7.3` 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`.
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](https://bugs.php.net/).
Read [Git access page](https://www.php.net/git.php) for help on using Git to get
and build PHP source code. We recommend to look at our
[workflow](https://wiki.php.net/vcs/gitworkflow) and our
[FAQ](https://wiki.php.net/vcs/gitfaq).
## 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 Comments (RFC)](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).
To create a RFC, discuss it with the extension maintainer, and discuss it on the
development mailing list internals@lists.php.net. RFC Wiki accounts can be
requested on https://wiki.php.net/start?do=register. PHP extension maintainers
can be found in the [EXTENSIONS](/EXTENSIONS) file in the PHP source code
repository. Mailing list subscription is explained on the
[mailing lists page](https://www.php.net/mailing-lists.php).
You may also 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.](https://qa.php.net/write-test.php)
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.
Failure conditions of `zend_parse_parameters`, `ZEND_PARSE_PARAMETERS()` and
similar functions should not be tested. These parameter parsing APIs are already
extensively tested, and additional tests only complicate future modifications.
For newly created tests, a `--CREDITS--` section should no longer be included,
as test authorship is already accurately tracked by Git. If multiple authors
should be credited, the `Co-authored-by` tag in the commit message may be used.
## 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. Windows development IRC channel
is available at #winphp-dev on FreeNode.
## PHP source code directory structure
PHP source code also includes several files generated during development and
several parts where maintenance is happening upstream in their respective
locations.
```bash
<php-src>/
├─ .git/ # Git configuration and source directory
├─ TSRM/ # Thread Safe Resource Manager
└─ Zend/ # Zend Engine
├─ zend_vm_execute.h # Generated by `Zend/zend_vm_gen.php`
├─ zend_vm_opcodes.c # Generated by `Zend/zend_vm_gen.php`
├─ zend_vm_opcodes.h # Generated by `Zend/zend_vm_gen.php`
└─ ...
├─ appveyor/ # Appveyor CI service files
└─ build/ # *nix build system files
├─ ax_*.m4 # https://github.com/autoconf-archive/autoconf-archive
├─ config.guess # https://git.savannah.gnu.org/cgit/config.git
├─ config.sub # https://git.savannah.gnu.org/cgit/config.git
├─ libtool.m4 # https://git.savannah.gnu.org/cgit/libtool.git
├─ ltmain.sh # https://git.savannah.gnu.org/cgit/libtool.git
├─ shtool # https://www.gnu.org/software/shtool/
└─ ...
├─ docs/ # PHP internals and repository documentation
└─ ext/ # PHP core extensions
└─ bcmath/
├─ libbcmath/ # Forked and maintained in php-src
└─ ...
└─ curl/
├─ sync-constants.php # The curl symbols checker
└─ ...
└─ date/
└─ lib/ # Bundled datetime library https://github.com/derickr/timelib
├─ parse_date.c # Generated by re2c 0.15.3
├─ parse_iso_intervals.c # Generated by re2c 0.15.3
└─ ...
└─ ...
└─ ffi/
├─ ffi_parser.c # Generated by https://github.com/dstogov/llk
└─ ...
└─ fileinfo/
├─ libmagic/ # Modified libmagic https://github.com/file/file
├─ data_file.c # Generated by `ext/fileinfo/create_data_file.php`
├─ libmagic.patch # Modifications patch from upstream libmagic
├─ magicdata.patch # Modifications patch from upstream libmagic
└─ ...
└─ gd/
├─ libgd/ # Bundled and modified GD library https://github.com/libgd/libgd
└─ ...
└─ mbstring/
├─ libmbfl/ # Forked and maintained in php-src
├─ unicode_data.h # Generated by `ext/mbstring/ucgendat/ucgendat.php`
└─ ...
└─ pcre/
├─ pcre2lib/ # https://www.pcre.org/
└─ ...
└─ pdo_mysql/
├─ php_pdo_mysql_sqlstate.h # Generated by `ext/pdo_mysql/get_error_codes.php`
└─ ...
└─ skeleton/ # Skeleton for developing new extensions with `ext/ext_skel.php`
└─ ...
└─ standard/
└─ html_tables/
├─ mappings/ # https://www.unicode.org/Public/MAPPINGS/
└─ ...
├─ credits_ext.h # Generated by `scripts/dev/credits`
├─ credits_sapi.h # Generated by `scripts/dev/credits`
├─ html_tables.h # Generated by `ext/standard/html_tables/html_table_gen.php`
└─ ...
└─ tokenizer/
├─ tokenizer_data.c # Generated by `ext/tokenizer/tokenizer_data_gen.sh`
└─ ...
└─ zend_test # For testing internal APIs. Not needed for regular builds.
└─ ...
└─ zip/ # Bundled https://github.com/pierrejoye/php_zip
└─ ...
└─ ...
└─ main/ # Binding that ties extensions, SAPIs, and engine together
├─ streams/ # Streams layer subsystem
├─ php_version.h # Generated by release managers using `configure`
└─ ...
├─ pear/ # PEAR installation
└─ sapi/ # PHP SAPI modules
└─ cli/
├─ mime_type_map.h # Generated by `sapi/cli/generate_mime_type_map.php`
└─ ...
└─ ...
├─ scripts/ # php-config, phpize and internal development scripts
├─ tests/ # Core features tests
├─ travis/ # Travis CI service files
└─ win32/ # Windows build system files
├─ cp_enc_map.c # Generated by `win32/cp_enc_map_gen.exe`
└─ ...
└─ ...
```
## PHP internals
For information on PHP internal C functions see
[References about Maintaining and Extending PHP](https://wiki.php.net/internals/references).
Various external resources can be found on the web. A standard printed reference
is the book "Extending and Embedding PHP" by Sara Golemon.
## PECL extensions
If you are fixing broken functionality in a [PECL](https://pecl.php.net)
extension then create a bug or identify an existing bug at
[bugs.php.net](https://bugs.php.net). A bug can be used to track the change
progress and prevent your changes getting lost in the PHP mail archives. Some
PECL extensions have their own bug tracker locations and different contributing
procedures.
If your change is large then create a
[Request for Comments (RFC)](https://wiki.php.net/rfc), discuss it with the
extension maintainer, and discuss it on the development mailing list
pecl-dev@lists.php.net depending on the extension. PECL mailing list
subscription is explained on the
[PECL support page](https://pecl.php.net/support.php).
Update any open bugs and add a link to the source of your change. 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.
## Checklist for submitting contribution
- Read [Coding standards](/CODING_STANDARDS.md) before you start working.
- 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 change 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-zts` to check your change compiles and operates
correctly in a thread safe PHP.
- Review the change once more just before submitting it.
## What happens after submitting contribution?
If your change 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 changes will require
patience on your side. If you do not receive feedback in a few days, consider
bumping. Before doing this think about these questions:
- Did I send the patch to the right mailing list?
- Did I review the mailing list archives to see if these kind of changes had
been discussed before?
- Did I explain my change clearly?
- Is my change too hard to review? Because of what factors?
## What happens when your contribution is applied?
Your name will likely be included in the Git commit log. If your change affects
end users, a brief description and your name might be added to the [NEWS](/NEWS)
file.
## Git commit rules
This section refers to contributors that have Git push access and make commit
changes themselves. 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 the more
detailed [information on Git](https://git-scm.com/).
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:
* Make everybody happier, especially those responsible for maintaining PHP
itself.
* Keep the changes consistently well documented and easily trackable.
* Prevent some of those 'Oops' moments.
* 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](/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-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:
| Branch | |
| --------- | --------- |
| master | Active development branch for PHP 8.0, which is open for backwards incompatible changes and major internal API changes. |
| PHP-7.4 | Is used to release the PHP 7.4.x series. This is a current stable version and is open for bugfixes only. |
| PHP-7.3 | Is used to release the PHP 7.3.x series. This is a current stable version and is open for bugfixes only. |
| PHP-7.2 | Is used to release the PHP 7.2.x series. This is an old stable version and is open for security fixes only. |
| PHP-7.1 | This branch is closed. |
| PHP-7.0 | This branch is closed. |
| PHP-5.6 | This branch is closed. |
| 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 non-security bugfix changes should first go to the lowest bugfix branch
(i.e. 7.3) and then get merged up to all other branches. All security fixes
should go to the lowest security fixes branch (i.e 7.2). 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 `#`.
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 [gitweb](https://git.php.net/) to look at PHP Git repository in
various ways.
## Copyright and license headers
New source code files should include the following header block:
```c
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: |
+----------------------------------------------------------------------+
*/
```
Thank you for contributing to PHP!
+2
View File
@@ -0,0 +1,2 @@
For the list of people who've put work into PHP, please see
http://www.php.net/credits.php
+34690
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.
+285 -304
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,42 +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
PRIMARY MAINTAINER: Marcus Börger <helly@php.net>, Edin Kadribasic <edink@php.net>
MAINTENANCE: Xinchen Hui <laruence@php.net> (2013 - 2020)
STATUS: Working
SINCE: 4.3.0
-------------------------------------------------------------------------------
EXTENSION: embed
PRIMARY MAINTAINER: Edin Kadribasic <edink@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: fpm
PRIMARY MAINTAINER: Jakub Zelenka <bukka@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3.3
-------------------------------------------------------------------------------
EXTENSION: litespeed
PRIMARY MAINTAINER: George Wang <gwang@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
-------------------------------------------------------------------------------
EXTENSION: phpdbg
PRIMARY MAINTAINER: Joe Watkins <krakjoe@php.net>, Bob Weinand <bwoebi@php.net>
EXTENSION: fhttpd
MAINTENANCE: Unknown
STATUS: 5.6
STATUS: Unknown
-------------------------------------------------------------------------------
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: thttpd
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: webjames
PRIMARY MAINTAINER: Alex Waugh <alex@alexwaugh.com>
MAINTENANCE: Maintained
STATUS: Experimental
-------------------------------------------------------------------------------
@@ -69,448 +89,409 @@ 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)
MAINTENANCE: Maintained
STATUS: Working
COMMENT: DBM abstraction for db2, db3, db4, dbm, ndbm, gdbm, ini
-------------------------------------------------------------------------------
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)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.0
-------------------------------------------------------------------------------
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
STATUS: Working
SINCE: 5.3
-------------------------------------------------------------------------------
EXTENSION: oci8
PRIMARY MAINTAINER: Christopher Jones <sixd@php.net> (2007 - 2017)
Antony Dovgal <tony2001@php.net> (2003 - 2009)
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: odbc
PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net> (2000 - 2004)
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
COMMENT: Working
SINCE: 4.0.6
COMMENT: DB abstraction for odbc, mysql, pgsql, mssql, fbsql and more, see documentation
-------------------------------------------------------------------------------
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: filepro
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: pdo_dblib
PRIMARY MAINTAINER: Adam Baratz <adambaratz@php.net> (2016 - 2017)
EXTENSION: hyperwave
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
EXTENSION: pdo_firebird
PRIMARY MAINTAINER: Lars Westermann <lwe@php.net> (2007 - 2007)
EXTENSION: informix
PRIMARY MAINTAINER: Danny Heijl <Danny.Heijl@cevi.be>
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: ingres_ii
PRIMARY MAINTAINER: David Hénot <henot@php.net>
MAINTENANCE: Maintained
STATUS: Experimental
SINCE: 4.0.2
-------------------------------------------------------------------------------
EXTENSION: pdo_odbc
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Odd fixes
EXTENSION: interbase
PRIMARY MAINTAINER: Jouni Ahto <jouni.ahto@exdec.fi>
MAINTENANCE: Odd Fixes
STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
EXTENSION: pdo_oci
PRIMARY MAINTAINER: Christopher Jones <sixd@php.net> (2007 - 2017)
MAINTENANCE: Odd fixes
EXTENSION: msql
MAINTENANCE: Unknown
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: 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: pdo_sqlite
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net> (2005 - 2011)
MAINTENANCE: Odd fixes
EXTENSION: mssql
PRIMARY MAINTAINER: Frank M. Kromann <fmk@swwwing.com>
MAINTENANCE: Maintained
STATUS: Working
COMMENT: Tested on phpts and isapi versions
-------------------------------------------------------------------------------
EXTENSION: mysql
PRIMARY MAINTAINER: Zak Greant <zak@mysql.com>, Georg Richter <georg@php.net>
MAINTENANCE: Maintained
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)
Christoph M. Becker <cmb@php.net> (2016 - 2020)
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: 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
-------------------------------------------------------------------------------
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> (2004 - 2010)
Christian Stocker <chregu@php.net> (2004 - 2004)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: xmlwriter
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net> (2004 - 2010)
Pierre-Alain Joye <pajoye@php.net> (2005-2009)
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
PRIMARY MAINTAINER: 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)
PRIMARY MAINTAINER: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Odd Fixes
STATUS: Working
SINCE: 4.0.3
-------------------------------------------------------------------------------
EXTENSION: dio
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Orphaned
STATUS: Working
SINCE: 4.0.6
-------------------------------------------------------------------------------
EXTENSION: cyrus
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Orphaned
STATUS: Working
SINCE: 4.0.6
-------------------------------------------------------------------------------
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)
Christoph M. Becker <cmb@php.net> (2018 - 2020)
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: ffi
PRIMARY MAINTAINER: Dmitry Stogov <dmitry@php.net> (2018 - 2019)
EXTENSION: fdf
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
MAINTENANCE: Maintained
STATUS: Experimental
SINCE: 7.4.0
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: fileinfo
PRIMARY MAINTAINER: Derick Rethans <derick@php.net> (2004 - 2008)
Anatol Belski <ab@php.net> (2012 - 2020)
EXTENSION: fribidi
PRIMARY MAINTAINER: Tal Peer <tal@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
-------------------------------------------------------------------------------
EXTENSION: ftp
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Odd fixes
PRIMARY MAINTAINER: Stefan Esser (sesser@php.net)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: gd
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net> (2002 - 2016)
Christoph M. Becker <cmb@php.net> (2015 - 2020)
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: gettext
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: gmp
PRIMARY MAINTAINER: Stanislav Malyshev <stas@php.net> (2000 - 2019)
Antony Dovgal <tony2001@php.net> (2005 - 2010)
Nikita Popov <nikic@php.net> (2013 - 2020)
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: icap
MAINTENANCE: Unknown
STATUS: Obsolete
-------------------------------------------------------------------------------
EXTENSION: iconv
PRIMARY MAINTAINER: Moriyoshi Koizumi <moriyoshi@php.net> (2002 - 2010)
PRIMARY MAINTAINER: Moriyoshi Koizumi <moriyoshi@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: intl
PRIMARY MAINTAINER: Stanislav Malyshev <stas@php.net> (2008 - 2019)
Anatol Belski <ab@php.net> (2017 - 2018)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
-------------------------------------------------------------------------------
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)
Bishop Bettini <bishop@php.net> (2018 - 2019)
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)
Nikita Popov <nikic@php.net> (2017 - 2020)
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 - 2020)
Nikita Popov <nikic@php.net> (2016 - 2020)
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)
Bishop Bettini <bishop@php.net> (2018 - 2019)
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: readline
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: reflection
PRIMARY MAINTAINER: Marcus Börger <helly@php.net> (2003 - 2009)
Johannes Schlüter <johannes@php.net> (2006 - 2014)
Nikita Popov <nikic@php.net> (2019 - 2020)
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: Unknown
-------------------------------------------------------------------------------
EXTENSION: recode
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de>
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)
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
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Unknown
STATUS: Working
EXTENSION: swf
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Orphaned
STATUS: Deprecated (Use the ming swf extension instead)
COMMENT: Only for Unix (won't change)
-------------------------------------------------------------------------------
EXTENSION: sysvsem
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Unknown
STATUS: Working
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: sysvshm
PRIMARY MAINTAINER: Unknown
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)
EXTENSION: vpopmail
MAINTENANCE: Unknown
STATUS: Experimental
SINCE: 4.0.5
-------------------------------------------------------------------------------
EXTENSION: wddx
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: tokenizer
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net> (2002 - 2002)
Nikita Popov <nikic@php.net> (2013 - 2020)
EXTENSION: xml
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: zip
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net> (2006 - 2011)
Remi Collet <remi@php.net> (2013-2020)
EXTENSION: xslt
PRIMARY MAINTAINER: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Odd Fixes
STATUS: Working (mostly)
-------------------------------------------------------------------------------
EXTENSION: yaz
PRIMARY MAINTAINER: Adam Dickmeiss <adam@indexdata.dk>
MAINTENANCE: Maintained
STATUS: Working
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: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Odd Fixes
STATUS: Working
SINCE: 4.0.5
-------------------------------------------------------------------------------
# iptc?
+417
View File
@@ -0,0 +1,417 @@
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 \
+18 -18
View File
@@ -1,7 +1,7 @@
--------------------------------------------------------------------
The PHP License, version 3.01
Copyright (c) 1999 - 2021 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>.
+18
View File
@@ -0,0 +1,18 @@
$(builddir)/zend_language_scanner.lo: $(builddir)/zend_language_parser.h
$(builddir)/zend_ini_scanner.lo: $(builddir)/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
$(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 $@
$(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 $@
$(builddir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
$(LEX) -Pini_ -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_ini_scanner.l
$(builddir)/zend_indent.lo $(builddir)/zend_highlight.lo $(builddir)/zend_compile.lo: $(builddir)/zend_language_parser.h
+68
View File
@@ -0,0 +1,68 @@
mkinstalldirs = $(top_srcdir)/build/shtool mkdir -p
INSTALL = $(top_srcdir)/build/shtool install -c
INSTALL_DATA = $(INSTALL) -m 644
DEFS = -DPHP_ATOM_INC -I$(top_builddir)/include -I$(top_builddir)/main -I$(top_srcdir)
COMMON_FLAGS = $(DEFS) $(INCLUDES) $(EXTRA_INCLUDES) $(CPPFLAGS) $(PHP_FRAMEWORKPATH)
all: $(all_targets)
build-modules: $(PHP_MODULES)
libphp4.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 $@
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: $(install_targets)
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)/libphp4.$(SHLIB_SUFFIX_NAME); then \
for i in 0.0.0 0.0 0; do \
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-modules: build-modules
@test -d modules && \
$(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-tester:
@echo "Installing regression tester: $(INSTALL_ROOT)$(PEAR_INSTALLDIR)/"
@$(mkinstalldirs) $(INSTALL_ROOT)$(PEAR_INSTALLDIR)
@$(INSTALL) -m 755 $(top_srcdir)/run-tests.php $(INSTALL_ROOT)$(PEAR_INSTALLDIR)
install-su: install-pear install-tester
test: $(SAPI_CLI_PATH)
@TEST_PHP_EXECUTABLE=$(top_builddir)/$(SAPI_CLI_PATH) \
TEST_PHP_SRCDIR=$(top_srcdir) \
CC=$(CC) \
$(top_builddir)/$(SAPI_CLI_PATH) -d 'open_basedir=' -d 'safe_mode=0' $(top_srcdir)/run-tests.php $(TESTS)
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
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp4.la $(SAPI_CLI_PATH) $(OVERALL_TARGET) modules/* libs/*
distclean: clean
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
egrep define'.*include/php' configure|sed 's/.*>//'|xargs rm -f
find . -name Makefile | xargs rm -f
.PHONY: all clean install distclean test
.NOEXPORT:
+2451 -692
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.
+189
View File
@@ -0,0 +1,189 @@
WHAT IT IS
It's a tool for automatically creating the basic framework for a PHP module
and writing C code handling arguments passed to your functions from a simple
configuration file. See an example at the end of this file.
HOW TO USE IT
Very simple. First, change to the ext/ directory of the PHP 4 sources. If
you just need the basic framework and will be writing all the code in your
functions yourself, you can now do
./ext_skel --extname=module_name
and everything you need is placed in directory module_name.
[ Note that GNU awk is likely required for this script to work. Debian
systems seem to default to using mawk, so you may need to change the
#! line in skeleton/create_stubs to use gawk explicitly. ]
If you don't need to test the existence of any external header files,
libraries or functions in them, the module is already almost ready to be
compiled in PHP. Just remove 3 comments in your_module_name/config.m4,
change back up to PHP sources top directory, and do
./buildconf; ./configure --enable-module_name; make
But if you already have planned the overall scheme of your module, what
functions it will contain, their return types and the arguments they take
(a very good idea) and don't want to bother yourself with creating function
definitions and handling arguments passed yourself, it's time to create a
function definitions file, which you will give as an argument to ext_skel
with option
--proto=filename.
FORMAT OF FUNCTION DEFINITIONS FILE
All the definitions must be on one line. In it's simplest form, it's just
the function name, e.g.
my_function
but then you'll be left with an almost empty function body without any
argument handling.
Arguments are given in parenthesis after the function name, and are of
the form 'argument_type argument_name'. Arguments are separated from each
other with a comma and optional space. Argument_type can be one of int,
bool, double, float, string, array, object or mixed.
An optional argument is separated from the previous by an optional space,
then '[' and of course comma and optional space, like all the other
arguments. You should close a row of optional arguments with same amount of
']'s as there where '['s. Currently, it does not harm if you forget to do it
or there is a wrong amount of ']'s, but this may change in the future.
An additional short description may be added after the parameters.
If present it will be filled into the 'proto' header comments in the stubs
code and the <refpurpose> tag in the XML documentation.
An example:
my_function(int arg1, int arg2 [, int arg3 [, int arg4]]) this is my 1st
Arguments arg3 and arg4 are optional.
If possible, the function definition should also contain it's return type
in front of the definition. It's not actually used for any C code generating
purposes but PHP in-source documentation instead, and as such, very useful.
It can be any of int, double, string, bool, array, object, resource, mixed
or void.
The file must contain nothing else but function definitions, no comments or
empty lines.
OTHER OPTIONS
--no-help
By default, ext_skel creates both comments in the source code and a test
function to help first time module writers to get started and testing
configuring and compiling their module. This option turns off all such things
which may just annoy experienced PHP module coders. Especially useful with
--stubs=file
which will leave out also all module specific stuff and write just function
stubs with function value declarations and passed argument handling, and
function entries and definitions at the end of the file, for copying and
pasting into an already existing module.
--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");
}
/* }}} */
+127
View File
@@ -0,0 +1,127 @@
New parameter parsing functions
===============================
It should be easier to parse input parameters to an extension function.
Hence, borrowing from Python's example, there are now a set of functions
that given the string of type specifiers, can parse the input parameters
and store the results in the user specified variables. This avoids most
of the IS_* checks and convert_to_* conversions. The functions also
check for the appropriate number of parameters, and try to output
meaningful error messages.
Prototypes
----------
/* Implemented. */
int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);
int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...);
The zend_parse_parameters() function takes the number of parameters
passed to the extension function, the type specifier string, and the
list of pointers to variables to store the results in. The _ex() version
also takes 'flags' argument -- current only ZEND_PARSE_PARAMS_QUIET can
be used as 'flags' to specify that the function should operate quietly
and not output any error messages.
Both functions return SUCCESS or FAILURE depending on the result.
The auto-conversions are performed as necessary. Arrays, objects, and
resources cannot be auto-converted.
Type specifiers
---------------
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 (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 */
long l;
char *s;
int s_len;
zval *param;
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() TSRMLS_CC, "O|d",
&obj, my_ce, &d) == FAILURE) {
return;
}
/* Gets an object or null, and an array.
If null is passed for object, obj will be set to NULL. */
zval *obj;
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o!a",
&obj, &arr) == FAILURE) {
return;
}
/* Gets a separated array which can also be null. */
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!",
&arr) == FAILURE) {
return;
}
/* Get 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. */
long l1, l2, l3;
char *s;
/*
* The function expects a pointer to a integer in this case, not a long
* or any other type. If you specify a type which is larger
* than a 'int', the upper bits might not be initialized
* properly, leading to random crashes on platforms like
* Tru64 or Linux/Alpha.
*/
int length;
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"lll", &l1, &l2, &l3) == SUCCESS) {
/* manipulate longs */
} else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"s", &s, &length) == SUCCESS) {
/* manipulate string */
} else {
/* output error */
return;
}
+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
-642
View File
@@ -1,642 +0,0 @@
1. libmagic (ext/fileinfo) see ext/fileinfo/libmagic/LICENSE
2. libmbfl (ext/mbstring) see ext/mbstring/libmbfl/LICENSE
3. pcre2lib (ext/pcre)
4. ext/standard crypt
5. ext/standard crypt's blowfish implementation
6. ext/standard/rand
7. ext/standard/scanf
8. ext/standard/strnatcmp.c
9. ext/standard/uuencode
10. main/snprintf.c
11. main/strlcat
12. main/strlcpy
13. libgd (ext/gd)
14. ext/phar portions of tar implementations
15. ext/phar/zip.c portion extracted from libzip
16. libbcmath (ext/bcmath) see ext/bcmath/libbcmath/LICENSE
17. ext/mbstring/ucgendat portions based on the ucgendat.c from the OpenLDAP
3. 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.
Releases 10.00 and above of PCRE2 are 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-2019 University of Cambridge
All rights reserved.
PCRE2 JUST-IN-TIME COMPILATION SUPPORT
--------------------------------------
Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
Copyright(c) 2010-2019 Zoltan Herczeg
All rights reserved.
STACK-LESS JUST-IN-TIME COMPILER
--------------------------------
Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
Copyright(c) 2009-2019 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
4. 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.
5. 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).
6. 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.
7. 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.
8. 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.
9. 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.
10. 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.
11. main/strlcat
12. 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.
13. libgd (ext/gd)
* Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004 by Cold Spring Harbor Laboratory. Funded under
Grant P41-RR02188 by the National Institutes of Health.
* Portions copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004 by Boutell.Com, Inc.
* Portions relating to GD2 format copyright 1999, 2000, 2001, 2002,
2003, 2004 Philip Warner.
* Portions relating to PNG copyright 1999, 2000, 2001, 2002, 2003,
2004 Greg Roelofs.
* Portions relating to gdttf.c copyright 1999, 2000, 2001, 2002,
2003, 2004 John Ellson (ellson@graphviz.org).
* Portions relating to gdft.c copyright 2001, 2002, 2003, 2004 John
Ellson (ellson@graphviz.org).
* Portions copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Pierre-Alain Joye (pierre@libgd.org).
* Portions relating to JPEG and to color quantization copyright
2000, 2001, 2002, 2003, 2004, Doug Becker and copyright (C) 1994,
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Thomas
G. Lane. This software is based in part on the work of the
Independent JPEG Group. See the file README-JPEG.TXT for more
information.
* Portions relating to GIF compression copyright 1989 by Jef
Poskanzer and David Rowley, with modifications for thread safety
by Thomas Boutell.
* Portions relating to GIF decompression copyright 1990, 1991, 1993
by David Koblas, with modifications for thread safety by Thomas
Boutell.
* Portions relating to WBMP copyright 2000, 2001, 2002, 2003, 2004
Maurice Szmurlo and Johan Van den Brande.
* Portions relating to GIF animations copyright 2004 Jaakko Hyvätti
(jaakko.hyvatti@iki.fi)
Permission has been granted to copy, distribute and modify gd in
any context without fee, including a commercial application,
provided that this notice is present in user-accessible supporting
documentation.
This does not affect your ownership of the derived work itself,
and the intent is to assure proper credit for the authors of gd,
not to interfere with your productive use of gd. If you have
questions, ask. "Derived works" includes all programs that utilize
the library. Credit must be given in user-accessible
documentation.
This software is provided "AS IS." The copyright holders disclaim
all warranties, either express or implied, including but not
limited to implied warranties of merchantability and fitness for a
particular purpose, with respect to this code and accompanying
documentation.
Although their code does not appear in the current release, the
authors wish to thank David Koblas, David Rowley, and Hutchison
Avenue Software Corporation for their prior contributions.
END OF COPYRIGHT STATEMENT
14. 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.
15. ext/phar/zip.c portion extracted from libzip
zip_dirent.c -- read directory entry (local or central), clean dirent
Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner
This function is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <nih@giga.or.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.
16. ext/mbstring/ucgendat portions based on the ucgendat.c from the OpenLDAP
The OpenLDAP Public License
Version 2.8, 17 August 2003
Redistribution and use of this software and associated documentation
("Software"), with or without modification, are permitted provided
that the following conditions are met:
1. Redistributions in source form must retain copyright statements
and notices,
2. Redistributions in binary form must reproduce applicable copyright
statements and notices, this list of conditions, and the following
disclaimer in the documentation and/or other materials provided
with the distribution, and
3. Redistributions must contain a verbatim copy of this document.
The OpenLDAP Foundation may revise this license from time to time.
Each revision is distinguished by a version number. You may use
this Software under terms of this license revision or under the
terms of any subsequent revision of the license.
THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS
CONTRIBUTORS ``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 OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S)
OR OWNER(S) OF THE SOFTWARE 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.
The names of the authors and copyright holders must not be used in
advertising or otherwise to promote the sale, use or other dealing
in this Software without specific, written prior permission. Title
to copyright in this Software shall at all times remain with copyright
holders.
OpenLDAP is a registered trademark of the OpenLDAP Foundation.
Copyright 1999-2003 The OpenLDAP Foundation, Redwood City,
California, USA. All Rights Reserved. Permission to copy and
distribute verbatim copies of this document is granted.
+155
View File
@@ -0,0 +1,155 @@
$Id$
=============================================================================
HOW TO CREATE A SELF-CONTAINED PHP EXTENSION
A self-contained extension can be distributed independently of
the PHP source. To create such an extension, two things are
required:
- Configuration file (config.m4)
- Source code for your module
We will describe now how to create these and how to put things
together.
PREPARING YOUR SYSTEM
While the result will run on any system, a developer's setup needs these
tools:
GNU autoconf
GNU automake
GNU libtool
GNU m4
All of these are available from
ftp://ftp.gnu.org/pub/gnu/
CONVERTING AN EXISTING EXTENSION
Just to show you how easy it is to create a self-contained
extension, we will convert an embedded extension into a
self-contained one. Install PHP and execute the following
commands.
$ mkdir /tmp/newext
$ cd /tmp/newext
You now have an empty directory. We will copy the files from
the mysql extension:
$ cp -rp php-4.0.X/ext/mysql/* .
It is time to finish the module. Run:
$ phpize
You can now ship the contents of the directory - the extension
can live completely on its own.
The user instructions boil down to
$ ./configure \
[--with-php-config=/path/to/php-config] \
[--with-mysql=MYSQL-DIR]
$ make install
The MySQL module will either use the embedded MySQL client
library or the MySQL installation in MYSQL-DIR.
DEFINING THE NEW EXTENSION
Our demo extension is called "foobar".
It consists of two source files "foo.c" and "bar.c"
(and any arbitrary amount of header files, but that is not
important here).
The demo extension does not reference any external
libraries (that is important, because the user does not
need to specify anything).
LTLIBRARY_SOURCES specifies the names of the sources files. You can
name an arbitrary number of source files here.
CREATING THE M4 CONFIGURATION FILE
The m4 configuration can perform additional checks. For a
self-contained extension, you do not need more than a few
macro calls.
------------------------------------------------------------------------------
PHP_ARG_ENABLE(foobar,whether to enable foobar,
[ --enable-foobar Enable foobar])
if test "$PHP_FOOBAR" != "no"; then
PHP_NEW_EXTENSION(foobar, foo.c bar.c, $ext_shared)
fi
------------------------------------------------------------------------------
PHP_ARG_ENABLE will automatically set the correct variables, so
that the extension will be enabled by PHP_NEW_EXTENSION in shared mode.
The first argument of PHP_NEW_EXTENSION describes the name of the
extension. The second names the source-code files. The third passes
$ext_shared which is set by PHP_ARG_ENABLE/WITH to PHP_NEW_EXTENSION.
Please use always PHP_ARG_ENABLE or PHP_ARG_WITH. Even if you do not
plan to distribute your module with PHP, these facilities allow you
to integrate your module easily into the main PHP module framework.
CREATING SOURCE FILES
ext_skel can be of great help when creating the common code for all modules
in PHP for you and also writing basic function definitions and C code for
handling arguments passed to your functions. See README.EXT_SKEL for further
information.
As for the rest, you are currently alone here. There are a lot of existing
modules, use a simple module as a starting point and add your own code.
CREATING THE SELF-CONTAINED EXTENSION
Put config.m4 and the source files into one directory. Then, run phpize
(this is installed during make install by PHP 4.0).
For example, if you configured PHP with --prefix=/php, you would run
$ /php/bin/phpize
This will automatically copy the necessary build files and create
configure from your config.m4.
And that's it. You now have a self-contained extension.
INSTALLING A SELF-CONTAINED EXTENSION
An extension can be installed by running:
$ ./configure \
[--with-php-config=/path/to/php-config]
$ make install
ADDING SHARED MODULE SUPPORT TO A MODULE
In order to be useful, a self-contained extension must be loadable
as a shared module. I will explain now how you can add shared module
support to an existing module called foo.
1. In config.m4, use PHP_ARG_WITH/PHP_ARG_ENABLE. Then you will
automatically be able to use --with-foo=shared[,..] or
--enable-foo=shared[,..].
2. In config.m4, use PHP_NEW_EXTENSION(foo,.., $ext_shared) to enable
building the extension.
3. Add the following lines to your C source file:
#ifdef COMPILE_DL_FOO
ZEND_GET_MODULE(foo)
#endif
+373
View File
@@ -0,0 +1,373 @@
An Overview of the PHP Streams abstraction
==========================================
$Id$
WARNING: some prototypes in this file are out of date.
The information contained here is being integrated into
the PHP manual - stay tuned...
Please send comments to: Wez Furlong <wez@thebrainroom.com>
Why Streams?
============
You may have noticed a shed-load of issock parameters flying around the PHP
code; we don't want them - they are ugly and cumbersome and force you to
special case sockets and files every time you need to work with a "user-level"
PHP file pointer.
Streams take care of that and present the PHP extension coder with an ANSI
stdio-alike API that looks much nicer and can be extended to support non file
based data sources.
Using Streams
=============
Streams use a php_stream* parameter just as ANSI stdio (fread etc.) use a
FILE* parameter.
The main functions are:
PHPAPI size_t php_stream_read(php_stream * stream, char * buf, size_t count);
PHPAPI size_t php_stream_write(php_stream * stream, const char * buf, size_t
count);
PHPAPI size_t php_stream_printf(php_stream * stream TSRMLS_DC,
const char * fmt, ...);
PHPAPI int php_stream_eof(php_stream * stream);
PHPAPI int php_stream_getc(php_stream * stream);
PHPAPI char *php_stream_gets(php_stream * stream, char *buf, size_t maxlen);
PHPAPI int php_stream_close(php_stream * stream);
PHPAPI int php_stream_flush(php_stream * stream);
PHPAPI int php_stream_seek(php_stream * stream, off_t offset, int whence);
PHPAPI off_t php_stream_tell(php_stream * stream);
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.
Opening Streams
===============
In most cases, you should use this API:
PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode,
int options, char **opened_path TSRMLS_DC);
Where:
path is the file or resource to open.
mode is the stdio compatible mode eg: "wb", "rb" etc.
options is a combination of the following values:
IGNORE_PATH (default) - don't use include path to search for the file
USE_PATH - use include path to search for the file
IGNORE_URL - do not use plugin wrappers
REPORT_ERRORS - show errors in a standard format if something
goes wrong.
STREAM_MUST_SEEK - If you really need to be able to seek the stream
and don't need to be able to write to the original
file/URL, use this option to arrange for the stream
to be copied (if needed) into a stream that can
be seek()ed.
opened_path is used to return the path of the actual file opened,
but if you used STREAM_MUST_SEEK, may not be valid. You are
responsible for efree()ing opened_path. opened_path may be (and usually
is) NULL.
If you need to open a specific stream, or convert standard resources into
streams there are a range of functions to do this defined in php_streams.h.
A brief list of the most commonly used functions:
PHPAPI php_stream *php_stream_fopen_from_file(FILE *file, const char *mode);
Convert a FILE * into a stream.
PHPAPI php_stream *php_stream_fopen_tmpfile(void);
Open a FILE * with tmpfile() and convert into a stream.
PHPAPI php_stream *php_stream_fopen_temporary_file(const char *dir,
const char *pfx, char **opened_path TSRMLS_DC);
Generate a temporary file name and open it.
There are some network enabled relatives in php_network.h:
PHPAPI php_stream *php_stream_sock_open_from_socket(int socket, int persistent);
Convert a socket into a stream.
PHPAPI php_stream *php_stream_sock_open_host(const char *host, unsigned short port,
int socktype, int timeout, int persistent);
Open a connection to a host and return a stream.
PHPAPI php_stream *php_stream_sock_open_unix(const char *path, int persistent,
struct timeval *timeout);
Open a UNIX domain socket.
Stream Utilities
================
If you need to copy some data from one stream to another, you will be please
to know that the streams API provides a standard way to do this:
PHPAPI size_t php_stream_copy_to_stream(php_stream *src,
php_stream *dest, size_t maxlen);
If you want to copy all remaining data from the src stream, pass
PHP_STREAM_COPY_ALL as the maxlen parameter, otherwise maxlen indicates the
number of bytes to copy.
This function will try to use mmap where available to make the copying more
efficient.
If you want to read the contents of a stream into an allocated memory buffer,
you should use:
PHPAPI size_t php_stream_copy_to_mem(php_stream *src, char **buf,
size_t maxlen, int persistent);
This function will set buf to the address of the buffer that it allocated,
which will be maxlen bytes in length, or will be the entire length of the
data remaining on the stream if you set maxlen to PHP_STREAM_COPY_ALL.
The buffer is allocated using pemalloc(); you need to call pefree() to
release the memory when you are done.
As with copy_to_stream, this function will try use mmap where it can.
If you have an existing stream and need to be able to seek() it, you
can use this function to copy the contents into a new stream that can
be seek()ed:
PHPAPI int php_stream_make_seekable(php_stream *origstream, php_stream **newstream);
It returns one of the following values:
#define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */
#define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */
#define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */
#define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */
make_seekable will always set newstream to be the stream that is valid
if the function succeeds.
When you have finished, remember to close the stream.
NOTE: If you only need to seek forward, there is no need to call this
function, as the php_stream_seek can emulate forward seeking when the
whence parameter is SEEK_CUR.
NOTE: Writing to the stream may not affect the original source, so it
only makes sense to use this for read-only use.
NOTE: If the origstream is network based, this function will block
until the whole contents have been downloaded.
NOTE: Never call this function with an origstream that is referenced
as a resource! It will close the origstream on success, and this
can lead to a crash when the resource is later used/released.
NOTE: If you are opening a stream and need it to be seekable, use the
STREAM_MUST_SEEK option to php_stream_open_wrapper();
Casting Streams
===============
What if your extension needs to access the FILE* of a user level file pointer?
You need to "cast" the stream into a FILE*, and this is how you do it:
FILE * fp;
php_stream * stream; /* already opened */
if (php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void*)&fp, REPORT_ERRORS) == FAILURE) {
RETURN_FALSE;
}
The prototype is:
PHPAPI int php_stream_cast(php_stream * stream, int castas, void ** ret, int
show_err);
The show_err parameter, if non-zero, will cause the function to display an
appropriate error message of type E_WARNING if the cast fails.
castas can be one of the following values:
PHP_STREAM_AS_STDIO - a stdio FILE*
PHP_STREAM_AS_FD - a generic file descriptor
PHP_STREAM_AS_SOCKETD - a socket descriptor
If you ask a socket stream for a FILE*, the abstraction will use fdopen to
create it for you. Be warned that doing so may cause buffered data to be lost
if you mix ANSI stdio calls on the FILE* with php stream calls on the stream.
If your system has the fopencookie function, php streams can synthesize a
FILE* on top of any stream, which is useful for SSL sockets, memory based
streams, data base streams etc. etc.
In situations where this is not desirable, you should query the stream
to see if it naturally supports FILE *. You can use this code snippet
for this purpose:
if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) {
/* can safely cast to FILE* with no adverse side effects */
}
You can use:
PHPAPI int php_stream_can_cast(php_stream * stream, int castas)
to find out if a stream can be cast, without actually performing the cast, so
to check if a stream is a socket you might use:
if (php_stream_can_cast(stream, PHP_STREAM_AS_SOCKETD) == SUCCESS) {
/* it can be a socket */
}
Please note the difference between php_stream_is and php_stream_can_cast;
stream_is tells you if the stream is a particular type of stream, whereas
can_cast tells you if the stream can be forced into the form you request.
The former doesn't change anything, while the later *might* change some
state in the stream.
Stream Internals
================
There are two main structures associated with a stream - the php_stream
itself, which holds some state information (and possibly a buffer) and a
php_stream_ops structure, which holds the "virtual method table" for the
underlying implementation.
The php_streams ops struct consists of pointers to methods that implement
read, write, close, flush, seek, gets and cast operations. Of these, an
implementation need only implement write, read, close and flush. The gets
method is intended to be used for streams if there is an underlying method
that can efficiently behave as fgets. The ops struct also contains a label
for the implementation that will be used when printing error messages - the
stdio implementation has a label of "STDIO" for example.
The idea is that a stream implementation defines a php_stream_ops struct, and
associates it with a php_stream using php_stream_alloc.
As an example, the php_stream_fopen() function looks like this:
PHPAPI php_stream * php_stream_fopen(const char * filename, const char * mode)
{
FILE * fp = fopen(filename, mode);
php_stream * ret;
if (fp) {
ret = php_stream_alloc(&php_stream_stdio_ops, fp, 0, 0, mode);
if (ret)
return ret;
fclose(fp);
}
return NULL;
}
php_stream_stdio_ops is a php_stream_ops structure that can be used to handle
FILE* based streams.
A socket based stream would use code similar to that above to create a stream
to be passed back to fopen_wrapper (or it's yet to be implemented successor).
The prototype for php_stream_alloc is this:
PHPAPI php_stream * php_stream_alloc(php_stream_ops * ops, void * abstract,
size_t bufsize, int persistent, const char * mode)
ops is a pointer to the implementation,
abstract holds implementation specific data that is relevant to this instance
of the stream,
bufsize is the size of the buffer to use - if 0, then buffering at the stream
level will be disabled (recommended for underlying sources that implement
their own buffering - such a FILE*),
persistent controls how the memory is to be allocated - persistently so that
it lasts across requests, or non-persistently so that it is freed at the end
of a request (it uses pemalloc),
mode is the stdio-like mode of operation - php streams places no real meaning
in the mode parameter, except that it checks for a 'w' in the string when
attempting to write (this may change).
The mode parameter is passed on to fdopen/fopencookie when the stream is cast
into a FILE*, so it should be compatible with the mode parameter of fopen().
Writing your own stream implementation
======================================
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
RULE #1: when writing your own streams: make sure you have configured PHP with
--enable-debug.
I've taken some great pains to hook into the Zend memory manager to help track
down allocation problems. It will also help you spot incorrect use of the
STREAMS_DC, STREAMS_CC and the semi-private STREAMS_REL_CC macros for function
definitions.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
RULE #2: Please use the stdio stream as a reference; it will help you
understand the semantics of the stream operations, and it will always
be more up to date than these docs :-)
First, you need to figure out what data you need to associate with the
php_stream. For example, you might need a pointer to some memory for memory
based streams, or if you were making a stream to read data from an RDBMS like
MySQL, you might want to store the connection and rowset handles.
The stream has a field called abstract that you can use to hold this data.
If you need to store more than a single field of data, define a structure to
hold it, allocate it (use pemalloc with the persistent flag set
appropriately), and use the abstract pointer to refer to it.
For structured state you might have this:
struct my_state {
MYSQL conn;
MYSQL_RES * result;
};
struct my_state * state = pemalloc(sizeof(struct my_state), persistent);
/* initialize the connection, and run a query, using the fields in state to
* hold the results */
state->result = mysql_use_result(&state->conn);
/* now allocate the stream itself */
stream = php_stream_alloc(&my_ops, state, 0, persistent, "r");
/* now stream->abstract == state */
Once you have that part figured out, you can write your implementation and
define the your own php_stream_ops struct (we called it my_ops in the above
example).
For example, for reading from this weird MySQL stream:
static size_t php_mysqlop_read(php_stream * stream, char * buf, size_t count)
{
struct my_state * state = (struct my_state*)stream->abstract;
if (buf == NULL && count == 0) {
/* in this special case, php_streams is asking if we have reached the
* end of file */
if (... at end of file ...)
return EOF;
else
return 0;
}
/* pull out some data from the stream and put it in buf */
... mysql_fetch_row(state->result) ...
/* we could do something strange, like format the data as XML here,
and place that in the buf, but that brings in some complexities,
such as coping with a buffer size too small to hold the data,
so I won't even go in to how to do that here */
}
Implement the other operations - remember that write, read, close and flush
are all mandatory. The rest are optional. Declare your stream ops struct:
php_stream_ops my_ops = {
php_mysqlop_write, php_mysqlop_read, php_mysqlop_close,
php_mysqlop_flush, NULL, NULL, NULL,
"Strange MySQL example"
}
Thats it!
Take a look at the STDIO implementation in streams.c for more information
about how these operations work.
The main thing to remember is that in your close operation you need to release
and free the resources you allocated for the abstract field. In the case of
the example above, you need to use mysql_free_result on the rowset, close the
connection and then use pefree to dispose of the struct you allocated.
You may read the stream->persistent field to determine if your struct was
allocated in persistent mode or not.
vim:tw=78:et
+126
View File
@@ -0,0 +1,126 @@
Submitting Patch for PHP
========================
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. :-)
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)
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.
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.
Recommended CVS client settings for creating patch file
------------------------------------------------------
Recommended ~/.cvsrc file setting is:
------
cvs -z3
update -d -P
checkout -P
diff -u
------
diff -u means:
-u Use the unified output format.
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 the PHP and
web server 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?
Where to send your patch?
-------------------------
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 you are patching PEAR, send the patch to pear-dev@lists.php.net.
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.
NOTE: only MIME attachments of type 'text/*' are accepted. The
easiest way to acclomplish this, is to make the extension
'.txt'.
Test scripts should be included in the same email.
Explain what has been fixed/added/changed by your patch.
Finally, add the bug Id(s) which can be closed by your patch, if any.
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.
Because this is a volunteer-driven effort, more complex patches will
require more patience on your side.
If you did not receive any feedback in a few days, please consider
resubmitting the description of your patch, along-side with
these questions:
- 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?
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.
Thank you for submitting patch for PHP!
+307
View File
@@ -0,0 +1,307 @@
[IMPORTANT NOTICE]
------------------
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]
----------------
To execute test scripts, you must build PHP with some SAPI, then you
type "make test" to execute all or some test scripts saved under
"tests" directory under source root directory.
Usage:
make test
"make test" basically executes "run-tests.php" script
under the source root (parallel builds will not work). Therefore you
can execute the script as follows:
TEST_PHP_EXECUTABLE=sapi/cli/php \
sapi/cli/php [-c /path/to/php.ini] run-tests.php [ext/foo/tests/GLOB]
[Which "php" executable "make test" look for]
---------------------------------------------
You must use TEST_PHP_EXECUTABLE environment variable to explicitly
select the php executable to be used to run the tests. That can either
be the CLI or CGI executable.
"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.
NOTE: PHP binary executing "run-tests.php" and php binary used for
executing test scripts may differ. If you use different PHP binary for
executing "run-tests.php" script, you may get errors.
[Which php.ini is used]
-----------------------
"make test" uses the same php.ini file as it would once installed.
The tests have been written to be independent of that php.ini file,
so if you find a test that is affected by a setting, please report
this, so we can address the issue.
[Which test scripts are executed]
---------------------------------
"run-tests.php" ("make test"), without any arguments executes all
test scripts by extracting all directories named "tests"
from the source root and any subdirectories below. If there are files,
which have a "phpt" extension, "run-tests.php" looks at the sections
in these files, determines whether it should run it, by evaluating
the 'SKIP' section. If the test is eligible for execution, the 'FILE'
section is extracted into a ".php" file (with the same name besides
the extension) and gets executed.
When an argument is given or TESTS environment variable is set, the
GLOB is expanded by the shell and any file with extension "*.phpt" is
regarded as a test file.
Tester can easily execute tests selectively with as follows.
Examples:
./sapi/cli/php run-tests.php ext/mbstring/*
./sapi/cli/php run-tests.php ext/mbstring/020.phpt
[Test results]
--------------
Test results are printed to standard output. If there is a failed test,
the "run-tests.php" script saves the result, the expected result and the
code executed to the test script directory. For example, if
ext/myext/tests/myext.phpt fails to pass, the following files are created:
ext/myext/tests/myext.php - actual test file executed
ext/myext/tests/myext.log - log of test execution (L)
ext/myext/tests/myext.exp - expected output (E)
ext/myext/tests/myext.out - output from test script (O)
ext/myext/tests/myext.diff - diff of .out and .exp (D)
Failed tests are always bugs. Either the test is bugged or not considering
factors applying to the tester's environment, or there is a bug in PHP.
If this is a known bug, we strive to provide bug numbers, in either the
test name or the file name. You can check the status of such a bug, by
going to: http://bugs.php.net/12345 where 12345 is the bug number.
For clarity and automated processing, bug numbers are prefixed by a hash
sign '#' in test names and/or test cases are named bug12345.phpt.
NOTE: The files generated by tests can be selected by setting the
environment variable TEST_PHP_LOG_FORMAT. For each file you want to be
generated use the character in brackets as shown above (default is LEOD).
The php file will be generated always.
NOTE: You can set environment variable TEST_PHP_DETAILED to enable
detailed test information.
[Automated testing]
If you like to keep up to speed, with latest developments and quality
assurance, setting the environment variable NO_INTERACTION to 1, will not
prompt the tester for any user input.
Normally, the exit status of "make test" is zero, regardless of the results
of independent tests. Set the environment variable REPORT_EXIT_STATUS to 1,
and "make test" will set the exit status ("$?") to non-zero, when an
individual test has failed.
Example script to be run by cron(1):
========== qa-test.sh =============
#!/bin/sh
CO_DIR=$HOME/cvs/php4
MYMAIL=qa-test@domain.com
TMPDIR=/var/tmp
TODAY=`date +"%Y%m%d"`
# Make sure compilation enviroment is correct
CONFIGURE_OPTS='--disable-all --enable-cli --with-pcre'
export MAKE=gmake
export CC=gcc
# Set test environment
export NO_INTERACTIVITY=1
export REPORT_EXIT_STATUS=1
cd $CO_DIR
cvs update . >>$TMPDIR/phpqatest.$TODAY
./cvsclean ; ./buildconf ; ./configure $CONFIGURE_OPTS ; $MAKE
$MAKE test >>$TMPDIR/phpqatest.$TODAY 2>&1
if test $? -gt 0
then
cat $TMPDIR/phpqatest.$TODAY | mail -s"PHP-QA Test Failed for $TODAY" $MYMAIL
fi
========== end of qa-test.sh =============
NOTE: the exit status of run-tests.php will be 1 when
REPORT_EXIT_STATUS is set. The result of "make test" may be higher
than that. At present, gmake 3.79.1 returns 2, so it is
advised to test for non-zero, rather then a specific value.
[Creating new test files]
-------------------------
Writing test file is very easy if you are used to PHP.
Here is an actual test file from standard module.
===== ext/standard/tests/strings/strtr.phpt =======
--TEST--
strtr() function
--FILE--
<?php
/* Do not change this test it is a REATME.TESTING example. */
$trans = array("hello"=>"hi", "hi"=>"hello", "a"=>"A", "world"=>"planet");
var_dump(strtr("# hi all, I said hello world! #", $trans));
?>
--EXPECT--
string(32) "# hello All, I sAid hi planet! #"
===== ext/standard/tests/strings/strtr.phpt =======
As you can see the file is devided into several sections. Below is a
list of all possible sections:
"--TEST--" is title of the test (required).
"--SKIPIF--" is condition when to skip this test (optional).
"--POST--" is POST variable passed to test script (optional).
"--GET--" is GET variable passed to test script (optional).
"--INI--" each line contains an ini setting e.g. foo=bar (optional).
"--FILE--" is the test script (required).
"--EXPECT--" is the expected output from the test script (required).
"--EXPECTF--" is an alternative of --EXPECT--. The difference is that
this form uses sscanf for output validation (alternative).
"--EXPECTREGEX--" is an alternative of --EXPECT--. This form allows the tester
to specify the result in a regular expression (alternative).
A test must at least contain the sections TEST, FILE and either EXPECT
or EXPECTF. When a test is called run-test.php takes the name from the
TEST section and writes the FILE section into a ".php" file with the
same name as the ".phpt" file. This ".php" file will then be executed
and its output compared to the contents of the EXPECT section. It is a
good idea to generate output with var_dump() calls.
/ext/standard/tests/strings/str_shuffle.phpt is a good example for using
EXPECTF instead of EXPECT. From time to time the algorithm used for shuffle
changed and sometimes the machine used to execute the code has influence
on the result of shuffle. But it always returns a three character string
detectable by %s. Other scan-able forms are %i for integers, %d for numbers
only, %f for floating point values, %c for single characters and %x for
hexadecimal values.
==== /ext/standard/tests/strings/str_shuffle.phpt ===
--TEST--
Testing str_shuffle.
--FILE--
<?php
/* Do not change this test it is a REATME.TESTING example. */
$s = '123';
var_dump(str_shuffle($s));
var_dump($s);
?>
--EXPECTF--
string(3) %s
string(3) "123"
==== end of /ext/standard/tests/strings/str_shuffle.phpt ===
/ext/standard/tests/strings/strings001.phpt is a good example for using
EXPECTREGEX instead of EXPECT. This test also shows that in EXPECTREGEX
some characters need to be escaped since otherwise they would be
interpreted as a regular expression.
==== /ext/standard/tests/strings/strings001.phpt ===
--TEST--
Test whether strstr() and strrchr() are binary safe.
--FILE--
<?php
/* Do not change this test it is a REATME.TESTING example. */
$s = "alabala nica".chr(0)."turska panica";
var_dump(strstr($s, "nic"));
var_dump(strrchr($s," nic"));
?>
--EXPECTREGEX--
string\(18\) \"nica\x00turska panica\"
string\(19\) \" nica\x00turska panica\"
==== end of /ext/standard/tests/strings/strings001.phpt ===
Some tests depend on modules or functions available only in certain versions
or they even require minimum version of php or zend. These tests should be
skipped when the requirement cannot be fullfilled. To achieve this you can
use the SKIPIF section. To tell run-test.php that your test should be skipped
the SKIPIF section must print out the word "skip" followed by a reason why
the test should skip.
==== /ext/exif/tests/exif005.phpt ===
--TEST--
Check for exif_read_data, unusual IFD start
--SKIPIF--
<?php
if (!extension_loaded('exif')) print 'skip exif extension not available';
?>
--FILE--
<?php
/* Do not change this test it is a REATME.TESTING example.
* test5.jpg is a 1*1 image that contains an Exif section with ifd = 00000009h
*/
$image = exif_read_data('./ext/exif/tests/test5.jpg','',true,false);
var_dump($image['IFD0']);
?>
--EXPECT--
array(2) {
["ImageDescription"]=>
string(11) "Ifd00000009"
["DateTime"]=>
string(19) "2002:10:18 20:06:00"
}
==== end of /ext/exif/tests/exif005.phpt ===
Test script and SKIPIF code should be directly written into *.phpt. However,
it is recommended to use include files when more test scripts depend on the
same SKIPIF code or when certain test files need the same values for some
input. But no file used by any test should have one of the following
extensions: ".php", ".log", ".exp", ".out" or ".diff".
Tests should be named according to the following list:
Class: Name: Example:
Tests for bugs bug<bugid>.phpt bug17123.phpt
Tests for functions <functionname>.phpt dba_open.phpt
General tests for extensions <extname><no>.phpt dba3.phpt
When you use an include file for the SKIPIF section it should be named
"skipif.inc" and an include file used in the FILE section of many tests
should be named "test.inc".
NOTE: All tests should run correctly with error_reporting(E_ALL) and
display_errors=1. This is the default when called from run-test.php.
If you have a good reason for lowering the error reporting, use --INI--
section and comment this in your testcode.
NOTE: If your test intentionally generates a PHP warning message use
$php_errormsg variable, which you can then output. This will result
in a consistent error message output across all platforms and PHP
configurations, preventing your test from failing due inconsistencies
in the error message content.
[How to help us]
----------------
If you find bug in PHP, you can submit bug report AND test script
for us. You don't have to write complete script, just give us test
script with following format. Please test the script and make sure
you write the correct ACTUAL OUTPUT and EXPECTED OUTPUT before you
submit.
<?php
/*
Bug #12345
substr() bug. Do not return expected string.
ACTUAL OUTPUT
XYXA
EXPECTED OUTPUT
ABCD
*/
$str = "XYZABCD";
echo substr($str,3,7);
?>
+123
View File
@@ -0,0 +1,123 @@
PHP Build System V5 Overview
- supports Makefile.ins during transition phase
- not-really-portable Makefile includes have been eliminated
- supports separate build directories without VPATH by using
explicit rules only
- does not waste disk-space/CPU-time for building temporary libraries
=> especially noticeable on slower systems
- slow recursive make replaced with one global Makefile
- eases integration of proper dependencies
- adds PHP_DEFINE(what[, value]) which creates a single include-file
per what. This will allow more fine-grained dependencies.
- abandoning the "one library per directory" concept
- improved integration of the CLI
- several new targets
build-modules: builds and copies dynamic modules into modules/
install-cli: installs the CLI only, so that the install-sapi
target does only what its name says
- finally abandoned automake (still requires aclocal at this time)
- changed some configure-time constructs to run at buildconf-time
- upgraded shtool to 1.5.4
- removed $(moduledir) (use EXTENSION_DIR)
The Reason For a New System
It became more and more apparent that there is a severe need
for addressing the portability concerns and improving the chance
that your build is correct (how often have you been told to
"make clean"? When this is done, you won't need to anymore).
If You Build PHP on a Unix System
You, as a user of PHP, will notice no changes. Of course, the build
system will be faster, look better and work smarter.
If You Are Developing PHP
Extension developers:
Makefile.ins are abandoned. The files which are to be compiled
are specified in the config.m4 now using the following macro:
PHP_NEW_EXTENSION(foo, foo.c bar.c baz.cpp, $ext_shared)
E.g. this enables the extension foo which consists of three source-code
modules, two in C and one in C++. And, depending on the user's wishes,
the extension will even be built as a dynamic module.
The full syntax:
PHP_NEW_EXTENSION(extname, sources [, shared [,sapi_class[, extra-cflags]]])
Please have a look at acinclude.m4 for the gory details and meanings
of the other parameters.
And that's basically it for the extension side.
If you previously built sub-libraries for this module, add
the source-code files here as well. If you need to specify
separate include directories, do it this way:
PHP_NEW_EXTENSION(foo, foo.c mylib/bar.c mylib/gregor.c,,,-I@ext_srcdir@/lib)
E.g. this builds the three files which are located relative to the
extension source directory and compiles all three files with the
special include directive (@ext_srcdir@ is automatically replaced).
Now, you need to tell the build system that you want to build files
in a directory called $ext_builddir/lib:
PHP_ADD_BUILD_DIR($ext_builddir/lib)
Make sure to call this after PHP_NEW_EXTENSION, because $ext_builddir
is only set by the latter.
If you have a complex extension, you might to need add special
Make rules. You can do this by calling PHP_ADD_MAKEFILE_FRAGMENT
in your config.m4 after PHP_NEW_EXTENSION.
This will read a file in the source-dir of your extension called
Makefile.frag. In this file, $(builddir) and $(srcdir) will be
replaced by the values which are correct for your extension
and which are again determined by the PHP_NEW_EXTENSION macro.
Make sure to prefix *all* relative paths correctly with either
$(builddir) or $(srcdir). Because the build system does not
change the working directory anymore, we must use either
absolute paths or relative ones to the top build-directory.
Correct prefixing ensures that.
SAPI developers:
Instead of using PHP_SAPI=foo/PHP_BUILD_XYZ, you will need to type
PHP_SELECT_SAPI(name, type, sources.c)
I.e. specify the source-code files as above and also pass the
information regarding how PHP is supposed to be built (shared
module, program, etc).
For example for APXS:
PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php4.c php_apache.c)
General info
The foundation for the new system is the flexible handling of
sources and their contexts. With the help of macros you
can define special flags for each source-file, where it is
located, in which target context it can work, etc.
Have a look at the well documented macros
PHP_ADD_SOURCES(_X) in acinclude.m4.
+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'
-142
View File
@@ -1,142 +0,0 @@
<div align="center">
<a href="https://php.net">
<img
alt="PHP"
src="https://www.php.net/images/logos/new-php-logo.svg"
width="150">
</a>
</div>
# The PHP Interpreter
PHP is a popular general-purpose scripting language that is especially suited to
web development. Fast, flexible and pragmatic, PHP powers everything from your
blog to the most popular websites in the world. PHP is distributed under the
[PHP License v3.01](LICENSE).
[![Build status](https://travis-ci.org/php/php-src.svg?branch=master)](https://travis-ci.org/php/php-src)
[![Build status](https://ci.appveyor.com/api/projects/status/meyur6fviaxgdwdy/branch/master?svg=true)](https://ci.appveyor.com/project/php/php-src)
[![Build Status](https://dev.azure.com/phpazuredevops/php/_apis/build/status/php.php-src?branchName=master)](https://dev.azure.com/phpazuredevops/php/_build/latest?definitionId=1&branchName=master)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/php.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:php)
## Documentation
The PHP manual is available at [php.net/docs](https://php.net/docs).
## Installation
### Prebuilt packages and binaries
Prebuilt packages and binaries can be used to get up and running fast with PHP.
For Windows, the PHP binaries can be obtained from
[windows.php.net](https://windows.php.net). After extracting the archive the
`*.exe` files are ready to use.
For other systems, see the [installation chapter](https://php.net/install).
### Building PHP source code
*For Windows, see [Build your own PHP on Windows](https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2).*
For a minimal PHP build from Git, you will need autoconf, bison, and re2c. For
a default build, you will additionally need libxml2 and libsqlite3. On Ubuntu,
you can install these using:
sudo apt install -y pkg-config build-essential autoconf bison re2c \
libxml2-dev libsqlite3-dev
Generate configure:
./buildconf
Configure your build. `--enable-debug` is recommended for development, see
`./configure --help` for a full list of options.
# For development
./configure --enable-debug
# For production
./configure
Build PHP. To speed up the build, specify the maximum number of jobs using `-j`:
make -j4
The number of jobs should usually match the number of available cores, which
can be determined using `nproc`.
## Testing PHP source code
PHP ships with an extensive test suite, the command `make test` is used after
successful compilation of the sources to run this test suite.
It is possible to run tests using multiple cores by setting `-jN` in
`TEST_PHP_ARGS`:
make TEST_PHP_ARGS=-j4 test
Shall run `make test` with a maximum of 4 concurrent jobs: Generally the maximum
number of jobs should not exceed the number of cores available.
The [qa.php.net](https://qa.php.net) site provides more detailed info about
testing and quality assurance.
## Installing PHP built from source
After a successful build (and test), PHP may be installed with:
make install
Depending on your permissions and prefix, `make install` may need super user
permissions.
## PHP extensions
Extensions provide additional functionality on top of PHP. PHP consists of many
essential bundled extensions. Additional extensions can be found in the PHP
Extension Community Library - [PECL](https://pecl.php.net).
## Contributing
The PHP source code is located in the Git repository at
[git.php.net](https://git.php.net). Contributions are most welcome by forking
the [GitHub mirror repository](https://github.com/php/php-src) and sending a
pull request.
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
[Request for comments - RFC](https://wiki.php.net/rfc) and
[Voting on PHP features](https://wiki.php.net/rfc/voting) for more information
on the process.
Bug fixes **do not** require an RFC but require a bug tracker ticket. Open a
ticket at [bugs.php.net](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
deprecated warning. get_magic_quotes_gpc can be used to detect the
magic_quotes behavior and therefore should not raise a warning at any time.
The patch removes this warning.
Pull requests are not merged directly on GitHub. All PRs will be pulled and
pushed through [git.php.net](https://git.php.net). See
[Git workflow](https://wiki.php.net/vcs/gitworkflow) for more details.
### Guidelines for contributors
See further documents in the repository for more information on how to
contribute:
- [Contributing to PHP](/CONTRIBUTING.md)
- [PHP coding standards](/CODING_STANDARDS.md)
- [Mailinglist rules](/docs/mailinglist-rules.md)
- [PHP release process](/docs/release-process.md)
## Credits
For the list of people who've put work into PHP, please see the
[PHP credits page](https://php.net/credits.php).
+176
View File
@@ -0,0 +1,176 @@
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?)
* 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/odbc
--------
For PHP 4.3.0:
* update all php_error calls to php_error_docref where valid
* integrate EXPERIMENTAL ODBC update for use in PHP 5.0, use for
testing purposes only.
For PHP 5.0.0
* Activate EXPERIMENTAL ODBC codebase update
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()
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
+6
View File
@@ -0,0 +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 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
+227 -369
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,20 +15,13 @@
#ifdef ZTS
#include <stdio.h>
#include <stdarg.h>
#if ZEND_DEBUG
# include <assert.h>
# define TSRM_ASSERT(c) assert(c)
#else
# define TSRM_ASSERT(c)
#if HAVE_STDARG_H
#include <stdarg.h>
#endif
typedef struct _tsrm_tls_entry tsrm_tls_entry;
/* TSRMLS_CACHE_DEFINE; is already done in Zend, this is being always compiled statically. */
TSRMLS_CACHE_EXTERN();
struct _tsrm_tls_entry {
void **storage;
int count;
@@ -41,8 +34,6 @@ typedef struct {
size_t size;
ts_allocate_ctor ctor;
ts_allocate_dtor dtor;
size_t fast_offset;
int done;
} tsrm_resource_type;
@@ -55,17 +46,12 @@ static ts_rsrc_id id_count;
static tsrm_resource_type *resource_types_table=NULL;
static int resource_types_table_size;
/* Reserved space for fast globals access */
static size_t tsrm_reserved_pos = 0;
static size_t tsrm_reserved_size = 0;
static MUTEX_T tsmm_mutex; /* thread-safe memory manager mutex */
static MUTEX_T tsrm_env_mutex; /* tsrm environ mutex */
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, ...);
@@ -74,7 +60,7 @@ int tsrm_error(int level, const char *format, ...);
static int tsrm_error_level;
static FILE *tsrm_error_file;
#ifdef TSRM_DEBUG
#if TSRM_DEBUG
#define TSRM_ERROR(args) tsrm_error args
#define TSRM_SAFE_RETURN_RSRC(array, offset, range) \
{ \
@@ -102,32 +88,33 @@ static FILE *tsrm_error_file;
}
#endif
#ifdef TSRM_WIN32
static DWORD tls_key;
# define tsrm_tls_set(what) TlsSetValue(tls_key, (void*)(what))
# define tsrm_tls_get() TlsGetValue(tls_key)
#else
#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;
#elif defined(TSRM_WIN32)
static DWORD tls_key;
#elif defined(BETHREADS)
static int32 tls_key;
#endif
TSRM_TLS uint8_t in_main_thread = 0;
TSRM_TLS uint8_t is_thread_shutdown = 0;
/* Startup TSRM (call once for the entire process) */
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, const char *debug_filename)
{/*{{{*/
#ifdef TSRM_WIN32
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename)
{
#if defined(GNUPTH)
pth_init();
#elif defined(PTHREADS)
pthread_key_create( &tls_key, 0 );
#elif defined(TSRM_ST)
st_init();
st_key_create(&tls_key, 0);
#elif defined(TSRM_WIN32)
tls_key = TlsAlloc();
#else
pthread_key_create(&tls_key, 0);
#elif defined(BETHREADS)
tls_key = tls_allocate();
#endif
/* ensure singleton */
in_main_thread = 1;
is_thread_shutdown = 0;
tsrm_error_file = stderr;
tsrm_error_set(debug_level, debug_filename);
tsrm_tls_table_size = expected_threads;
@@ -135,7 +122,6 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
tsrm_tls_table = (tsrm_tls_entry **) calloc(tsrm_tls_table_size, sizeof(tsrm_tls_entry *));
if (!tsrm_tls_table) {
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate TLS table"));
is_thread_shutdown = 1;
return 0;
}
id_count=0;
@@ -144,132 +130,69 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
resource_types_table = (tsrm_resource_type *) calloc(resource_types_table_size, sizeof(tsrm_resource_type));
if (!resource_types_table) {
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate resource types table"));
is_thread_shutdown = 1;
free(tsrm_tls_table);
tsrm_tls_table = NULL;
return 0;
}
tsmm_mutex = tsrm_mutex_alloc();
tsrm_new_thread_begin_handler = tsrm_new_thread_end_handler = NULL;
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Started up TSRM, %d expected threads, %d expected resources", expected_threads, expected_resources));
tsrm_reserved_pos = 0;
tsrm_reserved_size = 0;
tsrm_env_mutex = tsrm_mutex_alloc();
return 1;
}/*}}}*/
}
/* Shutdown TSRM (call once for the entire process) */
TSRM_API void tsrm_shutdown(void)
{/*{{{*/
{
int i;
if (is_thread_shutdown) {
/* shutdown must only occur once */
return;
}
if (tsrm_tls_table) {
for (i=0; i<tsrm_tls_table_size; i++) {
tsrm_tls_entry *p = tsrm_tls_table[i], *next_p;
is_thread_shutdown = 1;
while (p) {
int j;
if (!in_main_thread) {
/* only the main thread may shutdown tsrm */
return;
}
for (i=0; i<tsrm_tls_table_size; i++) {
tsrm_tls_entry *p = tsrm_tls_table[i], *next_p;
while (p) {
int j;
next_p = p->next;
for (j=0; j<p->count; j++) {
if (p->storage[j]) {
if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) {
resource_types_table[j].dtor(p->storage[j]);
}
if (!resource_types_table[j].fast_offset) {
free(p->storage[j]);
}
next_p = p->next;
for (j=0; j<id_count; j++) {
free(p->storage[j]);
}
free(p->storage);
free(p);
p = next_p;
}
free(p->storage);
free(p);
p = next_p;
}
free(tsrm_tls_table);
tsrm_tls_table = NULL;
}
if (resource_types_table) {
free(resource_types_table);
resource_types_table=NULL;
}
free(tsrm_tls_table);
free(resource_types_table);
tsrm_mutex_free(tsmm_mutex);
tsrm_mutex_free(tsrm_env_mutex);
tsmm_mutex = NULL;
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Shutdown TSRM"));
if (tsrm_error_file!=stderr) {
fclose(tsrm_error_file);
}
#ifdef TSRM_WIN32
TlsFree(tls_key);
#else
pthread_setspecific(tls_key, 0);
#if defined(GNUPTH)
pth_kill();
#elif defined(PTHREADS)
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;
tsrm_reserved_pos = 0;
tsrm_reserved_size = 0;
}/*}}}*/
/* {{{ */
/* environ lock api */
TSRM_API void tsrm_env_lock(void) {
tsrm_mutex_lock(tsrm_env_mutex);
}
TSRM_API void tsrm_env_unlock(void) {
tsrm_mutex_unlock(tsrm_env_mutex);
} /* }}} */
/* enlarge the arrays for the already active threads */
static void tsrm_update_active_threads(void)
{/*{{{*/
int i;
for (i=0; i<tsrm_tls_table_size; i++) {
tsrm_tls_entry *p = tsrm_tls_table[i];
while (p) {
if (p->count < id_count) {
int j;
p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count);
for (j=p->count; j<id_count; j++) {
if (resource_types_table[j].fast_offset) {
p->storage[j] = (void *) (((char*)p) + resource_types_table[j].fast_offset);
} else {
p->storage[j] = (void *) malloc(resource_types_table[j].size);
}
if (resource_types_table[j].ctor) {
resource_types_table[j].ctor(p->storage[j]);
}
}
p->count = id_count;
}
p = p->next;
}
}
}/*}}}*/
/* allocates a new thread-safe-resource id */
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
{/*{{{*/
{
int i;
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", size));
tsrm_mutex_lock(tsmm_mutex);
@@ -280,148 +203,110 @@ 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)].fast_offset = 0;
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0;
tsrm_update_active_threads();
tsrm_mutex_unlock(tsmm_mutex);
/* enlarge the arrays for the already active threads */
for (i=0; i<tsrm_tls_table_size; i++) {
tsrm_tls_entry *p = tsrm_tls_table[i];
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id));
return *rsrc_id;
}/*}}}*/
while (p) {
if (p->count < id_count) {
int j;
/* Reserve space for fast thread-safe-resources */
TSRM_API void tsrm_reserve(size_t size)
{/*{{{*/
tsrm_reserved_pos = 0;
tsrm_reserved_size = TSRM_ALIGNED_SIZE(size);
}/*}}}*/
/* allocates a new fast thread-safe-resource id */
TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
{/*{{{*/
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new fast resource id, %d bytes", size));
tsrm_mutex_lock(tsmm_mutex);
/* obtain a resource id */
*rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++);
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtained resource id %d", *rsrc_id));
size = TSRM_ALIGNED_SIZE(size);
if (tsrm_reserved_size - tsrm_reserved_pos < size) {
tsrm_mutex_unlock(tsmm_mutex);
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate space for fast resource"));
*rsrc_id = 0;
*offset = 0;
return 0;
}
*offset = TSRM_ALIGNED_SIZE(sizeof(tsrm_tls_entry)) + tsrm_reserved_pos;
tsrm_reserved_pos += size;
/* 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) {
tsrm_mutex_unlock(tsmm_mutex);
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));
*rsrc_id = 0;
return 0;
p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count);
for (j=p->count; j<id_count; j++) {
p->storage[j] = (void *) malloc(resource_types_table[j].size);
if (resource_types_table[j].ctor) {
resource_types_table[j].ctor(p->storage[j], &p->storage);
}
}
p->count = id_count;
}
p = p->next;
}
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)].fast_offset = *offset;
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0;
tsrm_update_active_threads();
tsrm_mutex_unlock(tsmm_mutex);
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id));
return *rsrc_id;
}/*}}}*/
}
static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_T thread_id)
{/*{{{*/
{
int i;
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Creating data structures for thread %x", thread_id));
(*thread_resources_ptr) = (tsrm_tls_entry *) malloc(TSRM_ALIGNED_SIZE(sizeof(tsrm_tls_entry)) + tsrm_reserved_size);
(*thread_resources_ptr)->storage = NULL;
if (id_count > 0) {
(*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count);
}
(*thread_resources_ptr) = (tsrm_tls_entry *) malloc(sizeof(tsrm_tls_entry));
(*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count);
(*thread_resources_ptr)->count = id_count;
(*thread_resources_ptr)->thread_id = thread_id;
(*thread_resources_ptr)->next = NULL;
#if defined(PTHREADS)
/* Set thread local storage to this new thread resources structure */
tsrm_tls_set(*thread_resources_ptr);
TSRMLS_CACHE = *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);
#elif defined(BETHREADS)
tls_set(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 {
if (resource_types_table[i].fast_offset) {
(*thread_resources_ptr)->storage[i] = (void *) (((char*)(*thread_resources_ptr)) + resource_types_table[i].fast_offset);
} 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);
#elif defined(BETHREADS)
thread_resources = (tsrm_tls_entry*)tls_get(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.
@@ -467,20 +352,18 @@ 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 all resources allocated for the current thread */
void ts_free_thread(void)
{/*{{{*/
{
tsrm_tls_entry *thread_resources;
int i;
THREAD_T thread_id = tsrm_thread_id();
int hash_value;
tsrm_tls_entry *last=NULL;
TSRM_ASSERT(!in_main_thread);
tsrm_mutex_lock(tsmm_mutex);
hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
thread_resources = tsrm_tls_table[hash_value];
@@ -489,13 +372,11 @@ 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++) {
if (!resource_types_table[i].fast_offset) {
free(thread_resources->storage[i]);
}
free(thread_resources->storage[i]);
}
free(thread_resources->storage);
if (last) {
@@ -503,7 +384,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;
}
@@ -513,42 +398,15 @@ void ts_free_thread(void)
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]);
}
if (!resource_types_table[j].fast_offset) {
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));
}/*}}}*/
/*
@@ -557,129 +415,176 @@ 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();
#else
#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();
#elif defined(BETHREADS)
return find_thread(NULL);
#endif
}/*}}}*/
}
/* Allocate a mutex */
TSRM_API MUTEX_T tsrm_mutex_alloc(void)
{/*{{{*/
{
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));
InitializeCriticalSection(mutexp);
#else
#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();
#elif defined(BETHREADS)
mutexp = (beos_ben*)malloc(sizeof(beos_ben));
mutexp->ben = 0;
mutexp->sem = create_sem(1, "PHP sempahore");
#endif
#ifdef THR_DEBUG
printf("Mutex created thread: %d\n",mythreadid());
#endif
return( mutexp );
}/*}}}*/
}
/* Free a mutex */
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
{/*{{{*/
{
if (mutexp) {
#ifdef TSRM_WIN32
DeleteCriticalSection(mutexp);
#elif defined(NETWARE)
NXMutexFree(mutexp);
#elif defined(GNUPTH)
free(mutexp);
#else
#elif defined(PTHREADS)
pthread_mutex_destroy(mutexp);
free(mutexp);
#elif defined(NSAPI)
crit_terminate(mutexp);
#elif defined(PI3WEB)
PISync_delete(mutexp);
#elif defined(TSRM_ST)
st_mutex_destroy(mutexp);
#elif defined(BETHREADS)
delete_sem(mutexp->sem);
free(mutexp);
#endif
}
#ifdef THR_DEBUG
printf("Mutex freed thread: %d\n",mythreadid());
#endif
}/*}}}*/
}
/*
Lock a mutex.
A return value of 0 indicates success
*/
/* 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;
#else
return 1;
#elif defined(NETWARE)
return NXLock(mutexp);
#elif defined(GNUPTH)
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);
#elif defined(BETHREADS)
if (atomic_add(&mutexp->ben, 1) != 0)
return acquire_sem(mutexp->sem);
return 0;
#endif
}/*}}}*/
}
/*
Unlock a mutex.
A return value of 0 indicates success
*/
/* 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;
#else
return 1;
#elif defined(NETWARE)
return NXUnlock(mutexp);
#elif defined(GNUPTH)
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);
#elif defined(BETHREADS)
if (atomic_add(&mutexp->ben, -1) != 1)
return release_sem(mutexp->sem);
return 0;
#endif
}/*}}}*/
/*
Changes the signal mask of the calling thread
*/
#ifdef HAVE_SIGPROCMASK
TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset)
{/*{{{*/
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Changed sigmask in thread: %ld", tsrm_thread_id()));
return pthread_sigmask(how, set, oldset);
}/*}}}*/
#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
*/
#ifdef TSRM_DEBUG
#if TSRM_DEBUG
int tsrm_error(int level, const char *format, ...)
{/*{{{*/
{
if (level<=tsrm_error_level) {
va_list args;
int size;
@@ -694,15 +599,15 @@ int tsrm_error(int level, const char *format, ...)
} else {
return 0;
}
}/*}}}*/
}
#endif
void tsrm_error_set(int level, const char *debug_filename)
{/*{{{*/
void tsrm_error_set(int level, char *debug_filename)
{
tsrm_error_level = level;
#ifdef TSRM_DEBUG
#if TSRM_DEBUG
if (tsrm_error_file!=stderr) { /* close files opened earlier */
fclose(tsrm_error_file);
}
@@ -716,53 +621,6 @@ void tsrm_error_set(int level, const char *debug_filename)
tsrm_error_file = stderr;
}
#endif
}/*}}}*/
TSRM_API void *tsrm_get_ls_cache(void)
{/*{{{*/
return tsrm_tls_get();
}/*}}}*/
/* Returns offset of tsrm_ls_cache slot from Thread Control Block address */
TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void)
{/*{{{*/
#if defined(__APPLE__) && defined(__x86_64__)
// TODO: Implement support for fast JIT ZTS code ???
return 0;
#elif defined(__x86_64__) && defined(__GNUC__) && !defined(__FreeBSD__)
size_t ret;
asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0"
: "=r" (ret));
return ret;
#elif defined(__i386__) && defined(__GNUC__) && !defined(__FreeBSD__)
size_t ret;
asm ("leal _tsrm_ls_cache@ntpoff,%0"
: "=r" (ret));
return ret;
#else
return 0;
#endif
}/*}}}*/
TSRM_API uint8_t tsrm_is_main_thread(void)
{/*{{{*/
return in_main_thread;
}/*}}}*/
TSRM_API uint8_t tsrm_is_shutdown(void)
{/*{{{*/
return is_thread_shutdown;
}/*}}}*/
TSRM_API const char *tsrm_api_name(void)
{/*{{{*/
#ifdef TSRM_WIN32
return "Windows Threads";
#else
return "POSIX Threads";
#endif
}/*}}}*/
}
#endif /* ZTS */
+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
+63 -96
View File
@@ -2,58 +2,54 @@
+----------------------------------------------------------------------+
| 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 "Zend/zend_config.w32.h"
#else
# include "main/php_config.h"
/* #ifndef WIN32 */
#if !defined(WIN32) && !defined(NETWARE)
# include "tsrm_config.h"
#endif
#include "main/php_stdint.h"
#ifdef WIN32
# define TSRM_WIN32
# include "tsrm_config.w32.h"
#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
#else
# include <windows.h>
#elif defined(NETWARE)
# include <nks/thread.h>
# include <nks/synch.h>
#elif defined(GNUPTH)
# include <pth.h>
#elif defined(PTHREADS)
# include <pthread.h>
#endif
#if SIZEOF_SIZE_T == 4
# define TSRM_ALIGNED_SIZE(size) \
(((size) + INT32_C(15)) & ~INT32_C(15))
#else
# define TSRM_ALIGNED_SIZE(size) \
(((size) + INT64_C(15)) & ~INT64_C(15))
#elif defined(TSRM_ST)
# include <st.h>
#elif defined(BETHREADS)
#include <kernel/OS.h>
#include <TLS.h>
#endif
typedef int ts_rsrc_id;
@@ -62,15 +58,35 @@ typedef int ts_rsrc_id;
#ifdef TSRM_WIN32
# define THREAD_T DWORD
# define MUTEX_T CRITICAL_SECTION *
#else
#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
#elif defined(BETHREADS)
# define THREAD_T thread_id
typedef struct {
sem_id sem;
int32 ben;
} beos_ben;
# define MUTEX_T beos_ben *
#endif
#include <signal.h>
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
@@ -79,20 +95,12 @@ extern "C" {
#endif
/* startup/shutdown */
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, const char *debug_filename);
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename);
TSRM_API void tsrm_shutdown(void);
/* environ lock API */
TSRM_API void tsrm_env_lock(void);
TSRM_API void tsrm_env_unlock(void);
/* allocates a new thread-safe-resource id */
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);
/* Fast resource in reserved (pre-allocated) space */
TSRM_API void tsrm_reserve(size_t size);
TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);
/* fetches the requested resource for the current thread */
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id);
#define ts_resource(id) ts_resource_ex(id, NULL)
@@ -109,13 +117,12 @@ 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, ...);
TSRM_API void tsrm_error_set(int level, const char *debug_filename);
TSRM_API void tsrm_error_set(int level, char *debug_filename);
/* utility functions */
TSRM_API THREAD_T tsrm_thread_id(void);
@@ -123,54 +130,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);
TSRM_API void *tsrm_get_ls_cache(void);
TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void);
TSRM_API uint8_t tsrm_is_main_thread(void);
TSRM_API uint8_t tsrm_is_shutdown(void);
TSRM_API const char *tsrm_api_name(void);
#ifdef TSRM_WIN32
# define TSRM_TLS __declspec(thread)
#else
# define TSRM_TLS __thread
#endif
#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
#if !__has_attribute(tls_model) || defined(__FreeBSD__)
# define TSRM_TLS_MODEL_ATTR
#elif __PIC__
# define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("initial-exec")))
#else
# define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("local-exec")))
#endif
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
#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_FAST(offset, type, element) (TSRMG_FAST_BULK(offset, type)->element)
#define TSRMG_FAST_BULK(offset, type) ((type) (((char*) tsrm_get_ls_cache())+(offset)))
#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 TSRMG_FAST_STATIC(offset, type, element) (TSRMG_FAST_BULK_STATIC(offset, type)->element)
#define TSRMG_FAST_BULK_STATIC(offset, type) ((type) (((char*) TSRMLS_CACHE)+(offset)))
#define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR;
#define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR = NULL;
#define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache()
#define TSRMLS_CACHE _tsrm_ls_cache
#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
}
@@ -178,16 +150,11 @@ TSRM_API const char *tsrm_api_name(void);
#else /* non ZTS */
#define tsrm_env_lock()
#define tsrm_env_unlock()
#define TSRMG_STATIC(id, type, element)
#define TSRMLS_CACHE_EXTERN()
#define TSRMLS_CACHE_DEFINE()
#define TSRMLS_CACHE_UPDATE()
#define TSRMLS_CACHE
#define TSRM_TLS
#define TSRMLS_FETCH()
#define TSRMLS_D void
#define TSRMLS_DC
#define TSRMLS_C
#define TSRMLS_CC
#endif /* ZTS */
+1
View File
@@ -0,0 +1 @@
#undef PTHREADS
+5
View File
@@ -0,0 +1,5 @@
AC_DEFUN(AM_SET_LIBTOOL_VARIABLE,[
LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
])
+43
View File
@@ -0,0 +1,43 @@
# Makefile to generate build tools
#
# Standard usage:
# make -f build.mk
#
# Written by Sascha Schumann
#
# $Id$
LT_TARGETS = ltmain.sh ltconfig
config_h_in = tsrm_config.h.in
makefile_am_files = Makefile.am
makefile_in_files = $(makefile_am_files:.am=.in)
makefile_files = $(makefile_am_files:e.am=e)
targets = $(makefile_in_files) $(LT_TARGETS) configure $(config_h_in)
all: $(targets)
clean:
rm -f $(targets)
$(LT_TARGETS):
rm -f $(LT_TARGETS)
libtoolize --automake $(AMFLAGS) -f
$(makefile_in_files): $(makefile_am_files)
automake -a -i $(AMFLAGS) $(makefile_files)
aclocal.m4: configure.in acinclude.m4
aclocal
$(config_h_in): configure.in 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.in
autoconf
Executable
+33
View File
@@ -0,0 +1,33 @@
#!/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
-4
View File
@@ -1,4 +0,0 @@
// vim:ft=javascript
ADD_SOURCES("TSRM", "TSRM.c tsrm_win32.c");
ADD_FLAG("CFLAGS_BD_TSRM", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+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)
+44
View File
@@ -0,0 +1,44 @@
#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 */
+64 -39
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
@@ -28,9 +28,9 @@ dnl OF THE POSSIBILITY OF SUCH DAMAGE.
dnl
dnl PTHREADS_FLAGS
dnl
dnl Set some magic defines to achieve POSIX threads conformance.
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
@@ -52,20 +52,21 @@ AC_DEFUN([PTHREADS_FLAGS],[
PTHREAD_FLAGS=-D_REENTRANT;;
*sco*)
PTHREAD_FLAGS=-D_REENTRANT;;
dnl Solves sigwait() problem, creates problems with u_long etc.
dnl PTHREAD_FLAGS="-D_REENTRANT -D_XOPEN_SOURCE=500 -D_POSIX_C_SOURCE=199506 -D_XOPEN_SOURCE_EXTENDED=1";;
esac
if test -n "$PTHREAD_FLAGS"; then
CPPFLAGS="$CPPFLAGS $PTHREAD_FLAGS"
fi
])
])dnl
dnl
dnl PTHREADS_CHECK_COMPILE
dnl
dnl Check whether the current setup can use POSIX threads calls.
dnl 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>
@@ -79,17 +80,15 @@ 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
]
) ] )
pthreads_working=no
], pthreads_working=no ) ] )dnl
dnl
dnl PTHREADS_CHECK
dnl PTHREADS_CHECK()
dnl
dnl Try to find a way to enable POSIX threads.
dnl Try to find a way to enable POSIX threads
dnl
dnl Magic flags
dnl -kthread gcc (FreeBSD)
@@ -97,36 +96,49 @@ 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_CACHE_CHECK(for pthreads_cflags,ac_cv_pthreads_cflags,[
ac_cv_pthreads_cflags=
if test "$pthreads_working" != "yes"; then
for flag in -kthread -pthread -pthreads -mthreads -Kthread -threads -mt -qthreaded; do
ac_save=$CFLAGS
CFLAGS="$CFLAGS $flag"
PTHREADS_CHECK_COMPILE
CFLAGS=$ac_save
if test "$pthreads_checked" = "yes"; then
ac_cv_pthreads_cflags=$flag
break
fi
done
AC_DEFUN(PTHREADS_CHECK,[
if test "$beos_threads" = "1"; then
pthreads_working="yes"
ac_cv_pthreads_cflags=""
else
save_CFLAGS=$CFLAGS
save_LIBS=$LIBS
PTHREADS_ASSIGN_VARS
PTHREADS_CHECK_COMPILE
LIBS=$save_LIBS
CFLAGS=$save_CFLAGS
AC_CACHE_CHECK(for pthreads_cflags,ac_cv_pthreads_cflags,[
ac_cv_pthreads_cflags=
if test "$pthreads_working" != "yes"; then
for flag in -kthread -pthread -pthreads -mthreads -Kthread -threads -mt -qthreaded; do
ac_save=$CFLAGS
CFLAGS="$CFLAGS $flag"
PTHREADS_CHECK_COMPILE
CFLAGS=$ac_save
if test "$pthreads_working" = "yes"; then
ac_cv_pthreads_cflags=$flag
break
fi
done
fi
fi
])
AC_CACHE_CHECK(for pthreads_lib, ac_cv_pthreads_lib,[
ac_cv_pthreads_lib=
if test "$pthreads_working" != "yes"; then
for lib in pthread pthreads c_r; do
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
@@ -134,7 +146,20 @@ 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"
if test "$pthreads_working" = "yes"; then
threads_result="POSIX-Threads found"
else
threads_result="POSIX-Threads not found"
fi
])
])dnl
dnl
dnl
AC_DEFUN(PTHREADS_ASSIGN_VARS,[
if test -n "$ac_cv_pthreads_lib"; then
LIBS="$LIBS -l$ac_cv_pthreads_lib"
fi
if test -n "$ac_cv_pthreads_cflags"; then
CFLAGS="$CFLAGS $ac_cv_pthreads_cflags"
fi
])dnl
+122 -11
View File
@@ -1,17 +1,128 @@
dnl This file contains TSRM specific autoconf macros.
dnl
dnl TSRM_CHECK_PTHREADS
dnl
AC_DEFUN([TSRM_CHECK_PTHREADS],[
PTHREADS_CHECK
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
])
if test "$pthreads_working" != "yes"; then
AC_MSG_ERROR(Your system seems to lack POSIX threads.)
AC_DEFUN(TSRM_BASIC_CHECKS,[
AC_REQUIRE([AC_PROG_CC])dnl
dnl AC_REQUIRE([AM_PROG_CC_STDC])dnl
AC_REQUIRE([AC_PROG_CC_C_O])dnl
AC_REQUIRE([AC_PROG_RANLIB])dnl
AC_CHECK_HEADERS(stdarg.h)
])
AC_DEFUN(TSRM_CHECK_PTH,[
AC_MSG_CHECKING(for GNU Pth)
PTH_PREFIX="`$1 --prefix`"
if test -z "$PTH_PREFIX"; then
AC_MSG_RESULT(Please check your Pth installation)
fi
AC_DEFINE(PTHREADS, 1, Whether to use Pthreads)
CPPFLAGS="$CPPFLAGS `$1 --cflags`"
LDFLAGS="$LDFLAGS `$1 --ldflags`"
LIBS="$LIBS `$1 --libs`"
AC_DEFINE(GNUPTH, 1, [Whether you use GNU Pth])
AC_MSG_RESULT(yes - installed in $PTH_PREFIX)
])
AC_DEFUN(TSRM_CHECK_ST,[
if test -r "$1/include/st.h"; then
CPPFLAGS="$CPPFLAGS -I$1/include"
LDFLAGS="$LDFLAGS -L$1/lib"
elif test -r "$1/st.h"; then
CPPFLAGS="$CPPFLAGS -I$1"
LDFLAGS="$LDFLAGS -L$1"
fi
AC_CHECK_HEADERS(st.h,[],[
AC_MSG_ERROR([Sorry[,] I was unable to locate the State Threads header file. Please specify the prefix using --with-tsrm-st=/prefix])
])
LIBS="$LIBS -lst"
AC_MSG_CHECKING(for SGI's State Threads)
AC_MSG_RESULT(yes)
AC_DEFINE(TSRM_ST, 1, [ ])
])
sinclude(threads.m4)
sinclude(TSRM/threads.m4)
AC_DEFUN(TSRM_CHECK_PTHREADS,[
PTHREADS_CHECK
if test "$beos_threads" = "1"; then
AC_DEFINE(BETHREADS, 1, Whether to use native BeOS threads)
else
if test "$pthreads_working" != "yes"; then
AC_MSG_ERROR(Your system seems to lack POSIX threads.)
fi
AC_DEFINE(PTHREADS, 1, Whether to use Pthreads)
AC_MSG_CHECKING(for POSIX threads)
AC_MSG_RESULT(yes)
fi
])
AC_DEFUN(TSRM_THREADS_CHECKS,[
dnl For the thread implementations, we always use --with-*
dnl to maintain consistency
AC_ARG_WITH(tsrm-pth,
[ --with-tsrm-pth[=pth-config] Use GNU Pth.],[
TSRM_PTH=$withval
],[
TSRM_PTH=no
])
AC_ARG_WITH(tsrm-st,
[ --with-tsrm-st],[
TSRM_ST=$withval
],[
TSRM_ST=no
])
AC_ARG_WITH(tsrm-pthreads,
[ --with-tsrm-pthreads Use POSIX threads (default)],[
TSRM_PTHREADS=$withval
],[
TSRM_PTHREADS=yes
])
test "$TSRM_PTH" = "yes" && TSRM_PTH=pth-config
if test "$TSRM_PTH" != "no"; then
TSRM_CHECK_PTH($TSRM_PTH)
elif test "$TSRM_ST" != "no"; then
TSRM_CHECK_ST($TSRM_ST)
elif test "$TSRM_PTHREADS" != "no"; then
TSRM_CHECK_PTHREADS
fi
AC_MSG_CHECKING(for POSIX threads)
AC_MSG_RESULT(yes)
])
+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
+19
View File
@@ -0,0 +1,19 @@
#ifndef TSRM_CONFIG_W32_H
#define TSRM_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
#endif
+58
View File
@@ -0,0 +1,58 @@
#ifndef TSRM_CONFIG_COMMON_H
#define TSRM_CONFIG_COMMON_H
#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 <sys/param.h>
#endif
#if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
# include <alloca.h>
#endif
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# ifndef HAVE_ALLOCA_H
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
# endif
# endif
# endif
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#ifndef MAXPATHLEN
# ifdef PATH_MAX
# define MAXPATHLEN PATH_MAX
# else
# define MAXPATHLEN 256
# endif
#endif
#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2))
# define tsrm_do_alloca(p) alloca(p)
# define tsrm_free_alloca(p)
#else
# define tsrm_do_alloca(p) malloc(p)
# define tsrm_free_alloca(p) free(p)
#endif
#endif /* TSRM_CONFIG_COMMON_H */
+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
+63
View File
@@ -0,0 +1,63 @@
#include <stdio.h>
#include "tsrm_config_common.h"
#include "tsrm_strtok_r.h"
static inline int in_character_class(char ch, const char *delim)
{
while (*delim) {
if (*delim == ch) {
return 1;
}
delim++;
}
return 0;
}
char *tsrm_strtok_r(char *s, const char *delim, char **last)
{
char *token;
if (s == NULL) {
s = *last;
}
while (*s && in_character_class(*s, delim)) {
s++;
}
if (!*s) {
return NULL;
}
token = s;
while (*s && !in_character_class(*s, delim)) {
s++;
}
if (!*s) {
*last = s;
} else {
*s = '\0';
*last = s + 1;
}
return token;
}
#if 0
main()
{
char foo[] = "/foo/bar//\\barbara";
char *last;
char *token;
token = tsrm_strtok_r(foo, "/\\", &last);
while (token) {
printf ("Token = '%s'\n", token);
token = tsrm_strtok_r(NULL, "/\\", &last);
}
return 0;
}
#endif
+6
View File
@@ -0,0 +1,6 @@
#ifndef TSRM_STRTOK_R
#define TSRM_STRTOK_R
char *tsrm_strtok_r(char *s, const char *delim, char **last);
#endif
+847
View File
@@ -0,0 +1,847 @@
/*
+----------------------------------------------------------------------+
| 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
#ifndef HAVE_REALPATH
#define realpath(x,y) strcpy(y,x)
#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 use_realpath)
{
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(NETWARE)
if (IS_ABSOLUTE_PATH(path, path_length)) {
if (use_realpath && 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 (use_realpath && 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_amount = COPY_WHEN_ABSOLUTE(path_copy);
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);
}
if (state->cwd_length == COPY_WHEN_ABSOLUTE(state->cwd)) {
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)?-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;
}
if (length == COPY_WHEN_ABSOLUTE(path) && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */
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, 1);
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, 1);
*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, 1);
f = fopen(new_state.cwd, mode);
CWD_STATE_FREE(&new_state);
return f;
}
#if !defined(TSRM_WIN32)
CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC)
{
cwd_state new_state;
int ret;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, pathname, NULL, 1);
ret = access(new_state.cwd, mode);
CWD_STATE_FREE(&new_state);
return ret;
}
#endif
#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, 0);
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, 1);
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, 0);
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, 1);
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, 1);
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, 0);
oldname = old_state.cwd;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, newname, NULL, 0);
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, 1);
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, 1);
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, 0);
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, 0);
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, 1);
#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, 0);
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, 1);
retval = opendir(new_state.cwd);
CWD_STATE_FREE(&new_state);
return retval;
}
#ifdef TSRM_WIN32
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
{
return popen_ex(command, type, CWDG(cwd).cwd, NULL);
}
#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:
*/
+252
View File
@@ -0,0 +1,252 @@
/*
+----------------------------------------------------------------------+
| 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))))
/* COPY_WHEN_ABSOLUTE also takes path as argument because netware needs it
* to account for volume name that is unique to NetWare absolute paths
*/
#define COPY_WHEN_ABSOLUTE(path) 2
#define IS_ABSOLUTE_PATH(path, len) \
(len >= 2 && ((isalpha(path[0]) && path[1] == ':') || (IS_SLASH(path[0]) && IS_SLASH(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(path) 0
#endif
#ifndef IS_ABSOLUTE_PATH
#define IS_ABSOLUTE_PATH(path, len) \
(IS_SLASH(path[0]))
#endif
#ifdef TSRM_EXPORTS
#define CWD_EXPORTS
#endif
#ifdef TSRM_WIN32
# ifdef CWD_EXPORTS
# define CWD_API __declspec(dllexport)
# else
# define CWD_API __declspec(dllimport)
# endif
#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 !defined(TSRM_WIN32)
CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC);
#endif
#if HAVE_UTIME
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC);
#endif
CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC);
#if !defined(TSRM_WIN32) && !defined(NETWARE)
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_DC);
#endif
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath);
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_lstat(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)
#define VCWD_ACCESS(pathname, mode) virtual_access(pathname, mode TSRMLS_CC)
#if HAVE_UTIME
#define VCWD_UTIME(path, time) virtual_utime(path, time TSRMLS_CC)
#endif
#define VCWD_CHMOD(path, mode) virtual_chmod(path, mode TSRMLS_CC)
#if !defined(TSRM_WIN32) && !defined(NETWARE)
#define VCWD_CHOWN(path, owner, group) virtual_chown(path, owner, group 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)
#define VCWD_ACCESS(pathname, mode) access(pathname, mode)
#ifdef HAVE_REALPATH
#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 */
+96 -559
View File
@@ -1,11 +1,13 @@
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
| PHP Version 4 |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| 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 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. |
@@ -14,22 +16,18 @@
+----------------------------------------------------------------------+
*/
/* $Id$ */
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <process.h>
#include <time.h>
#include <errno.h>
#define TSRM_INCLUDE_FULL_WINDOWS_HEADERS
#include "SAPI.h"
#include "TSRM.h"
#ifdef TSRM_WIN32
#include <Sddl.h>
#include "tsrm_win32.h"
#include "zend_virtual_cwd.h"
#include "win32/ioutil.h"
#ifdef ZTS
static ts_rsrc_id win32_globals_id;
@@ -37,30 +35,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) {
@@ -78,329 +63,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
}/*}}}*/
}
const 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;
@@ -415,110 +127,61 @@ 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, const char *env)
{/*{{{*/
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;
char *ptype = (char *)type;
HANDLE thread_token = NULL;
HANDLE token_user = NULL;
BOOL asuser = TRUE;
if (!type) {
return NULL;
}
type_len = (int)strlen(type);
if (type_len < 1 || type_len > 2) {
return NULL;
}
if (ptype[0] != 'r' && ptype[0] != 'w') {
return NULL;
}
if (type_len > 1 && (ptype[1] != 'b' && ptype[1] != 't')) {
return NULL;
}
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /s /c ")+2);
if (!cmd) {
return NULL;
}
sprintf(cmd, "%s /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);
@@ -530,56 +193,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, env, cwd, &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);
}
@@ -587,19 +215,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);
@@ -607,68 +236,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 = NULL, info_handle = NULL;
HANDLE shm_handle, info_handle;
BOOL created = FALSE;
if (key != IPC_PRIVATE) {
snprintf(shm_segment, sizeof(shm_segment), "TSRM_SHM_SEGMENT:%d", key);
snprintf(shm_info, sizeof(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 (size < 0) {
return -1;
}
if (!shm_handle && !info_handle) {
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, key == IPC_PRIVATE ? NULL : shm_segment);
info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), key == IPC_PRIVATE ? NULL : shm_info);
created = TRUE;
}
if (!shm_handle || !info_handle) {
if (shm_handle) {
CloseHandle(shm_handle);
}
if (info_handle) {
CloseHandle(info_handle);
}
sprintf(shm_segment, "TSRM_SHM_SEGMENT:%d", key);
sprintf(shm_info, "TSRM_SHM_DESCRIPTOR:%d", key);
shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
if ((!shm_handle && !info_handle)) {
if (flags & IPC_EXCL) {
return -1;
}
} else {
if (flags & IPC_EXCL) {
if (shm_handle) {
CloseHandle(shm_handle);
}
if (info_handle) {
CloseHandle(info_handle);
}
if (flags & IPC_CREAT) {
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shm_segment);
info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info);
created = TRUE;
}
if ((!shm_handle || !info_handle)) {
return -1;
}
}
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);
@@ -682,45 +288,36 @@ 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);
int ret;
if (!shm->segment) {
return -1;
@@ -730,16 +327,10 @@ TSRM_API int shmdt(const void *shmaddr)
shm->descriptor->shm_lpid = getpid();
shm->descriptor->shm_nattch--;
ret = UnmapViewOfFile(shm->addr) ? 0 : -1;
if (!ret && shm->descriptor->shm_nattch <= 0) {
ret = UnmapViewOfFile(shm->descriptor) ? 0 : -1;
shm->descriptor = NULL;
}
return ret;
}/*}}}*/
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) {
@@ -767,59 +358,5 @@ TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf)
default:
return -1;
}
}/*}}}*/
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
+15 -18
View File
@@ -1,11 +1,13 @@
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
| PHP Version 4 |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| 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 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. |
@@ -14,16 +16,16 @@
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef TSRM_WIN32_H
#define TSRM_WIN32_H
#include "TSRM.h"
#include <windows.h>
#include <sys/utime.h>
#include "win32/ipc.h"
struct ipc_perm {
key_t key;
int key;
unsigned short uid;
unsigned short gid;
unsigned short cuid;
@@ -34,7 +36,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;
@@ -61,13 +63,10 @@ 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
@@ -89,19 +88,17 @@ TSRMLS_CACHE_EXTERN()
#define SHM_RND FILE_MAP_WRITE
#define SHM_REMAP FILE_MAP_COPY
const 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, const char *env);
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
#endif
-1159
View File
File diff suppressed because it is too large. Load diff
-461
View File
@@ -1,461 +0,0 @@
PHP 8.0 INTERNALS UPGRADE NOTES
1. Internal API changes
a. Object Handlers API
b. ZEND_OVERLOADED_FUNCTION and corresponding call_method() object handler
c. TSRM changes
d. get() and set() object handlers
e. zend_parse_parameters 'L' specifier
f. Arginfo argument types
g. zend_free_op type and should_free argument of zend_get_zval_ptr()
h. zend_value_error()
i. get_closure() object handler
j. compare_objects() and compare() object handlers
k. The 'I' length modifier
l. Some VM instructions switched to IS_TMP_VAR result instead of IS_VAR
m. All internal functions must have arginfo
n. zend_hash_sort compare function and zend_hash_sort signature change
o. cast_object() object handler is now required
p. ARG_COUNT() macro removed
q. GC_COLLECTABLE flag
r. Cannot implement Traversable only
s. zend_fcall_info no_separation flag removed
t. Signature changes
u. Error Notification callbacks to replace zend_error_cb overwrite use-cases
v. Removed Zend APIs
w. Renamed Zend APIs
x. ZEND_EXT_NOP no longer emitted
2. Build system changes
a. Abstract
b. Unix build system changes
c. Windows build system changes
3. Module changes
========================
1. Internal API changes
========================
a. The Object Handlers API was changed to receive zend_object* instead of
zval* and zend_string* instead of zval* for property names. See also
section t for other similar changes.
b. ZEND_OVERLOADED_FUNCTION and corresponding call_method() object handler
were removed. ZEND_INTERNAL_FUNCTION with ZEND_ACC_CALL_VIA_HANDLER and
defined "handler" callback should be used instead. This "handler" callback
should also take care about function cleanup. See ext/zend_test/test.c
for example.
c. The following things have been removed from TSRM:
- TSRMLS_DC
- TSRMLS_D
- TSRMLS_CC
- TSRMLS_C
- TSRMLS_FETCH
- TSRMLS_FETCH_FROM_CTX
- TSRMLS_SET_CTX
- tsrm_new_interpreter_context
- tsrm_set_interpreter_context
- tsrm_free_interpreter_context
- support for GNUPTH, SGI ST, and BETHREADS
d. The get() and set() object handlers have been removed. The get() handler
can generally be replaced with cast_object(). Some uses of set() may be
replaced by do_operation(). If set() was used to overload direct
assignments using "=", then this is no longer supported and the
functionality should be provided in some other way (for example, as
modification of an object property).
e. The zend_parse_parameters 'L' specifier and the Z_PARAM_STRICT_LONG()
family of macros have been removed. Use 'l' and Z_PARAM_LONG() instead,
which, despite the confusing name, actually have stricter input validation.
f. Arginfo argument types for internal functions are no longer checked.
Instead type checks should be performed using the zend_parse_parameters()
or ZEND_PARSE_PARAMETERS_*() APIs.
g. The zend_free_op type and the "should_free" and "type" arguments of
zend_get_zval_ptr() were removed. It's possible to get the old
"should_free" value using the following code:
zval *ret = zend_get_zval_ptr(
opline, opline->op1_type, &opline->op1, execute_data);
zval *should_free = (op_type & (IS_TMP_VAR|IS_VAR)) ? ret : NULL;
h. Added the zend_value_error() function, which is intended to be used
to raise ValueError when inappropriate argument values are passed
to functions.
i. get_closure() object handlers now accept an additional zend_bool parameter
`check_only`. If it is true, the handler is called to check whether the
object is callable; in this case the handler should not throw an exception.
j. compare_objects() handler was removed. Extensions should use compare() object
handler instead and check if both arguments are objects and have the same
compare handler, using ZEND_COMPARE_OBJECTS_FALLBACK() macro.
k. The 'I' length modifier, used to denote 32 and 64bit integer from the custom
snprintf and spprintf implementations has been removed.
Use the ZEND_LONG_FMT, ZEND_ULONG_FMT and ZEND_XLONG_FMT macros defined in
php-src/Zend/zend_long.h
The 'v' format from the custom snprintf and spprintf implementations has
been removed. Use the standard 's' format instead.
l. Some VM instructions switched to IS_TMP_VAR result instead of IS_VAR.
Actually, all assignments (ZEND_ASSIGN, ZEND_ASSIGN_DIM, ZEND_ASSIGN_OBJ,
ZEND_ASSIGN_STATIC_PROP), all compound assignments (ZEND_ASSIGN_OP,
ZEND_ASSIGN_DIM_OP, ZEND_ASSIGN_OBJ_OP, ZEND_ASSIGN_STATIC_PROP_OP) and all
pre increments/decrements (ZEND_PRE_INC, ZEND_PRE_DEC, ZEND_PRE_INC_OBJ
ZEND_PRE_DEC_OBJ, ZEND_PRE_INC_STATIC_PROP ZEND_PRE_DEC_STATIC_PROP).
m. All internal functions and methods are now required to specify arginfo
information, otherwise warnings will be thrown on startup.
n. The zend_hash_sort and zend_hash_minmax APIs now accept a comparison
function with the following signature:
typedef int (*bucket_compare_func_t)(Bucket *a, Bucket *b);
Previously compare_func_t was used, which accepted void pointers.
Furthermore, the return type of zend_hash_sort and zend_ts_hash_sort has
been changed from int to void; these functions always succeed.
o. The cast_object() handler is now required, i.e. must be non-null. You can
indicate that casting is not supported by always returning FAILURE.
p. The ARG_COUNT() macro has been removed use ZEND_NUM_ARGS() instead.
q. GC_COLLECTABLE flag was inverted into GC_NOT_COLLECTABLE.
Assignments to GC_TYPE_INFO() might need to be changed to properly
set the value of the GC_NOT_COLLECTABLE flag.
r. Just for for userland classes, it is no longer allowed to implement only
the Traversable interface. Instead, it is necessary to implement either
Iterator or IteratorAggregate. You can do the latter by implementing
zend_ce_aggregate and providing the following method implementation:
ZEND_METHOD(MyClass, getIterator) {
ZEND_PARSE_PARAMETERS_NONE();
zend_create_internal_iterator_zval(return_value, ZEND_THIS);
}
s. The zend_fcall_info no_separation flag has been removed, and separation is
never allowed. If you wish to pass (or allow passing) arguments by
reference, explicitly create those arguments as references using
ZEND_MAKE_REF. This removal also affects call_user_function_ex(), which
should be replaced by call_user_function().
t. The following ZEND_API function have changed signature:
1. Void in Zend Engine 4.0:
- add_assoc_*()
- add_index_*()
- add_property_*()
- object_init()
- zend_declare_class_constant*()
- zend_declare_property*()
- zend_startup_modules()
- zend_wrong_parameters_none_error()
- zend_fcall_info_argp()
- zend_fcall_info_argv()
- zend_fcall_info_argn()
- zend_startup()
- zend_set_memory_limit()
- pass_two()
- zend_startup_constants()
- zend_shutdown_constants()
- zend_startup_extensions_mechanism()
- zend_startup_extensions()
- zend_register_extension()
- highlight_string()
- zend_ini_startup()
- zend_ini_shutdown()
- zend_ini_global_shutdown()
- zend_ini_deactivate()
- zend_copy_ini_directives()
- zend_prepare_string_for_scanning()
- zend_init_rsrc_list()
- zend_list_close()
- zend_signal()
- zend_sigaction()
- zend_stack_init()
- zend_stack_del_top()
- zend_stack_destroy()
2. Argument int to uint32_t in Zend Engine 4.0:
- _zend_get_parameters_array_ex()
- zend_copy_parameters_array()
- zend_fcall_info_args_save()
- zend_fcall_info_args_restore()
- zend_fcall_info_argp()
- zend_fcall_info_argv()
- zend_fcall_info_argn()
- zend_wrong_parameter*()
- zend_wrong_callback_error()
- zend_parse_arg_class()
3. Argument int to bool in Zend Engine 4.0:
- add_next_index_bool()
- zend_register_class_alias_ex()
- add_assoc_bool_ex()
- add_index_bool()
- zend_fcall_info_args_clear()
- zend_set_local_var()
- zend_set_local_var_str()
- zend_parse_arg_*()
- shutdown_memory_manager()
- zend_memory_usage()
- zend_memory_peak_usage()
- zend_mm_shutdown()
- zend_eval_string*()
- zend_set_timeout()
- _zend_hash_append_ex()
- _zend_hash_append_ptr_ex()
- zend_alter_ini_entry_ex()
- (*zend_encoding_list_parser) typedef
- zend_multibyte_parse_encoding_list()
- zend_safe_address()
- zend_string_tolower_ex()
- zend_string_alloc()
- zend_string_safe_alloc()
- zend_string_init()
- zend_string_dup()
- zend_string_realloc()
- zend_string_extend()
- zend_string_truncate()
- zend_string_safe_realloc()
- zend_string_release_ex()
- zend_ts_hash_merge()
- zend_ts_hash_sort()
4. Argument int to size_t in Zend Engine 4.0:
- zend_set_hash_symbol()
5. Argument zval* to zend_object* in Zend Engine 4.0:
- zend_read_property()
- zend_update_property()
- zend_unset_property()
- zend_call_method()
- zend_objects_clone_obj()
- zend_get_closure_method_def()
- zend_throw_exception_hook()
- zend_throw_exception_internal()
- zend_get_exception_base()
6. Argument zval* to zend_long in Zend Engine 4.0:
- _php_math_longtobase()
7. Return type from int to zend_result in Zend Engine 4.0:
- (*stream_open_function) in _zend_utility_functions
- (*zend_post_startup_cb)
- (*zend_preload_autoload)
- zend_execute_scripts()
- zend_post_startup()
- _zend_get_parameters_array_ex()
- zend_copy_parameters_array()
- zend_parse_parameters()
- zend_parse_parameters_ex()
- zend_parse_method_parameters()
- zend_parse_method_parameters_ex()
- zend_parse_method_parameters()
- zend_register_functions()
- zend_startup_module()
- zend_startup_module_ex()
- zend_register_class_alias_ex()
- zend_disable_function()
- zend_disable_class()
- zend_update_class_constants()
- zend_update_static_property*()
- object_init_ex()
- object_and_properties_init()
- add_index_zval()
- add_next_index_long_*()
- array_set_zval_key()
- _call_user_function_impl()
- zend_fcall_info_*()
- zend_call_function()
- zend_set_hash_symbol()
- zend_delete_global_variable()
- zend_set_local_var()
- zend_set_local_var_str()
- zend_forbid_dynamic_call()
- zend_get_default_from_internal_arg_info()
- zend_try_assign_typed_ref*()
- zend_ast_evaluate()
- zend_startup_builtin_functions()
- do_bind_function()
- do_bind_class()
- zend_unmangle_property_name_ex()
- zend_register_auto_global()
- zend_register_constant()
- zend_exception_error()
- zend_eval_string*()
- zend_undefined_offset_write()
- zend_undefined_index_write()
- zval_update_constant(_ex)()
- zend_load_extension()
- zend_load_extension_handle()
- zend_hash_del(_ind)()
- zend_hash_str_del(_ind)()
- zend_hash_index_del()
- zend_hash_move_forward_ex()
- zend_hash_move_backward_ex()
- zend_hash_get_current_key_ex()
- zend_hash_get_current_key_type_ex()
- zend_symtable_del(_ind)()
- zend_symtable_str_del(_ind)()
- highlight_file()
- zend_do_link_class()
- zend_alter_ini_entry*()
- zend_restore_ini_entry()
- zend_ini_register_displayer()
- zend_ini_open_file_for_scanning()
- zend_ini_prepare_string_for_scanning()
- zend_user_it_valid()
- zend_create_internal_iterator_zval()
- zend_multibyte_set_filter()
- zend_lex_tstring()
- _zend_module_entry module_startup_func, module_shutdown_func,
request_startup_func, request_shutdown_func, and post_deactivate_func function pointers
- (*zend_encoding_list_parser) typedef
- (*zend_encoding_internal_encoding_setter) typedef
- zend_multibyte_set_functions()
- zend_multibyte_set_script_encoding_by_string()
- add_function()
- sub_function()
- mul_function()
- pow_function()
- div_function()
- mod_function()
- boolean_xor_function()
- boolean_not_function()
- bitwise_not_function()
- bitwise_or_function()
- bitwise_and_function()
- bitwise_xor_function()
- shift_left_function()
- shift_right_function()
- concat_function()
- is_equal_function(
- is_identical_function()
- is_not_identical_function()
- is_not_equal_function()
- is_smaller_function()
- is_smaller_or_equal_function(zv
- increment_function()
- decrement_function()
- zend_stream_open()
- zend_stream_fixup()
- zend_ts_hash_del()
- zend_ts_hash_index_del()
8. Return type from int to bool in Zend Engine 4.0:
- zend_make_printable_zval()
- zend_parse_arg_*()
- is_zend_mm()
- is_zend_ptr()
- zend_mm_is_custom_heap()
- (*zend_mm_chunk_truncate_t)
- (*zend_mm_chunk_extend_t)
- zend_bitset_empty()
- zend_is_smart_branch()
- zend_check_arg_send_type()
- zend_verify_const_access()
- zend_gdb_register_code()
- zend_gdb_present()
- _zend_handle_numeric_str(_ex)()
- zend_hash_exists_ind()
- zend_hash_str_exists_ind()
- zend_symtable_exists(_ind)()
- zend_symtable_str_exists()
- (*zend_encoding_lexer_compatibility_checker)
- zend_object_is_true()
- i_zend_is_true()
- zendi_smart_streq()
- zend_stack_is_empty()
- zend_ts_hash_exists()
- zend_ts_hash_index_exists()
9. Argument void to const char* in Zend Engine 4.0:
- zend_get_op_array_extension_handle()
10. Argument zend_extension to const char* in Zend Engine 4.0:
- zend_get_resource_handle()
11. Argument const char * to HMODULE in Zend Engine 4.0:
- php_win32_image_compatible()
12. const char * argument dropped in Zend Engine 4.0:
- php_win32_crt_compatible()
u. Instead of overwriting zend_error_cb extensions with debugging, monitoring
use-cases catching Errors/Exceptions are strongly encouraged to use
the new error observer API instead.
Error observering callbacks are guaranteed to be called regardless of
the users error_reporting setting or userland error handler return values.
Register observer callbacks during MINIT of an extension:
void my_error_observer_cb(int type,
const char *error_filename,
uint32_t error_lineno,
zend_string *message) {
}
zend_observer_error_register(my_error_observer_cb);
v. The following APIs have been removed from the Zend Engine:
- zend_ts_hash_init_ex(), drop the last argument and use zend_ts_hash_init() instead
- zend_hash_init_ex(), drop the last argument and use zend_hash_init() instead
- zval_internal_dtor(), use zval_internal_ptr_dtor() instead
- zval_dtor_func(), use rc_dtor_func() instead
- zval_ptr_dtor_wrapper(), use zval_ptr_dtor() instead
- zval_internal_ptr_dtor_wrapper(), use zval_internal_ptr_dtor() instead
w. The following APIs have been renamed:
- _zend_ts_hash_init() to zend_ts_hash_init()
x. In COMPILE_EXTENDED_STMT mode, a ZEND_EXT_NOP opcode will no longer be
generated at the start of a function. Use the new observer APIs or hook
into zend_execute_ex instead.
========================
2. Build system changes
========================
a. Abstract
1. Symbol HAVE_HASH_EXT is removed and is no longer defined. It should be
considered to have hash extension always available since PHP 7.4.
2. Symbol HAVE_PCRE is removed and is no longer defined. It should be
considered to have pcre extension always available since PHP 7.4.
3. Symbol HAVE_LOCALE_H has been removed and is no longer defined.
4. --disable-inline-optimization (which actually disabled all compiler
optimizations) has been removed. If you wish to build PHP on a host
with extremely constrained memory, and compilation fails with an "out
of memory" message, add "-O0" to CFLAGS.
5. build system and provider are displayed in phpinfo from environment:
- PHP_BUILD_SYSTEM (default is same as PHP_UNAME)
- PHP_BUILD_PROVIDER (no default)
b. Unix build system changes
1. --enable-maintainer-zts is renamed --enable-zts for parity with Windows
and as recognition that ZTS is not a "maintainer" or experimental
feature.
2. The PHP_CHECK_GCC_ARG() m4 macro has been removed in favor of
AX_CHECK_COMPILE_FLAG().
3. The 6th argument of PHP_ADD_SOURCES_X has been removed.
4. The 'special-flags' (3rd) argument of PHP_ADD_SOURCES_X are
now appended instead of prepended to previous compiler flags.
This means compiler flags passed to PHP_NEW_EXTENSION and PHP_ADD_SOURCES
are now appended, this allows to disable compiler flags set by Zend/Zend.m4
(e.g. disable certain compiler flags enabled by -Wextra)
c. Windows build system changes
- The configuration option --enable-crt-debug has been removed. The VC
debug heap can now be enabled for debug builds by setting the environment
variable PHP_WIN32_DEBUG_HEAP to a non-negative number before PHP process
startup.
========================
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.
--------------------------------------------------------------------
-37
View File
@@ -1,37 +0,0 @@
#
# Zend
#
$(builddir)/zend_language_scanner.lo: $(srcdir)/zend_language_parser.h
$(builddir)/zend_ini_scanner.lo: $(srcdir)/zend_ini_parser.h
$(srcdir)/zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l)
$(srcdir)/zend_language_parser.h: $(srcdir)/zend_language_parser.c
$(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
# Tweak zendparse to be exported through ZEND_API. This has to be revisited once
# bison supports foreign skeletons and that bison version is used. Read
# https://git.savannah.gnu.org/cgit/bison.git/tree/data/README.md for more.
@$(YACC) $(YFLAGS) -v -d $(srcdir)/zend_language_parser.y -o $@
@$(SED) -e 's,^int zendparse\(.*\),ZEND_API int zendparse\1,g' < $@ \
> $@.tmp && \
mv $@.tmp $@
@$(SED) -e 's,^int zendparse\(.*\),ZEND_API int zendparse\1,g' < $(srcdir)/zend_language_parser.h \
> $(srcdir)/zend_language_parser.h.tmp && \
mv $(srcdir)/zend_language_parser.h.tmp $(srcdir)/zend_language_parser.h
@nlinit=`echo 'nl="'; echo '"'`; eval "$$nlinit"; \
$(SED) -e "s/^#ifndef YYTOKENTYPE/#include \"zend.h\"\\$${nl}#ifndef YYTOKENTYPE/" < $(srcdir)/zend_language_parser.h \
> $(srcdir)/zend_language_parser.h.tmp && \
mv $(srcdir)/zend_language_parser.h.tmp $(srcdir)/zend_language_parser.h
$(srcdir)/zend_ini_parser.h: $(srcdir)/zend_ini_parser.c
$(srcdir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
$(YACC) $(YFLAGS) -v -d $(srcdir)/zend_ini_parser.y -o $@
$(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
Zend/zend_execute.lo: $(srcdir)/zend_vm_execute.h $(srcdir)/zend_vm_opcodes.h
-139
View File
@@ -1,139 +0,0 @@
# Zend Engine
## 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.
### Debugging
Normal:
```bash
sapi/cli/php -r 'leak();'
```
Zend MM disabled:
```bash
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.
## 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:
```c
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>` and `<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:
```c
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:
```c
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:
```bash
php zend_vm_gen.php --with-vm-kind=CALL
```
-380
View File
@@ -1,380 +0,0 @@
dnl This file contains Zend specific autoconf macros.
dnl
dnl ZEND_CHECK_FLOAT_PRECISION
dnl
dnl x87 floating point internal precision control checks
dnl See: http://wiki.php.net/rfc/rounding
dnl
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
])
dnl
dnl LIBZEND_BASIC_CHECKS
dnl
dnl Basic checks specific for the Zend engine library.
dnl
AC_DEFUN([LIBZEND_BASIC_CHECKS],[
AC_REQUIRE([AC_PROG_CC])
AC_CHECK_HEADERS([cpuid.h])
dnl
dnl LIBZEND_DLSYM_CHECK
dnl
dnl Ugly hack to check if dlsym() requires a leading underscore in symbol name.
dnl
AC_DEFUN([LIBZEND_DLSYM_CHECK],[
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 Checks for library functions.
AC_CHECK_FUNCS(getpid kill sigsetjmp)
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>
#include <stdlib.h>
int main()
{
if (sizeof(long) == 4) {
double d = (double) LONG_MIN * LONG_MIN + 2e9;
if ((long) d == 2e9 && (long) -d == -2e9) {
return 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 */
return 0;
}
}
return 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)
])
])
dnl
dnl LIBZEND_OTHER_CHECKS
dnl
AC_DEFUN([LIBZEND_OTHER_CHECKS],[
AC_MSG_CHECKING(whether to enable thread-safety)
AC_MSG_RESULT($ZEND_ZTS)
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
else
AC_DEFINE(ZEND_DEBUG,0,[ ])
fi
test -n "$GCC" && CFLAGS="-Wall -Wextra -Wno-strict-aliasing -Wno-implicit-fallthrough -Wno-unused-parameter -Wno-sign-compare $CFLAGS"
dnl Check if compiler supports -Wno-clobbered (only GCC)
AX_CHECK_COMPILE_FLAG([-Wno-clobbered], CFLAGS="-Wno-clobbered $CFLAGS", , [-Werror])
test -n "$DEBUG_CFLAGS" && CFLAGS="$CFLAGS $DEBUG_CFLAGS"
if test "$ZEND_ZTS" = "yes"; then
AC_DEFINE(ZTS,1,[ ])
CFLAGS="$CFLAGS -DZTS"
fi
AC_C_INLINE
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. This also does the
dnl logarithmic test for ZEND_MM.
AC_MSG_CHECKING(for MM alignment and log values)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#include <stdlib.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);
return 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 compilation needs something here.
LIBZEND_MM_ALIGN=8
])
AC_MSG_RESULT(done)
AC_CHECK_FUNCS(mremap)
AC_ARG_ENABLE([zend-signals],
[AS_HELP_STRING([--disable-zend-signals],
[whether to enable zend signal handling])],
[ZEND_SIGNALS=$enableval],
[ZEND_SIGNALS=yes])
AC_CHECK_FUNCS([sigaction], [], [
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_ARG_ENABLE([gcc-global-regs],
[AS_HELP_STRING([--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"
#elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__aarch64__)
# define ZEND_VM_FP_GLOBAL_REG "x27"
# define ZEND_VM_IP_GLOBAL_REG "x28"
#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 Check whether __cpuid_count is available.
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
-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();
?>
-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");
-62
View File
@@ -1,62 +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);
try {
func_num_args();
} catch (Error $exception) {
echo $exception->getMessage() . "\n";
}
echo "Done\n";
?>
--EXPECTF--
int(0)
int(1)
Exception: Too few arguments to function test2(), 0 passed in %s on line %d and exactly 1 expected
int(2)
int(0)
Exception: Too few arguments to function test3(), 1 passed in %s on line %d and exactly 2 expected
int(2)
int(1)
func_num_args() must be called from a function context
Done
-121
View File
@@ -1,121 +0,0 @@
--TEST--
func_get_arg() tests
--FILE--
<?php
function test1() {
try {
var_dump(func_get_arg(-10));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(func_get_arg(0));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(func_get_arg(1));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
}
function test2($a) {
try {
var_dump(func_get_arg(0));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(func_get_arg(1));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
}
function test3($a, $b) {
try {
var_dump(func_get_arg(0));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(func_get_arg(1));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(func_get_arg(2));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
}
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) {
try {
var_dump(func_get_arg(0));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(func_get_arg(1));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
}
}
test::test1(1);
try {
var_dump(func_get_arg(1));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
echo "Done\n";
?>
--EXPECTF--
func_get_arg(): Argument #1 ($position) must be greater than or equal to 0
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
func_get_arg(): Argument #1 ($position) must be greater than or equal to 0
int(10)
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
int(1)
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
Exception: Too few arguments to function test2(), 0 passed in %s002.php on line %d and exactly 1 expected
int(1)
int(2)
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
func_get_arg(): Argument #1 ($position) must be greater than or equal to 0
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
Exception: Too few arguments to function test3(), 1 passed in %s on line %d and exactly 2 expected
int(1)
int(2)
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
int(1)
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
func_get_arg() cannot be called from the global scope
Done
-82
View File
@@ -1,82 +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);
try {
var_dump(func_get_args());
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
?>
--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)
}
func_get_args() cannot be called from the global scope
-22
View File
@@ -1,22 +0,0 @@
--TEST--
strncmp() tests
--FILE--
<?php
var_dump(strncmp("", "", 100));
try {
var_dump(strncmp("aef", "dfsgbdf", -1));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump(strncmp("fghjkl", "qwer", 0));
var_dump(strncmp("qwerty", "qwerty123", 6));
var_dump(strncmp("qwerty", "qwerty123", 7));
?>
--EXPECT--
int(0)
strncmp(): Argument #3 ($length) must be greater than or equal to 0
int(0)
int(0)
int(-1)
-24
View File
@@ -1,24 +0,0 @@
--TEST--
strcasecmp() tests
--FILE--
<?php
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";
?>
--EXPECT--
int(0)
int(-3)
int(-1)
int(0)
int(0)
int(0)
int(0)
Done
-29
View File
@@ -1,29 +0,0 @@
--TEST--
strncasecmp() tests
--FILE--
<?php
try {
var_dump(strncasecmp("", "", -1));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
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));
?>
--EXPECT--
strncasecmp(): Argument #3 ($length) must be greater than or equal to 0
int(0)
int(-3)
int(0)
int(0)
int(2)
int(0)
int(0)
-49
View File
@@ -1,49 +0,0 @@
--TEST--
define() tests
--FILE--
<?php
try {
var_dump(define(array(1,2,3,4,5), 1));
} catch (TypeError $e) {
echo "TypeError: ", $e->getMessage(), "\n";
}
var_dump(define("TRUE", 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')));
try {
var_dump(define("test2", new stdclass));
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}
var_dump(constant(" "));
var_dump(constant("[[["));
var_dump(constant("test const"));
echo "Done\n";
?>
--EXPECTF--
TypeError: define(): Argument #1 ($constant_name) must be of type string, array given
Warning: Constant TRUE already defined in %s on line %d
bool(false)
bool(true)
bool(true)
bool(true)
Warning: Constant test const already defined in %s on line %d
bool(false)
bool(true)
bool(true)
define(): Argument #2 ($value) cannot be an object, stdClass given
int(1)
int(2)
int(3)
Done
-55
View File
@@ -1,55 +0,0 @@
--TEST--
get_class() tests
--FILE--
<?php
class foo {
function bar () {
var_dump(get_class());
}
function testNull ()
{
try {
var_dump(get_class(null));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
}
}
class foo2 extends foo {
}
$f1 = new foo;
$f2 = new foo2;
$f1->bar();
$f2->bar();
try {
var_dump(get_class());
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(get_class("qwerty"));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
var_dump(get_class($f1));
var_dump(get_class($f2));
$f1->testNull();
echo "Done\n";
?>
--EXPECT--
string(3) "foo"
string(3) "foo"
get_class() without arguments must be called from within a class
get_class(): Argument #1 ($object) must be of type object, string given
string(3) "foo"
string(4) "foo2"
get_class(): Argument #1 ($object) must be of type object, null given
Done
-84
View File
@@ -1,84 +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"));
try {
get_parent_class("");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}
try {
get_parent_class("[[[[");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}
try {
get_parent_class(" ");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}
var_dump(get_parent_class(new stdclass));
try {
get_parent_class(array());
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}
try {
get_parent_class(1);
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}
echo "Done\n";
?>
--EXPECT--
bool(false)
bool(false)
string(3) "foo"
string(3) "foo"
bool(false)
string(3) "foo"
bool(false)
bool(false)
get_parent_class(): Argument #1 ($object_or_class) must be an object or a valid class name, string given
get_parent_class(): Argument #1 ($object_or_class) must be an object or a valid class name, string given
get_parent_class(): Argument #1 ($object_or_class) must be an object or a valid class name, string given
bool(false)
get_parent_class(): Argument #1 ($object_or_class) must be an object or a valid class name, array given
get_parent_class(): Argument #1 ($object_or_class) must be an object or a valid class name, int given
Done
-99
View File
@@ -1,99 +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("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,""));
try {
var_dump(property_exists(array(), "test"));
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(property_exists(1, "test"));
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(property_exists(3.14, "test"));
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(property_exists(true, "test"));
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(property_exists(null, "test"));
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
$foo->bar();
$bar = new bar;
$bar->test();
?>
--EXPECT--
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)
property_exists(): Argument #1 ($object_or_class) must be of type object|string, array given
property_exists(): Argument #1 ($object_or_class) must be of type object|string, int given
property_exists(): Argument #1 ($object_or_class) must be of type object|string, float given
property_exists(): Argument #1 ($object_or_class) must be of type object|string, bool given
property_exists(): Argument #1 ($object_or_class) must be of type object|string, null given
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
-27
View File
@@ -1,27 +0,0 @@
--TEST--
class_exists() tests
--FILE--
<?php
class foo {
}
var_dump(class_exists("qwerty"));
var_dump(class_exists(""));
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";
?>
--EXPECT--
bool(false)
bool(false)
bool(false)
bool(true)
bool(true)
bool(true)
bool(true)
Done
-27
View File
@@ -1,27 +0,0 @@
--TEST--
interface_exists() tests
--FILE--
<?php
interface foo {
}
var_dump(interface_exists("qwerty"));
var_dump(interface_exists(""));
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";
?>
--EXPECT--
bool(false)
bool(false)
bool(false)
bool(true)
bool(true)
bool(false)
bool(false)
Done
-3
View File
@@ -1,3 +0,0 @@
<?php
/* dummy file for 014.phpt */
?>
-42
View File
@@ -1,42 +0,0 @@
--TEST--
get_included_files() tests
--FILE--
<?php
var_dump(get_included_files());
include(__DIR__."/014.inc");
var_dump(get_included_files());
include_once(__DIR__."/014.inc");
var_dump(get_included_files());
include(__DIR__."/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"
}
array(2) {
[0]=>
string(%d) "%s"
[1]=>
string(%d) "%s"
}
array(2) {
[0]=>
string(%d) "%s"
[1]=>
string(%d) "%s"
}
Done
-33
View File
@@ -1,33 +0,0 @@
--TEST--
trigger_error() tests
--FILE--
<?php
var_dump(trigger_error("error"));
try {
var_dump(trigger_error("error", -1));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(trigger_error("error", 0));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump(trigger_error("error", E_USER_WARNING));
var_dump(trigger_error("error", E_USER_DEPRECATED));
?>
--EXPECTF--
Notice: error in %s on line %d
bool(true)
trigger_error(): Argument #2 ($error_level) must be one of E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE, or E_USER_DEPRECATED
trigger_error(): Argument #2 ($error_level) must be one of E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE, or E_USER_DEPRECATED
Warning: error in %s on line %d
bool(true)
Deprecated: error in %s on line %d
bool(true)
-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
-59
View File
@@ -1,59 +0,0 @@
--TEST--
builtin functions tests
--FILE--
<?php
$fp = fopen(__FILE__, "r");
var_dump(get_resource_type($fp));
fclose($fp);
var_dump(get_resource_type($fp));
var_dump(gettype(get_loaded_extensions()));
var_dump(count(get_loaded_extensions()));
var_dump(gettype(get_loaded_extensions(true)));
var_dump(count(get_loaded_extensions(true)));
define("USER_CONSTANT", "test");
var_dump(gettype(get_defined_constants(true)));
var_dump(gettype(get_defined_constants()));
var_dump(count(get_defined_constants()));
function test () {
}
var_dump(gettype(get_defined_functions()));
var_dump(count(get_defined_functions()));
var_dump(gettype(get_declared_interfaces()));
var_dump(count(get_declared_interfaces()));
var_dump(get_extension_funcs(true));
var_dump(gettype(get_extension_funcs("standard")));
var_dump(count(get_extension_funcs("standard")));
var_dump(gettype(get_extension_funcs("zend")));
var_dump(count(get_extension_funcs("zend")));
echo "Done\n";
?>
--EXPECTF--
string(6) "stream"
string(7) "Unknown"
string(5) "array"
int(%d)
string(5) "array"
int(%d)
string(5) "array"
string(5) "array"
int(%d)
string(5) "array"
int(%d)
string(5) "array"
int(%d)
bool(false)
string(5) "array"
int(%d)
string(5) "array"
int(%d)
Done
-24
View File
@@ -1,24 +0,0 @@
--TEST--
constant() tests
--FILE--
<?php
try {
var_dump(constant(""));
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
define("TEST_CONST", 1);
var_dump(constant("TEST_CONST"));
define("TEST_CONST2", "test");
var_dump(constant("TEST_CONST2"));
echo "Done\n";
?>
--EXPECT--
Undefined constant ""
int(1)
string(4) "test"
Done
-1321
View File
File diff suppressed because it is too large. Load diff
-29
View File
@@ -1,29 +0,0 @@
--TEST--
func_get_arg() invalid usage
--FILE--
<?php
try {
var_dump(func_get_arg(1));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
function bar() {
var_dump(func_get_arg(1));
}
function foo() {
bar(func_get_arg(1));
}
try {
foo(1,2);
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
?>
--EXPECT--
func_get_arg() cannot be called from the global scope
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
-37
View File
@@ -1,37 +0,0 @@
--TEST--
?: operator
--FILE--
<?php
var_dump(true ?: false);
var_dump(false ?: true);
var_dump(23 ?: 42);
var_dump(0 ?: "bar");
$a = 23;
$b = 0;
$c = "";
$d = 23.5;
var_dump($a ?: $b);
var_dump($c ?: $d);
var_dump(1 ?: print(2));
$e = array();
$e['e'] = 'e';
$e['e'] = $e['e'] ?: 'e';
print_r($e);
?>
--EXPECT--
bool(true)
bool(true)
int(23)
string(3) "bar"
int(23)
float(23.5)
int(1)
Array
(
[e] => e
)
-25
View File
@@ -1,25 +0,0 @@
--TEST--
Implementing abstracting methods and optional parameters
--FILE--
<?php
abstract class Base
{
abstract function someMethod($param);
}
class Ext extends Base
{
function someMethod($param = "default")
{
echo $param, "\n";
}
}
$a = new Ext();
$a->someMethod("foo");
$a->someMethod();
?>
--EXPECT--
foo
default
-45
View File
@@ -1,45 +0,0 @@
--TEST--
Testing variable variables as function name
--FILE--
<?php
$a = 'ucfirst';
$b = 'a';
print $$b('test');
print "\n";
class bar {
public function a() {
return "bar!";
}
}
class foo {
public function test() {
print "foo!\n";
return new bar;
}
}
function test() {
return new foo;
}
$a = 'test';
$b = 'a';
var_dump($$b()->$$b()->$b());
$a = 'strtoupper';
$b = 'a';
$c = 'b';
$d = 'c';
var_dump($$$$d('foo'));
?>
--EXPECT--
Test
foo!
string(4) "bar!"
string(3) "FOO"
-57
View File
@@ -1,57 +0,0 @@
--TEST--
Testing operations with undefined variable
--FILE--
<?php
var_dump($a[1]);
var_dump($a[$c]);
var_dump($a + 1);
var_dump($a + $b);
var_dump($a++);
var_dump(++$b);
var_dump($a->$b);
var_dump($a->$b);
var_dump($a->$b->{$c[1]});
?>
--EXPECTF--
Warning: Undefined variable $a in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
NULL
Warning: Undefined variable $a in %s on line %d
Warning: Undefined variable $c in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
NULL
Warning: Undefined variable $a in %s on line %d
int(1)
Warning: Undefined variable $a in %s on line %d
Warning: Undefined variable $b in %s on line %d
int(0)
Warning: Undefined variable $a in %s on line %d
NULL
Warning: Undefined variable $b in %s on line %d
int(1)
Warning: Attempt to read property "1" on int in %s on line %d
NULL
Warning: Attempt to read property "1" on int in %s on line %d
NULL
Warning: Undefined variable $c in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Warning: Attempt to read property "1" on int in %s on line %d
Warning: Attempt to read property "" on null in %s on line %d
NULL
-32
View File
@@ -1,32 +0,0 @@
--TEST--
Testing dynamic calls
--FILE--
<?php
class foo {
static public function a() {
print "ok\n";
}
}
$a = 'a';
$b = 'a';
$class = 'foo';
foo::a();
foo::$a();
foo::$$b();
$class::a();
$class::$a();
$class::$$b();
?>
--EXPECT--
ok
ok
ok
ok
ok
ok
-28
View File
@@ -1,28 +0,0 @@
--TEST--
Trying assign value to property when an object is not returned in a function
--FILE--
<?php
class foo {
public function a() {
}
}
$test = new foo;
$test->a()->a;
print "ok\n";
try {
$test->a()->a = 1;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
print "ok\n";
?>
--EXPECTF--
Warning: Attempt to read property "a" on null in %s on line %d
ok
Attempt to assign property "a" on null
ok
-22
View File
@@ -1,22 +0,0 @@
--TEST--
Testing dynamic calls using variable variables with curly syntax
--FILE--
<?php
$a = 'b';
$b = 'c';
$c = 'strtoupper';
var_dump(${${$a}}('foo') == 'FOO');
$a = 'b';
$b = 'c';
$c = 'strtoupper';
$strtoupper = 'strtolower';
var_dump(${${++$a}}('FOO') == 'foo');
?>
--EXPECT--
bool(true)
bool(true)
-26
View File
@@ -1,26 +0,0 @@
--TEST--
Testing function call through of array item
--FILE--
<?php
$arr = array('strtoupper', 'strtolower');
$k = 0;
var_dump($arr[0]('foo') == 'FOO');
var_dump($arr[$k]('foo') == 'FOO');
var_dump($arr[++$k]('FOO') == 'foo');
var_dump($arr[++$k]('FOO') == 'foo');
?>
--EXPECTF--
bool(true)
bool(true)
bool(true)
Warning: Undefined array key 2 in %s on line %d
Fatal error: Uncaught Error: Value of type null is not callable in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
-51
View File
@@ -1,51 +0,0 @@
--TEST--
Testing assign to property of an object in an array
--FILE--
<?php
$arr = array(new stdClass);
$arr[0]->a = clone $arr[0];
var_dump($arr);
$arr[0]->b = new $arr[0];
var_dump($arr);
$arr[0]->c = $arr[0]->a;
var_dump($arr);
?>
--EXPECT--
array(1) {
[0]=>
object(stdClass)#1 (1) {
["a"]=>
object(stdClass)#2 (0) {
}
}
}
array(1) {
[0]=>
object(stdClass)#1 (2) {
["a"]=>
object(stdClass)#2 (0) {
}
["b"]=>
object(stdClass)#3 (0) {
}
}
}
array(1) {
[0]=>
object(stdClass)#1 (3) {
["a"]=>
object(stdClass)#2 (0) {
}
["b"]=>
object(stdClass)#3 (0) {
}
["c"]=>
object(stdClass)#2 (0) {
}
}
}
-34
View File
@@ -1,34 +0,0 @@
--TEST--
Overriding $this in catch and checking the object properties later.
--FILE--
<?php
class foo {
public $test = 0;
private $test_2 = 1;
protected $test_3 = 2;
public function bar() {
try {
throw new Exception('foo');
} catch (Exception $this) {
var_dump($this);
}
$this->baz();
}
public function baz() {
foreach ($this as $k => $v) {
printf("'%s' => '%s'\n", $k, $v);
}
print "ok\n";
}
}
$test = new foo;
$test->bar();
?>
--EXPECTF--
Fatal error: Cannot re-assign $this in %s030.php on line 11
-11
View File
@@ -1,11 +0,0 @@
--TEST--
Testing array with '[]' passed as argument by value
--FILE--
<?php
function test($var) { }
test($arr[]);
?>
--EXPECTF--
Fatal error: Cannot use [] for reading in %s on line %d
Loaded 100 of 21058 files, more files were not shown because too many files have changed in this diff. Show more