For each request, the worker calls the php_execute_script function from libphp that changes to the script directory before doing its work and then restores the process directory before returning. The chdir(2) calls it performs are unnecessary in Unit design. In simple benchmarks, profiling shows that the chdir syscall code path (syscall, FS walk, etc.) is where the CPU spends most of its time. PHP SAPI semantics requires the script to be run from the script directory. In Unit's PHP implementation, we have two use cases: - script - arbitrary path The "script" configuration doesn't have much need for a working directory change: it can be changed once at module initialization. The module needs to chdir again only if the user's PHP script also calls chdir to switch to another directory during execution. If "script" is not used in Unit configuration, we must ensure the script is run from its directory (thus calling chdir before exec), but there's no need to restore the working directory later. Our implementation disables mandatory chdir calls with the SAPI option SAPI_OPTION_NO_CHDIR, instead calling chdir only when needed. To detect the user's calls to chdir, a simple "unit" extension is added that hooks the built-in chdir() PHP call.
259 lines
6.1 KiB
Plaintext
259 lines
6.1 KiB
Plaintext
|
|
# Copyright (C) Max Romanov
|
|
# Copyright (C) Igor Sysoev
|
|
# Copyright (C) NGINX, Inc.
|
|
|
|
|
|
shift
|
|
|
|
for nxt_option; do
|
|
|
|
case "$nxt_option" in
|
|
-*=*) value=`echo "$nxt_option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
|
|
*) value="" ;;
|
|
esac
|
|
|
|
case "$nxt_option" in
|
|
--config=*) NXT_PHP_CONFIG="$value" ;;
|
|
--module=*) NXT_PHP_MODULE="$value" ;;
|
|
--lib-path=*) NXT_PHP_LIB_PATH="$value" ;;
|
|
--lib-static) NXT_PHP_LIB_STATIC=yes ;;
|
|
|
|
--help)
|
|
cat << END
|
|
|
|
--config=FILE set php-config filename
|
|
--module=NAME set unit php module name
|
|
--lib-path=DIRECTORY set directory path to libphp.so library
|
|
--lib-static enable linking with static libphp.a library
|
|
|
|
END
|
|
exit 0
|
|
;;
|
|
|
|
*)
|
|
echo
|
|
echo $0: error: invalid PHP option \"$nxt_option\"
|
|
echo
|
|
exit 1
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
if [ ! -f $NXT_AUTOCONF_DATA ]; then
|
|
echo
|
|
echo Please run common $0 before configuring module \"$nxt_module\".
|
|
echo
|
|
exit 1
|
|
fi
|
|
|
|
. $NXT_AUTOCONF_DATA
|
|
|
|
|
|
NXT_PHP_CONFIG=${NXT_PHP_CONFIG=php-config}
|
|
NXT_PHP=${NXT_PHP_CONFIG%-config*}
|
|
NXT_PHP_MODULE=${NXT_PHP_MODULE=${NXT_PHP##*/}}
|
|
NXT_PHP_LIB_PATH=${NXT_PHP_LIB_PATH=}
|
|
NXT_PHP_LIB_STATIC=${NXT_PHP_LIB_STATIC=no}
|
|
NXT_PHP_ADDITIONAL_FLAGS=
|
|
|
|
|
|
$echo "configuring PHP module"
|
|
$echo "configuring PHP module ..." >> $NXT_AUTOCONF_ERR
|
|
|
|
$echo -n "checking for PHP ..."
|
|
$echo "checking for PHP ..." >> $NXT_AUTOCONF_ERR
|
|
|
|
NXT_PHP_LDFLAGS=
|
|
|
|
if /bin/sh -c "${NXT_PHP_CONFIG} --version" >> $NXT_AUTOCONF_ERR 2>&1; then
|
|
|
|
$echo " found"
|
|
|
|
NXT_PHP_VERSION="`${NXT_PHP_CONFIG} --version`"
|
|
$echo " + PHP SAPI: [`${NXT_PHP_CONFIG} --php-sapis`]"
|
|
|
|
NXT_PHP_MAJOR_VERSION=${NXT_PHP_VERSION%%.*}
|
|
NXT_PHP_MINOR_VERSION=${NXT_PHP_VERSION#??}
|
|
NXT_PHP_MINOR_VERSION=${NXT_PHP_MINOR_VERSION%.*}
|
|
|
|
if [ $NXT_PHP_MAJOR_VERSION = 5 -a $NXT_PHP_MINOR_VERSION -lt 4 ]; then
|
|
NXT_PHP_ADDITIONAL_FLAGS=-Wno-write-strings
|
|
fi
|
|
|
|
NXT_PHP_INCLUDE="`${NXT_PHP_CONFIG} --includes`"
|
|
|
|
if [ $NXT_PHP_LIB_STATIC = yes ]; then
|
|
|
|
if [ "$NXT_PHP_LIB_PATH" = "" ]; then
|
|
$echo
|
|
$echo $0: error: --lib-static option requires --lib-path option.
|
|
$echo
|
|
exit 1;
|
|
fi
|
|
|
|
NXT_PHP_LIB="$NXT_PHP_LIB_PATH/libphp${NXT_PHP_VERSION%%.*}.a"
|
|
NXT_PHP_LDFLAGS="`${NXT_PHP_CONFIG} --ldflags` \
|
|
`${NXT_PHP_CONFIG} --libs`"
|
|
|
|
else
|
|
NXT_PHP_LIB="-lphp${NXT_PHP_VERSION%%.*}"
|
|
|
|
if [ "$NXT_PHP_LIB_PATH" != "" ]; then
|
|
# "php-config --ldflags" does not contain path to libphp, but
|
|
# contains usually path to libraries required by extensions.
|
|
NXT_PHP_LDFLAGS="-L${NXT_PHP_LIB_PATH} \
|
|
-Wl,-rpath ${NXT_PHP_LIB_PATH}"
|
|
fi
|
|
fi
|
|
|
|
nxt_feature="PHP embed SAPI"
|
|
nxt_feature_name=""
|
|
nxt_feature_run=no
|
|
nxt_feature_incs="${NXT_PHP_INCLUDE}"
|
|
nxt_feature_libs="${NXT_PHP_LIB} ${NXT_PHP_LDFLAGS}"
|
|
nxt_feature_test="
|
|
#include <php.h>
|
|
#include <php_main.h>
|
|
|
|
int main() {
|
|
php_module_startup(NULL, NULL, 0);
|
|
return 0;
|
|
}"
|
|
|
|
. auto/feature
|
|
|
|
if [ $nxt_found = no ]; then
|
|
$echo
|
|
$echo $0: error: no PHP embed SAPI found.
|
|
$echo
|
|
exit 1;
|
|
fi
|
|
|
|
# Bug #71041 (https://bugs.php.net/bug.php?id=71041).
|
|
|
|
nxt_feature="PHP zend_signal_startup()"
|
|
nxt_feature_name=""
|
|
nxt_feature_run=no
|
|
nxt_feature_incs="${NXT_PHP_INCLUDE}"
|
|
nxt_feature_libs="${NXT_PHP_LIB} ${NXT_PHP_LDFLAGS}"
|
|
nxt_feature_test="
|
|
#include <php.h>
|
|
#include <php_main.h>
|
|
|
|
int main() {
|
|
zend_signal_startup();
|
|
return 0;
|
|
}"
|
|
|
|
. auto/feature
|
|
|
|
if [ $nxt_found = yes ]; then
|
|
NXT_ZEND_SIGNAL_STARTUP=1
|
|
else
|
|
NXT_ZEND_SIGNAL_STARTUP=0
|
|
fi
|
|
|
|
else
|
|
$echo
|
|
$echo $0: error: no PHP found.
|
|
$echo
|
|
exit 1;
|
|
fi
|
|
|
|
|
|
nxt_feature="PHP version"
|
|
nxt_feature_name=""
|
|
nxt_feature_run=value
|
|
nxt_feature_incs="${NXT_PHP_INCLUDE}"
|
|
nxt_feature_libs="${NXT_PHP_LIB} ${NXT_PHP_LDFLAGS}"
|
|
nxt_feature_test="
|
|
#include <php.h>
|
|
|
|
int main() {
|
|
printf(\"%s\", PHP_VERSION);
|
|
return 0;
|
|
}"
|
|
|
|
. auto/feature
|
|
|
|
|
|
if grep ^$NXT_PHP_MODULE: $NXT_MAKEFILE 2>&1 > /dev/null; then
|
|
$echo
|
|
$echo $0: error: duplicate \"$NXT_PHP_MODULE\" module configured.
|
|
$echo
|
|
exit 1;
|
|
fi
|
|
|
|
$echo " + PHP module: ${NXT_PHP_MODULE}.unit.so"
|
|
|
|
. auto/cc/deps
|
|
|
|
$echo >> $NXT_MAKEFILE
|
|
|
|
NXT_PHP_MODULE_SRCS=" \
|
|
src/nxt_php_sapi.c \
|
|
"
|
|
|
|
# The php module object files.
|
|
|
|
nxt_objs=$NXT_BUILD_DIR/src/nxt_unit.o
|
|
|
|
for nxt_src in $NXT_PHP_MODULE_SRCS; do
|
|
|
|
nxt_obj=${nxt_src%.c}-$NXT_PHP_MODULE.o
|
|
nxt_dep=${nxt_src%.c}-$NXT_PHP_MODULE.dep
|
|
nxt_dep_flags=`nxt_gen_dep_flags`
|
|
nxt_dep_post=`nxt_gen_dep_post`
|
|
nxt_objs="$nxt_objs $NXT_BUILD_DIR/$nxt_obj"
|
|
|
|
cat << END >> $NXT_MAKEFILE
|
|
|
|
$NXT_BUILD_DIR/$nxt_obj: $nxt_src $NXT_VERSION_H
|
|
\$(CC) -c \$(CFLAGS) $NXT_PHP_ADDITIONAL_FLAGS \$(NXT_INCS) \\
|
|
$NXT_PHP_INCLUDE -DNXT_ZEND_SIGNAL_STARTUP=$NXT_ZEND_SIGNAL_STARTUP \\
|
|
$nxt_dep_flags \\
|
|
-o $NXT_BUILD_DIR/$nxt_obj $nxt_src
|
|
$nxt_dep_post
|
|
|
|
-include $NXT_BUILD_DIR/$nxt_dep
|
|
|
|
END
|
|
|
|
done
|
|
|
|
|
|
cat << END >> $NXT_MAKEFILE
|
|
|
|
.PHONY: ${NXT_PHP_MODULE}
|
|
.PHONY: ${NXT_PHP_MODULE}-install
|
|
.PHONY: ${NXT_PHP_MODULE}-uninstall
|
|
|
|
all: ${NXT_PHP_MODULE}
|
|
|
|
${NXT_PHP_MODULE}: $NXT_BUILD_DIR/${NXT_PHP_MODULE}.unit.so
|
|
|
|
$NXT_BUILD_DIR/${NXT_PHP_MODULE}.unit.so: $nxt_objs
|
|
\$(NXT_MODULE_LINK) -o $NXT_BUILD_DIR/${NXT_PHP_MODULE}.unit.so \\
|
|
$nxt_objs ${NXT_PHP_LIB} ${NXT_PHP_LDFLAGS} $NXT_LD_OPT
|
|
|
|
|
|
install: ${NXT_PHP_MODULE}-install
|
|
|
|
${NXT_PHP_MODULE}-install: ${NXT_PHP_MODULE} install-check
|
|
install -d \$(DESTDIR)$NXT_MODULES
|
|
install -p $NXT_BUILD_DIR/${NXT_PHP_MODULE}.unit.so \\
|
|
\$(DESTDIR)$NXT_MODULES/
|
|
|
|
|
|
uninstall: ${NXT_PHP_MODULE}-uninstall
|
|
|
|
${NXT_PHP_MODULE}-uninstall:
|
|
rm -f \$(DESTDIR)$NXT_MODULES/${NXT_PHP_MODULE}.unit.so
|
|
@rmdir -p \$(DESTDIR)$NXT_MODULES 2>/dev/null || true
|
|
|
|
END
|