📄 caudium.c
字号:
INLINE static int php_caudium_low_read_post(char *buf, uint count_bytes){ uint total_read = 0; GET_THIS(); TSRMLS_FETCH(); if(!MY_FD_OBJ->prog) { PG(connection_status) = PHP_CONNECTION_ABORTED; zend_bailout(); return -1; } push_int(count_bytes); safe_apply(MY_FD_OBJ, "read_post", 1); if(Pike_sp[-1].type == PIKE_T_STRING) { MEMCPY(buf, Pike_sp[-1].u.string->str, (total_read = Pike_sp[-1].u.string->len)); buf[total_read] = '\0'; } else total_read = 0; pop_stack(); return total_read;}static intphp_caudium_sapi_read_post(char *buf, uint count_bytes TSRMLS_DC){ uint total_read = 0; THREAD_SAFE_RUN(total_read = php_caudium_low_read_post(buf, count_bytes), "read post"); return total_read;}/* * php_caudium_sapi_read_cookies() returns the Cookie header from * the HTTP request header */ static char *php_caudium_sapi_read_cookies(TSRMLS_D){ char *cookies; cookies = lookup_string_header("HTTP_COOKIE", NULL); return cookies;}static void php_info_caudium(ZEND_MODULE_INFO_FUNC_ARGS){ /* char buf[512]; */ php_info_print_table_start(); php_info_print_table_row(2, "SAPI module version", "$Id: caudium.c,v 1.28.2.5.2.2 2007/01/01 09:46:51 sebastian Exp $"); /* php_info_print_table_row(2, "Build date", Ns_InfoBuildDate()); php_info_print_table_row(2, "Config file path", Ns_InfoConfigFile()); php_info_print_table_row(2, "Error Log path", Ns_InfoErrorLog()); php_info_print_table_row(2, "Installation path", Ns_InfoHomePath()); php_info_print_table_row(2, "Hostname of server", Ns_InfoHostname()); php_info_print_table_row(2, "Source code label", Ns_InfoLabel()); php_info_print_table_row(2, "Server platform", Ns_InfoPlatform()); snprintf(buf, 511, "%s/%s", Ns_InfoServerName(), Ns_InfoServerVersion()); php_info_print_table_row(2, "Server version", buf); snprintf(buf, 511, "%d day(s), %02d:%02d:%02d", uptime / 86400, (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60); php_info_print_table_row(2, "Server uptime", buf); */ php_info_print_table_end();}static zend_module_entry php_caudium_module = { STANDARD_MODULE_HEADER, "Caudium", NULL, NULL, NULL, NULL, NULL, php_info_caudium, NULL, STANDARD_MODULE_PROPERTIES};INLINE static void low_sapi_caudium_register_variables(zval *track_vars_array TSRMLS_DC) { int i; struct keypair *k; struct svalue *headers; struct pike_string *sind; struct svalue *ind; struct svalue *val; GET_THIS(); php_register_variable("PHP_SELF", SG(request_info).request_uri, track_vars_array TSRMLS_CC); php_register_variable("GATEWAY_INTERFACE", "CGI/1.1", track_vars_array TSRMLS_CC); php_register_variable("REQUEST_METHOD", (char *) SG(request_info).request_method, track_vars_array TSRMLS_CC); php_register_variable("REQUEST_URI", SG(request_info).request_uri, track_vars_array TSRMLS_CC); php_register_variable("PATH_TRANSLATED", SG(request_info).path_translated, track_vars_array TSRMLS_CC); sind = make_shared_string("env"); headers = low_mapping_string_lookup(REQUEST_DATA, sind); free_string(sind); if(headers && headers->type == PIKE_T_MAPPING) { MY_MAPPING_LOOP(headers->u.mapping, i, k) { ind = &k->ind; val = &k->val; if(ind && ind->type == PIKE_T_STRING && val && val->type == PIKE_T_STRING) { php_register_variable(ind->u.string->str, val->u.string->str, track_vars_array TSRMLS_CC ); } } }}static void sapi_caudium_register_variables(zval *track_vars_array TSRMLS_DC){ THREAD_SAFE_RUN(low_sapi_caudium_register_variables(track_vars_array TSRMLS_CC), "register_variables");}static int php_caudium_startup(sapi_module_struct *sapi_module){ if (php_module_startup(sapi_module, &php_caudium_module, 1)==FAILURE) { return FAILURE; } return SUCCESS;}/* this structure is static (as in "it does not change") */static sapi_module_struct caudium_sapi_module = { "caudium", "Caudium", php_caudium_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ NULL, /* activate */ NULL, /* deactivate */ php_caudium_sapi_ub_write, /* unbuffered write */ NULL, /* flush */ NULL, /* get uid */ NULL, /* getenv */ php_error, /* error handler */ php_caudium_sapi_header_handler, /* header handler */ php_caudium_sapi_send_headers, /* send headers handler */ NULL, /* send header handler */ php_caudium_sapi_read_post, /* read POST data */ php_caudium_sapi_read_cookies, /* read cookies */ sapi_caudium_register_variables, /* register server variables */ NULL, /* Log message */ NULL, /* Block interruptions */ NULL, /* Unblock interruptions */ STANDARD_SAPI_MODULE_PROPERTIES};/* * php_caudium_module_main() is called by the per-request handler and * "executes" the script */static void php_caudium_module_main(php_caudium_request *ureq){ int res; zend_file_handle file_handle = {0};#ifndef USE_PIKE_LEVEL_THREADS struct thread_state *state; extern struct program *thread_id_prog;#endif TSRMLS_FETCH(); GET_THIS(); THIS->filename = ureq->filename; THIS->done_cb = ureq->done_cb; THIS->my_fd_obj = ureq->my_fd_obj; THIS->my_fd = ureq->my_fd; THIS->request_data = ureq->request_data; free(ureq);#ifndef USE_PIKE_LEVEL_THREADS mt_lock_interpreter(); init_interpreter();#if PIKE_MAJOR_VERSION == 7 && PIKE_MINOR_VERSION < 1 thread_id = low_clone(thread_id_prog); state = OBJ2THREAD(thread_id); Pike_stack_top=((char *)&state)+ (thread_stack_size-16384) * STACK_DIRECTION; recoveries = NULL; call_c_initializers(thread_id); OBJ2THREAD(thread_id)->id=th_self(); num_threads++; thread_table_insert(thread_id); state->status=THREAD_RUNNING;#else Pike_interpreter.thread_id = low_clone(thread_id_prog); state = OBJ2THREAD(Pike_interpreter.thread_id); Pike_interpreter.stack_top=((char *)&state)+ (thread_stack_size-16384) * STACK_DIRECTION; Pike_interpreter.recoveries = NULL; call_c_initializers(Pike_interpreter.thread_id); state->id=th_self(); /* SWAP_OUT_THREAD(OBJ2THREAD(Pike_interpreter.thread_id)); */ num_threads++; thread_table_insert(Pike_interpreter.thread_id); state->status=THREAD_RUNNING;#endif state->swapped = 0;#endif SG(request_info).query_string = lookup_string_header("QUERY_STRING", 0); SG(server_context) = (void *)1; /* avoid server_context == NULL */ /* path_translated is apparently the absolute path to the file, not the translated PATH_INFO */ SG(request_info).path_translated = lookup_string_header("SCRIPT_FILENAME", NULL); SG(request_info).request_uri = lookup_string_header("DOCUMENT_URI", NULL); if(!SG(request_info).request_uri) SG(request_info).request_uri = lookup_string_header("SCRIPT_NAME", NULL); SG(request_info).request_method = lookup_string_header("REQUEST_METHOD", "GET"); SG(request_info).content_length = lookup_integer_header("HTTP_CONTENT_LENGTH", 0); SG(request_info).content_type = lookup_string_header("HTTP_CONTENT_TYPE", NULL); SG(sapi_headers).http_response_code = 200; if (!strcmp(SG(request_info).request_method, "HEAD")) { SG(request_info).headers_only = 1; } else { SG(request_info).headers_only = 0; } /* Let PHP4 handle the deconding of the AUTH */ php_handle_auth_data(lookup_string_header("HTTP_AUTHORIZATION", NULL), TSRMLS_C); /* Swap out this thread and release the interpreter lock to allow * Pike threads to run. We wait since the above would otherwise require * a lot of unlock/lock. */#ifndef USE_PIKE_LEVEL_THREADS SWAP_OUT_THREAD(state); mt_unlock_interpreter();#else THREADS_ALLOW();#endif#ifdef VIRTUAL_DIR /* Change virtual directory, if the feature is enabled, which is * (almost) a requirement for PHP in Caudium. Might want to fail if it * isn't. Not a problem though, since it's on by default when using ZTS * which we require. */ VCWD_CHDIR_FILE(THIS->filename->str);#endif file_handle.type = ZEND_HANDLE_FILENAME; file_handle.filename = THIS->filename->str; file_handle.opened_path = NULL; file_handle.free_filename = 0; THIS->written = 0; res = php_request_startup(TSRMLS_C); if(res == FAILURE) { THREAD_SAFE_RUN({ apply_svalue(&THIS->done_cb, 0); pop_stack(); free_struct(TSRMLS_C); }, "Negative run response"); } else { php_execute_script(&file_handle TSRMLS_CC); php_request_shutdown(NULL); THREAD_SAFE_RUN({ push_int(THIS->written); apply_svalue(&THIS->done_cb, 1); pop_stack(); free_struct(TSRMLS_C); }, "positive run response"); }#ifndef USE_PIKE_LEVEL_THREADS mt_lock_interpreter(); SWAP_IN_THREAD(state);#if PIKE_MAJOR_VERSION == 7 && PIKE_MINOR_VERSION < 1 state->status=THREAD_EXITED; co_signal(& state->status_change); thread_table_delete(thread_id); free_object(thread_id); thread_id=NULL;#else state->status=THREAD_EXITED; co_signal(& state->status_change); thread_table_delete(Pike_interpreter.thread_id); free_object(Pike_interpreter.thread_id); Pike_interpreter.thread_id=NULL;#endif cleanup_interpret(); num_threads--; mt_unlock_interpreter();#else THREADS_DISALLOW();#endif}/* * The php_caudium_request_handler() is called per request and handles * everything for one request. */void f_php_caudium_request_handler(INT32 args){ struct object *my_fd_obj; struct mapping *request_data; struct svalue *done_callback; struct pike_string *script; struct svalue *raw_fd; struct pike_string *ind; php_caudium_request *_request; THIS = malloc(sizeof(php_caudium_request)); if(THIS == NULL) Pike_error("Out of memory."); get_all_args("PHP4.Interpreter->run", args, "%S%m%O%*", &script, &request_data, &my_fd_obj, &done_callback); if(done_callback->type != PIKE_T_FUNCTION) Pike_error("PHP4.Interpreter->run: Bad argument 4, expected function.\n"); add_ref(request_data); add_ref(my_fd_obj); add_ref(script); THIS->request_data = request_data; THIS->my_fd_obj = my_fd_obj; THIS->filename = script; assign_svalue_no_free(&THIS->done_cb, done_callback); ind = make_shared_binary_string("my_fd", 5); raw_fd = low_mapping_string_lookup(THIS->request_data, ind); if(raw_fd && raw_fd->type == PIKE_T_OBJECT) { int fd = fd_from_object(raw_fd->u.object); if(fd == -1) THIS->my_fd = 0; /* Don't send directly to this FD... */ else THIS->my_fd = fd; } else THIS->my_fd = 0;#ifdef USE_PIKE_LEVEL_THREADS php_caudium_module_main(THIS);#else th_farm((void (*)(void *))php_caudium_module_main, THIS);#endif pop_n_elems(args);}static void free_struct(TSRMLS_D){ GET_THIS(); if(THIS->request_data) free_mapping(THIS->request_data); if(THIS->my_fd_obj) free_object(THIS->my_fd_obj); free_svalue(&THIS->done_cb); if(THIS->filename) free_string(THIS->filename); MEMSET(THIS, 0, sizeof(php_caudium_request));}/* * pike_module_init() is called by Pike once at startup * * This functions allocates basic structures */void pike_module_init( void ){ if (!caudium_php_initialized) { caudium_php_initialized = 1; tsrm_startup(1, 1, 0, NULL); ts_allocate_id(&caudium_globals_id, sizeof(php_caudium_request), NULL, NULL); sapi_startup(&caudium_sapi_module); sapi_module.startup(&caudium_sapi_module); } start_new_program(); /* Text */ pike_add_function("run", f_php_caudium_request_handler, "function(string, mapping, object, function:void)", 0); end_class("Interpreter", 0);}/* * pike_module_exit() performs the last steps before the * server exists. Shutdowns basic services and frees memory */void pike_module_exit(void){ caudium_php_initialized = 0; sapi_module.shutdown(&caudium_sapi_module); tsrm_shutdown();}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -