⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 caudium.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    +----------------------------------------------------------------------+   | 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: David Hedbor <neotron@php.net>                               |   | Based on aolserver SAPI by Sascha Schumann <sascha@schumann.cx>      |   +----------------------------------------------------------------------+ *//* $Id: caudium.c,v 1.28.2.5.2.2 2007/01/01 09:46:51 sebastian Exp $ */#include "php.h"#ifdef HAVE_CAUDIUM#include "php_ini.h"#include "php_globals.h"#include "SAPI.h"#include "php_main.h" #include "ext/standard/info.h"#include "php_version.h"/* Pike Include Files  * * conflicts with pike avoided by only using long names. Requires a new * Pike 0.7 since it was implemented for this interface only. * */#define NO_PIKE_SHORTHAND/* Ok, we are now using Pike level threads to handle PHP4 since * the nice th_farm threads aren't working on Linux with glibc 2.2 * (why this is I don't know). */#define USE_PIKE_LEVEL_THREADS#include <fdlib.h>#include <program.h>#include <pike_types.h>#include <interpret.h>#include <module_support.h>#include <array.h>#include <backend.h>#include <stralloc.h>#include <mapping.h>#include <object.h>#include <threads.h>#include <builtin_functions.h>#include <operators.h>#include <version.h>#if (PIKE_MAJOR_VERSION == 7 && PIKE_MINOR_VERSION == 1 && PIKE_BUILD_VERSION >= 12) || PIKE_MAJOR_VERSION > 7 || (PIKE_MAJOR_VERSION == 7 && PIKE_MINOR_VERSION > 1)# include "pike_error.h"#else# include "error.h"# ifndef Pike_error#  define Pike_error error# endif#endif/* Pike 7.x and newer */#define MY_MAPPING_LOOP(md, COUNT, KEY) \  for(COUNT=0;COUNT < md->data->hashsize; COUNT++ ) \	for(KEY=md->data->hash[COUNT];KEY;KEY=KEY->next)#ifndef ZTS/* Need thread safety */#error You need to compile PHP with threads.#endif#ifndef PIKE_THREADS#error The PHP4 module requires that your Pike has thread support.#endif#undef HIDE_GLOBAL_VARIABLES#undef REVEAL_GLOBAL_VARIABLES#define HIDE_GLOBAL_VARIABLES()#define REVEAL_GLOBAL_VARIABLES()/* php_caudium_request is per-request object storage */typedef struct{  struct mapping *request_data;  struct object *my_fd_obj;  struct svalue done_cb;  struct pike_string *filename;  int my_fd;  int written;  TSRMLS_D;} php_caudium_request;void pike_module_init(void);void pike_module_exit(void);static void free_struct(TSRMLS_D);void f_php_caudium_request_handler(INT32 args);/* Defines to get to the data supplied when the script is started. *//* Per thread storage area id... */static int caudium_globals_id;#define GET_THIS() php_caudium_request *_request = ts_resource(caudium_globals_id)#define THIS _request#define PTHIS ((php_caudium_request *)(Pike_fp->current_storage))/* File descriptor integer. Used to write directly to the FD without  * passing Pike */#define MY_FD    (THIS->my_fd)/* FD object. Really a PHPScript object from Pike which implements a couple * of functions to handle headers, writing and buffering. */#define MY_FD_OBJ        ((struct object *)(THIS->my_fd_obj))/* Mapping with data supplied from the calling Caudium module. Contains * a mapping with headers, an FD object etc. */#define REQUEST_DATA ((struct mapping *)(THIS->request_data))extern int fd_from_object(struct object *o);static unsigned char caudium_php_initialized;#ifndef mt_lock_interpreter#define mt_lock_interpreter()     mt_lock(&interpreter_lock);#define mt_unlock_interpreter()   mt_unlock(&interpreter_lock);#endif/* This allows calling of pike functions from the PHP callbacks, * which requires the Pike interpreter to be locked. */#define THREAD_SAFE_RUN(COMMAND, what)  do {\  struct thread_state *state;\  if((state = thread_state_for_id(th_self()))!=NULL) {\    if(!state->swapped) {\      COMMAND;\    } else {\      mt_lock_interpreter();\      SWAP_IN_THREAD(state);\      COMMAND;\      SWAP_OUT_THREAD(state);\      mt_unlock_interpreter();\    }\  }\} while(0)/* Low level header lookup. Basically looks for the named header in the mapping * headers in the supplied options mapping. */ INLINE static struct svalue *lookup_header(char *headername){  struct svalue *headers, *value;  struct pike_string *sind;  GET_THIS();  sind = make_shared_string("env");  headers = low_mapping_string_lookup(REQUEST_DATA, sind);  free_string(sind);  if(!headers || headers->type != PIKE_T_MAPPING) return NULL;  sind = make_shared_string(headername);  value = low_mapping_string_lookup(headers->u.mapping, sind);  free_string(sind);  if(!value) return NULL;  return value;}/* Lookup a header in the mapping and return the value as a string, or * return the default if it's missing */INLINE static char *lookup_string_header(char *headername, char *default_value){  struct svalue *head = NULL;  THREAD_SAFE_RUN(head = lookup_header(headername), "header lookup");  if(!head || head->type != PIKE_T_STRING)    return default_value;  return head->u.string->str;}/* Lookup a header in the mapping and return the value as if it's an integer * and otherwise return the default. */INLINE static int lookup_integer_header(char *headername, int default_value){  struct svalue *head = NULL;  THREAD_SAFE_RUN(head = lookup_header(headername), "header lookup");  if(!head || head->type != PIKE_T_INT)    return default_value;  return head->u.integer;}/* * php_caudium_low_ub_write() writes data to the client connection. Might be * rewritten to do more direct IO to save CPU and the need to lock the  * interpreter for better threading. */INLINE static intphp_caudium_low_ub_write(const char *str, uint str_length TSRMLS_DC) {  int sent_bytes = 0;  struct pike_string *to_write = NULL;  GET_THIS();  if(!MY_FD_OBJ->prog) {    PG(connection_status) = PHP_CONNECTION_ABORTED;    zend_bailout();    return -1;  }  to_write = make_shared_binary_string(str, str_length);  push_string(to_write);  safe_apply(MY_FD_OBJ, "write", 1);  if(Pike_sp[-1].type == PIKE_T_INT)    sent_bytes = Pike_sp[-1].u.integer;  pop_stack();  if(sent_bytes != str_length) {    /* This means the connection is closed. Dead. Gone. *sniff*  */    PG(connection_status) = PHP_CONNECTION_ABORTED;    zend_bailout();  }  return sent_bytes;}/* * php_caudium_sapi_ub_write() calls php_caudium_low_ub_write in a Pike thread * safe manner or writes directly to the output FD if RXML post-parsing is * disabled.  */static intphp_caudium_sapi_ub_write(const char *str, uint str_length TSRMLS_DC){  GET_THIS();  int sent_bytes = 0, fd = MY_FD;  if(fd)  {    for(sent_bytes=0;sent_bytes < str_length;)    {      int written;      written = fd_write(fd, str + sent_bytes, str_length - sent_bytes);      if(written < 0)      {	switch(errno)	{	 default:	  /* This means the connection is closed. Dead. Gone. *sniff*  */	  PG(connection_status) = PHP_CONNECTION_ABORTED;	  zend_bailout();	  THIS->written += sent_bytes;	  return sent_bytes;	 case EINTR: 	 case EWOULDBLOCK:	  continue;	}      } else {	sent_bytes += written;      }    }    THIS->written += sent_bytes;  } else {    THREAD_SAFE_RUN(sent_bytes = php_caudium_low_ub_write(str, str_length TSRMLS_CC),		    "write");  }  return sent_bytes;}/* php_caudium_set_header() sets a header in the header mapping. Called in a * thread safe manner from php_caudium_sapi_header_handler. */INLINE static voidphp_caudium_set_header(char *header_name, char *value, char *p){  struct svalue hsval;  struct pike_string *hval, *ind, *hind;  struct mapping *headermap;  struct svalue *s_headermap, *soldval;  int vallen;  GET_THIS();  /*  hval = make_shared_string(value); */  ind = make_shared_string(" _headers");  hind = make_shared_binary_string(header_name,				   (int)(p - header_name));  s_headermap = low_mapping_string_lookup(REQUEST_DATA, ind);  if(!s_headermap || s_headermap->type != PIKE_T_MAPPING)  {    struct svalue mappie;                                               mappie.type = PIKE_T_MAPPING;    headermap = allocate_mapping(1);    mappie.u.mapping = headermap;    mapping_string_insert(REQUEST_DATA, ind, &mappie);    free_mapping(headermap);    hval = make_shared_string(value);  } else {    headermap = s_headermap->u.mapping;    soldval = low_mapping_string_lookup(headermap, hind);    vallen = strlen(value);    if(soldval != NULL &&        soldval->type == PIKE_T_STRING &&       soldval->u.string->size_shift == 0) {      /* Existing, valid header. Prepend.*/      hval = begin_shared_string(soldval->u.string->len + 1 + vallen);      MEMCPY(hval->str, soldval->u.string->str, soldval->u.string->len);      STR0(hval)[soldval->u.string->len] = '\0';      MEMCPY(hval->str+soldval->u.string->len+1, value, vallen);      hval = end_shared_string(hval);    } else {       hval = make_shared_string(value);    }  }  hsval.type = PIKE_T_STRING;  hsval.u.string = hval;  mapping_string_insert(headermap, hind, &hsval);  free_string(hval);  free_string(ind);  free_string(hind);}/* * php_caudium_sapi_header_handler() sets a HTTP reply header to be  * sent to the client. */static intphp_caudium_sapi_header_handler(sapi_header_struct *sapi_header,			      sapi_headers_struct *sapi_headers TSRMLS_DC){  char *header_name, *header_content, *p;  header_name = sapi_header->header;  header_content = p = strchr(header_name, ':');    if(p) {  do {    header_content++;  } while(*header_content == ' ');    THREAD_SAFE_RUN(php_caudium_set_header(header_name, header_content, p), "header handler");  }  sapi_free_header(sapi_header);  return 0;}/* * php_caudium_sapi_send_headers() flushes the headers to the client. * Called before real content is sent by PHP. */INLINE static intphp_caudium_low_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC){  struct pike_string *ind;  struct svalue *s_headermap;  GET_THIS();  if(!MY_FD_OBJ->prog) {    PG(connection_status) = PHP_CONNECTION_ABORTED;    zend_bailout();    return SAPI_HEADER_SEND_FAILED;  }  ind = make_shared_string(" _headers");    s_headermap = low_mapping_string_lookup(REQUEST_DATA, ind);  free_string(ind);    push_int(SG(sapi_headers).http_response_code);  if(s_headermap && s_headermap->type == PIKE_T_MAPPING)    ref_push_mapping(s_headermap->u.mapping);  else    push_int(0);  safe_apply(MY_FD_OBJ, "send_headers", 2);  pop_stack();    return SAPI_HEADER_SENT_SUCCESSFULLY;}static intphp_caudium_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC){  int res = 0;  THREAD_SAFE_RUN(res = php_caudium_low_send_headers(sapi_headers TSRMLS_CC), "send headers");  return res;}/* * php_caudium_sapi_read_post() reads a specified number of bytes from * the client. Used for POST/PUT requests. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -