📄 php_cli.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Edin Kadribasic <edink@php.net> | | Marcus Boerger <helly@php.net> | | Parts based on CGI SAPI Module by | | Rasmus Lerdorf, Stig Bakken and Zeev Suraski | +----------------------------------------------------------------------+*/#include "php.h"#include "php_globals.h"#include "php_variables.h"#include "zend_hash.h"#include "zend_modules.h"#include "SAPI.h"#include <stdio.h>#include "php.h"#ifdef PHP_WIN32#include "win32/time.h"#include "win32/signal.h"#include <process.h>#endif#if HAVE_SYS_TIME_H#include <sys/time.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_SIGNAL_H#include <signal.h>#endif#if HAVE_SETLOCALE#include <locale.h>#endif#if HAVE_FCNTL_H#include <fcntl.h>#endif#include "zend.h"#include "zend_extensions.h"#include "php_ini.h"#include "php_globals.h"#include "php_main.h"#include "fopen_wrappers.h"#include "ext/standard/php_standard.h"#ifdef PHP_WIN32#include <io.h>#include <fcntl.h>#include "win32/php_registry.h"#endif#if HAVE_SIGNAL_H#include <signal.h>#endif#ifdef __riscos__#include <unixlib/local.h>#endif#include "zend_compile.h"#include "zend_execute.h"#include "zend_highlight.h"#include "zend_indent.h"#include "php_getopt.h"#ifndef O_BINARY#define O_BINARY 0#endif#define PHP_MODE_STANDARD 1#define PHP_MODE_HIGHLIGHT 2#define PHP_MODE_INDENT 3#define PHP_MODE_LINT 4#define PHP_MODE_STRIP 5#define PHP_MODE_CLI_DIRECT 6static char *php_optarg = NULL;static int php_optind = 1;static const opt_struct OPTIONS[] = { {'a', 0, "interactive"}, {'C', 0, "no-chdir"}, /* for compatibility with CGI (do not chdir to script directory) */ {'c', 1, "php-ini"}, {'d', 1, "define"}, {'e', 0, "profile-info"}, {'f', 1, "file"}, {'g', 1, "global"}, {'h', 0, "help"}, {'i', 0, "info"}, {'l', 0, "syntax-check"}, {'m', 0, "modules"}, {'n', 0, "no-php-ini"}, {'q', 0, "no-header"}, /* for compatibility with CGI (do not generate HTTP headers) */ {'H', 0, "hide-args"}, {'r', 1, "run"}, {'s', 0, "syntax-highlight"}, {'s', 0, "syntax-highlighting"}, {'w', 0, "strip"}, {'?', 0, "usage"},/* help alias (both '?' and 'usage') */ {'v', 0, "version"}, {'z', 1, "zend-extension"}, {'-', 0, NULL} /* end of args */};static int print_module_info(zend_module_entry *module, void *arg TSRMLS_DC){ php_printf("%s\n", module->name); return 0;}static int module_name_cmp(const void *a, const void *b TSRMLS_DC){ Bucket *f = *((Bucket **) a); Bucket *s = *((Bucket **) b); return strcasecmp(((zend_module_entry *)f->pData)->name, ((zend_module_entry *)s->pData)->name);}static void print_modules(TSRMLS_D){ HashTable sorted_registry; zend_module_entry tmp; zend_hash_init(&sorted_registry, 50, NULL, NULL, 1); zend_hash_copy(&sorted_registry, &module_registry, NULL, &tmp, sizeof(zend_module_entry)); zend_hash_sort(&sorted_registry, zend_qsort, module_name_cmp, 0 TSRMLS_CC); zend_hash_apply_with_argument(&sorted_registry, (apply_func_arg_t) print_module_info, NULL TSRMLS_CC); zend_hash_destroy(&sorted_registry);}static int print_extension_info(zend_extension *ext, void *arg TSRMLS_DC){ php_printf("%s\n", ext->name); return 0;}static int extension_name_cmp(const zend_llist_element **f, const zend_llist_element **s TSRMLS_DC){ return strcmp(((zend_extension *)(*f)->data)->name, ((zend_extension *)(*s)->data)->name);}static void print_extensions(TSRMLS_D){ zend_llist sorted_exts; zend_llist_copy(&sorted_exts, &zend_extensions); sorted_exts.dtor = NULL; zend_llist_sort(&sorted_exts, extension_name_cmp TSRMLS_CC); zend_llist_apply_with_argument(&sorted_exts, (llist_apply_with_arg_func_t) print_extension_info, NULL TSRMLS_CC); zend_llist_destroy(&sorted_exts);}#ifndef STDOUT_FILENO#define STDOUT_FILENO 1#endifstatic inline size_t sapi_cli_single_write(const char *str, uint str_length){#ifdef PHP_WRITE_STDOUT long ret; ret = write(STDOUT_FILENO, str, str_length); if (ret <= 0) { return 0; } return ret;#else size_t ret; ret = fwrite(str, 1, MIN(str_length, 16384), stdout); return ret;#endif}static int sapi_cli_ub_write(const char *str, uint str_length TSRMLS_DC){ const char *ptr = str; uint remaining = str_length; size_t ret; while (remaining > 0) { ret = sapi_cli_single_write(ptr, remaining); if (!ret) { php_handle_aborted_connection(); } ptr += ret; remaining -= ret; } return str_length;}static void sapi_cli_flush(void *server_context){ /* Ignore EBADF here, it's caused by the fact that STDIN/STDOUT/STDERR streams * are/could be closed before fflush() is called. */ if (fflush(stdout)==EOF && errno!=EBADF) { php_handle_aborted_connection(); }}static char *php_self = "";static char *script_filename = "";static void sapi_cli_register_variables(zval *track_vars_array TSRMLS_DC){ /* In CGI mode, we consider the environment to be a part of the server * variables */ php_import_environment_variables(track_vars_array TSRMLS_CC); /* Build the special-case PHP_SELF variable for the CLI version */ php_register_variable("PHP_SELF", php_self, track_vars_array TSRMLS_CC); php_register_variable("SCRIPT_NAME", php_self, track_vars_array TSRMLS_CC); /* filenames are empty for stdin */ php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array TSRMLS_CC); php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array TSRMLS_CC); /* just make it available */ php_register_variable("DOCUMENT_ROOT", "", track_vars_array TSRMLS_CC);}static void sapi_cli_log_message(char *message){ fprintf(stderr, "%s\n", message);}static int sapi_cli_deactivate(TSRMLS_D){ fflush(stdout); if(SG(request_info).argv0) { free(SG(request_info).argv0); SG(request_info).argv0 = NULL; } return SUCCESS;}static char* sapi_cli_read_cookies(TSRMLS_D){ return NULL;}static int sapi_cli_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC){ /* We do nothing here, this function is needed to prevent that the fallback * header handling is called. */ return SAPI_HEADER_SENT_SUCCESSFULLY;}static void sapi_cli_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC){}static int php_cli_startup(sapi_module_struct *sapi_module){ if (php_module_startup(sapi_module, NULL, 0)==FAILURE) { return FAILURE; } return SUCCESS;}/* {{{ sapi_cli_ini_defaults *//* overwriteable ini defaults must be set in sapi_cli_ini_defaults() */#define INI_DEFAULT(name,value)\ ZVAL_STRING(tmp, value, 0);\ zend_hash_update(configuration_hash, name, sizeof(name), tmp, sizeof(zval), (void**)&entry);\ Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry))/* hard coded ini settings must be set in main() */#define INI_HARDCODED(name,value)\ zend_alter_ini_entry(name, sizeof(name), value, strlen(value), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);static void sapi_cli_ini_defaults(HashTable *configuration_hash){ zval *tmp, *entry; MAKE_STD_ZVAL(tmp); INI_DEFAULT("report_zend_debug", "0"); INI_DEFAULT("display_errors", "1"); FREE_ZVAL(tmp);}/* }}} *//* {{{ sapi_module_struct cli_sapi_module */static sapi_module_struct cli_sapi_module = { "cli", /* name */ "Command Line Interface", /* pretty name */ php_cli_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ NULL, /* activate */ sapi_cli_deactivate, /* deactivate */ sapi_cli_ub_write, /* unbuffered write */ sapi_cli_flush, /* flush */ NULL, /* get uid */ NULL, /* getenv */ php_error, /* error handler */ NULL, /* header handler */ sapi_cli_send_headers, /* send headers handler */ sapi_cli_send_header, /* send header handler */ NULL, /* read POST data */ sapi_cli_read_cookies, /* read Cookies */ sapi_cli_register_variables, /* register server variables */ sapi_cli_log_message, /* Log message */ NULL, /* Block interruptions */ NULL, /* Unblock interruptions */ STANDARD_SAPI_MODULE_PROPERTIES};/* }}} *//* {{{ php_cli_usage */static void php_cli_usage(char *argv0){ char *prog; prog = strrchr(argv0, '/'); if (prog) { prog++; } else { prog = "php"; } php_printf( "Usage: %s [options] [-f] <file> [args...]\n" " %s [options] -r <code> [args...]\n" " %s [options] [-- args...]\n" " -a Run interactively\n" " -c <path>|<file> Look for php.ini file in this directory\n" " -n No php.ini file will be used\n" " -d foo[=bar] Define INI entry foo with value 'bar'\n" " -e Generate extended information for debugger/profiler\n" " -f <file> Parse <file>.\n" " -h This help\n" " -i PHP information\n" " -l Syntax check only (lint)\n" " -m Show compiled in modules\n" " -r <code> Run PHP <code> without using script tags <?..?>\n" " -s Display colour syntax highlighted source.\n" " -v Version number\n" " -w Display source with stripped comments and whitespace.\n" " -z <file> Load Zend extension <file>.\n" "\n" " args... Arguments passed to script. Use -- args when first argument \n" " starts with - or script is read from stdin\n" , prog, prog, prog);}/* }}} */static void define_command_line_ini_entry(char *arg){ char *name, *value; name = arg; value = strchr(arg, '='); if (value) { *value = 0; value++; } else { value = "1"; } zend_alter_ini_entry(name, strlen(name)+1, value, strlen(value), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);}static void php_register_command_line_global_vars(char **arg TSRMLS_DC){ char *var, *val; var = *arg; val = strchr(var, '='); if (!val) { printf("No value specified for variable '%s'\n", var); } else { *val++ = '\0'; php_register_variable(var, val, NULL TSRMLS_CC); } efree(*arg);}static void cli_register_file_handles(TSRMLS_D){ zval *zin, *zout, *zerr; php_stream *s_in, *s_out, *s_err; php_stream_context *sc_in=NULL, *sc_out=NULL, *sc_err=NULL; zend_constant ic, oc, ec; MAKE_STD_ZVAL(zin); MAKE_STD_ZVAL(zout); MAKE_STD_ZVAL(zerr); s_in = php_stream_open_wrapper_ex("php://stdin", "rb", 0, NULL, sc_in); s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out); s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err); if (s_in==NULL || s_out==NULL || s_err==NULL) { FREE_ZVAL(zin); FREE_ZVAL(zout); FREE_ZVAL(zerr); if (s_in) php_stream_close(s_in); if (s_out) php_stream_close(s_out); if (s_err) php_stream_close(s_err); return; } php_stream_to_zval(s_in, zin); php_stream_to_zval(s_out, zout); php_stream_to_zval(s_err, zerr); ic.value = *zin; ic.flags = CONST_CS; ic.name = zend_strndup(ZEND_STRL("STDIN")); ic.name_len = sizeof("STDIN"); ic.module_number = 0; zend_register_constant(&ic TSRMLS_CC); oc.value = *zout; oc.flags = CONST_CS; oc.name = zend_strndup(ZEND_STRL("STDOUT")); oc.name_len = sizeof("STDOUT"); oc.module_number = 0; zend_register_constant(&oc TSRMLS_CC); ec.value = *zerr; ec.flags = CONST_CS; ec.name = zend_strndup(ZEND_STRL("STDERR"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -