Annotation of embedaddon/php/sapi/litespeed/lsapilib.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
                      5:    | Copyright (c) 1997-2007 The PHP Group                                |
                      6:    +----------------------------------------------------------------------+
                      7:    | This source file is subject to version 3.01 of the PHP license,      |
                      8:    | that is bundled with this package in the file LICENSE, and is        |
                      9:    | available at through the world-wide-web at the following url:        |
                     10:    | http://www.php.net/license/3_01.txt.                                 |
                     11:    | If you did not receive a copy of the PHP license and are unable to   |
                     12:    | obtain it through the world-wide-web, please send a note to          |
                     13:    | license@php.net so we can mail you a copy immediately.               |
                     14:    +----------------------------------------------------------------------+
                     15:    | Author: George Wang <gwang@litespeedtech.com>                        |
                     16:    +----------------------------------------------------------------------+
                     17: */
                     18: 
                     19: /* $Id: lsapilib.c 311935 2011-06-08 16:51:59Z gwang $ */
                     20: 
                     21: /*
                     22: Copyright (c) 2007, Lite Speed Technologies Inc.
                     23: All rights reserved.
                     24: 
                     25: Redistribution and use in source and binary forms, with or without
                     26: modification, are permitted provided that the following conditions are
                     27: met: 
                     28: 
                     29:     * Redistributions of source code must retain the above copyright
                     30:       notice, this list of conditions and the following disclaimer. 
                     31:     * Redistributions in binary form must reproduce the above
                     32:       copyright notice, this list of conditions and the following
                     33:       disclaimer in the documentation and/or other materials provided
                     34:       with the distribution. 
                     35:     * Neither the name of the Lite Speed Technologies Inc nor the
                     36:       names of its contributors may be used to endorse or promote
                     37:       products derived from this software without specific prior
                     38:       written permission.  
                     39: 
                     40: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
                     41: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
                     42: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
                     43: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
                     44: OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
                     45: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
                     46: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     47: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     48: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     49: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
                     50: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
                     51: */
                     52: 
                     53: #include <lsapilib.h>
                     54: 
                     55: #include <ctype.h>
                     56: #include <errno.h>
                     57: #include <fcntl.h>
                     58: 
                     59: #include <arpa/inet.h>
                     60: #include <netdb.h>
                     61: #include <netinet/in.h>
                     62: #include <netinet/tcp.h>
                     63: #include <sys/un.h>
                     64: #include <signal.h>
                     65: #include <stdlib.h>
                     66: #include <stdio.h>
                     67: #include <string.h>
                     68: #include <sys/mman.h>
                     69: #include <sys/resource.h>
                     70: #include <sys/socket.h>
                     71: #include <sys/time.h>
                     72: #include <sys/uio.h>
                     73: #include <sys/wait.h>
                     74: #include <time.h>
                     75: #include <unistd.h>
                     76: 
                     77: #define LSAPI_ST_REQ_HEADER     1
                     78: #define LSAPI_ST_REQ_BODY       2
                     79: #define LSAPI_ST_RESP_HEADER    4
                     80: #define LSAPI_ST_RESP_BODY      8
                     81: 
                     82: #define LSAPI_RESP_BUF_SIZE     8192
                     83: #define LSAPI_INIT_RESP_HEADER_LEN 4096
                     84: 
                     85: 
                     86: static int g_inited = 0;
                     87: static int g_running = 1;
                     88: static int s_ppid;
                     89: static int s_slow_req_msecs = 0;
                     90: LSAPI_Request g_req = { -1, -1 };
                     91: 
                     92: void Flush_RespBuf_r( LSAPI_Request * pReq );
                     93: 
                     94: static const char *CGI_HEADERS[H_TRANSFER_ENCODING+1] =
                     95: {
                     96:     "HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET",
                     97:     "HTTP_ACCEPT_ENCODING",
                     98:     "HTTP_ACCEPT_LANGUAGE", "HTTP_AUTHORIZATION",
                     99:     "HTTP_CONNECTION", "CONTENT_TYPE",
                    100:     "CONTENT_LENGTH", "HTTP_COOKIE", "HTTP_COOKIE2",
                    101:     "HTTP_HOST", "HTTP_PRAGMA",
                    102:     "HTTP_REFERER", "HTTP_USER_AGENT",
                    103:     "HTTP_CACHE_CONTROL",
                    104:     "HTTP_IF_MODIFIED_SINCE", "HTTP_IF_MATCH",
                    105:     "HTTP_IF_NONE_MATCH",
                    106:     "HTTP_IF_RANGE",
                    107:     "HTTP_IF_UNMODIFIED_SINCE",
                    108:     "HTTP_KEEP_ALIVE",
                    109:     "HTTP_RANGE",
                    110:     "HTTP_X_FORWARDED_FOR",
                    111:     "HTTP_VIA",
                    112:     "HTTP_TRANSFER_ENCODING"
                    113: };
                    114:      
                    115: static int CGI_HEADER_LEN[H_TRANSFER_ENCODING+1] = {
                    116:      11, 19, 20, 20, 18, 15, 12, 14, 11, 12, 9, 11, 12, 15, 18,
                    117:      22, 13, 18, 13, 24, 15, 10, 20, 8, 22 
                    118: };
                    119: 
                    120: 
                    121: static const char *HTTP_HEADERS[H_TRANSFER_ENCODING+1] = {
                    122:     "Accept", "Accept-Charset",
                    123:     "Accept-Encoding",
                    124:     "Accept-Language", "Authorization",
                    125:     "Connection", "Content-Type",
                    126:     "Content-Length", "Cookie", "Cookie2",
                    127:     "Host", "Pragma",
                    128:     "Referer", "User-Agent",
                    129:     "Cache-Control",
                    130:     "If-Modified-Since", "If-Match",
                    131:     "If-None-Match",
                    132:     "If-Range",
                    133:     "If-Unmodified-Since",
                    134:     "Keep-Alive",
                    135:     "Range",
                    136:     "X-Forwarded-For",
                    137:     "Via",
                    138:     "Transfer-Encoding"
                    139: };
                    140: 
                    141: static int HTTP_HEADER_LEN[H_TRANSFER_ENCODING+1] = {
                    142:     6, 14, 15, 15, 13, 10, 12, 14, 6, 7, 4, 6, 7, 10, /* user-agent */
                    143:     13,17, 8, 13, 8, 19, 10, 5, 15, 3, 17
                    144: };
                    145:      
                    146: static void lsapi_sigpipe( int sig )
                    147: {
                    148: }
                    149: static void lsapi_siguser1( int sig )
                    150: {
                    151:     g_running = 0;
                    152: }
                    153: 
                    154: #ifndef sighandler_t
                    155: typedef void (*sighandler_t)(int);
                    156: #endif
                    157:           
                    158: static void lsapi_signal(int signo, sighandler_t handler)
                    159: {
                    160:     struct sigaction sa;
                    161: 
                    162:     sigaction(signo, NULL, &sa);
                    163: 
                    164:     if (sa.sa_handler == SIG_DFL) {
                    165:         sigemptyset(&sa.sa_mask);
                    166:         sa.sa_flags = 0;
                    167:         sa.sa_handler = handler;
                    168:         sigaction(signo, &sa, NULL);
                    169:     }
                    170: }
                    171: 
                    172: 
                    173: static inline void lsapi_buildPacketHeader( struct lsapi_packet_header * pHeader,
                    174:                                 char type, int len )
                    175: {
                    176:     pHeader->m_versionB0 = LSAPI_VERSION_B0;  /* LSAPI protocol version */
                    177:     pHeader->m_versionB1 = LSAPI_VERSION_B1;
                    178:     pHeader->m_type      = type;
                    179:     pHeader->m_flag      = LSAPI_ENDIAN;
                    180:     pHeader->m_packetLen.m_iLen = len;
                    181: }
                    182: 
                    183: static  int lsapi_set_nblock( int fd, int nonblock )
                    184: {
                    185:     int val = fcntl( fd, F_GETFL, 0 );
                    186:     if ( nonblock )
                    187:     {
                    188:         if (!( val & O_NONBLOCK ))
                    189:         {
                    190:             return fcntl( fd, F_SETFL, val | O_NONBLOCK );
                    191:         }
                    192:     }
                    193:     else
                    194:     {
                    195:         if ( val & O_NONBLOCK )
                    196:         {
                    197:             return fcntl( fd, F_SETFL, val &(~O_NONBLOCK) );
                    198:         }
                    199:     }
                    200:     return 0;
                    201: }
                    202: 
                    203: 
                    204: static int lsapi_close( int fd )
                    205: {
                    206:     int ret;
                    207:     while( 1 ) {
                    208:         ret = close( fd );
                    209:         if (( ret == -1 )&&( errno == EINTR )&&(g_running)) {
                    210:             continue;
                    211:         }
                    212:         return ret;
                    213:     }
                    214: }
                    215: 
                    216: static inline int lsapi_read( int fd, void * pBuf, int len )
                    217: {
                    218:     int ret;
                    219:     while( 1 ) {
                    220:         ret = read( fd, (char *)pBuf, len );
                    221:         if (( ret == -1 )&&( errno == EINTR )&&(g_running)) {
                    222:             continue;
                    223:         }
                    224:         return ret;
                    225:     }
                    226: }
                    227: 
                    228: 
                    229: static int lsapi_writev( int fd, struct iovec ** pVec, int count, int totalLen )
                    230: {
                    231:     int ret;
                    232:     int left = totalLen;
                    233:     int n = count;
                    234:     while(( left > 0 )&&g_running ) {
                    235:         ret = writev( fd, *pVec, n );
                    236:         if ( ret > 0 ) {
                    237:             left -= ret;
                    238:             if (( left <= 0)||( !g_running )) {
                    239:                 return totalLen - left;
                    240:             }
                    241:             while( ret > 0 ) {
                    242:                 if ( (*pVec)->iov_len <= ret ) {
                    243:                     ret -= (*pVec)->iov_len;
                    244:                     ++(*pVec);
                    245:                 } else {
                    246:                     (*pVec)->iov_base = (char *)(*pVec)->iov_base + ret;
                    247:                     (*pVec)->iov_len -= ret;
                    248:                     break;
                    249:                 }
                    250:             }
                    251:         } else if ( ret == -1 ) {
                    252:             if ( errno == EAGAIN ) {
                    253:                 if ( totalLen - left > 0 ) {
                    254:                     return totalLen - left;
                    255:                 } else {
                    256:                     return -1;
                    257:                 }
                    258:             } else {
                    259:                 if ( errno != EINTR ) {
                    260:                     return ret;
                    261:                 }
                    262:             }
                    263:         }
                    264:     }
                    265:     return totalLen - left;
                    266: }
                    267: 
                    268: static inline int allocateBuf( LSAPI_Request * pReq, int size )
                    269: {
                    270:     char * pBuf = (char *)realloc( pReq->m_pReqBuf, size );
                    271:     if ( pBuf ) {
                    272:         pReq->m_pReqBuf = pBuf;
                    273:         pReq->m_reqBufSize = size;
                    274:         pReq->m_pHeader = (struct lsapi_req_header *)pReq->m_pReqBuf;
                    275:         return 0;
                    276:     }
                    277:     return -1;
                    278: }
                    279: 
                    280: 
                    281: static int allocateIovec( LSAPI_Request * pReq, int n )
                    282: {
                    283:     struct iovec * p = (struct iovec *)realloc(
                    284:                 pReq->m_pIovec, sizeof(struct iovec) * n );
                    285:     if ( !p ) {
                    286:         return -1;
                    287:     }
                    288:     pReq->m_pIovecToWrite = p + ( pReq->m_pIovecToWrite - pReq->m_pIovec );
                    289:     pReq->m_pIovecCur = p + ( pReq->m_pIovecCur - pReq->m_pIovec );
                    290:     pReq->m_pIovec = p;
                    291:     pReq->m_pIovecEnd = p + n;
                    292:     return 0;
                    293: }
                    294: 
                    295: static int allocateRespHeaderBuf( LSAPI_Request * pReq, int size )
                    296: {
                    297:     char * p = (char *)realloc( pReq->m_pRespHeaderBuf, size );
                    298:     if ( !p ) {
                    299:         return -1;
                    300:     }
                    301:     pReq->m_pRespHeaderBufPos   = p + ( pReq->m_pRespHeaderBufPos - pReq->m_pRespHeaderBuf );
                    302:     pReq->m_pRespHeaderBuf      = p;
                    303:     pReq->m_pRespHeaderBufEnd   = p + size;
                    304:     return 0;
                    305: }
                    306: 
                    307: 
                    308: static inline int verifyHeader( struct lsapi_packet_header * pHeader, char pktType )
                    309: {
                    310:     if (( LSAPI_VERSION_B0 != pHeader->m_versionB0 )||
                    311:         ( LSAPI_VERSION_B1 != pHeader->m_versionB1 )||
                    312:         ( pktType != pHeader->m_type )) {
                    313:         return -1;
                    314:     }
                    315:     if ( LSAPI_ENDIAN != (pHeader->m_flag & LSAPI_ENDIAN_BIT )) {
                    316:         register char b;
                    317:         b = pHeader->m_packetLen.m_bytes[0];
                    318:         pHeader->m_packetLen.m_bytes[0] = pHeader->m_packetLen.m_bytes[3];
                    319:         pHeader->m_packetLen.m_bytes[3] = b;
                    320:         b = pHeader->m_packetLen.m_bytes[1];
                    321:         pHeader->m_packetLen.m_bytes[1] = pHeader->m_packetLen.m_bytes[2];
                    322:         pHeader->m_packetLen.m_bytes[2] = b;
                    323:     }
                    324:     return pHeader->m_packetLen.m_iLen;
                    325: }
                    326: 
                    327: static int allocateEnvList( struct LSAPI_key_value_pair ** pEnvList,
                    328:                         int *curSize, int newSize )
                    329: {
                    330:     struct LSAPI_key_value_pair * pBuf;
                    331:     if ( *curSize >= newSize ) {
                    332:         return 0;
                    333:     }
                    334:     if ( newSize > 8192 ) {
                    335:         return -1;
                    336:     }
                    337:     pBuf = (struct LSAPI_key_value_pair *)realloc( *pEnvList, newSize *
                    338:                     sizeof(struct LSAPI_key_value_pair) );
                    339:     if ( pBuf ) {
                    340:         *pEnvList = pBuf;
                    341:         *curSize  = newSize;
                    342:         return 0;
                    343:     } else {
                    344:         return -1;
                    345:     }
                    346: 
                    347: }
                    348: 
                    349: static inline int isPipe( int fd )
                    350: {
                    351:     char        achPeer[128];
                    352:     socklen_t   len = 128;
                    353:     if (( getpeername( fd, (struct sockaddr *)achPeer, &len ) != 0 )&&
                    354:         ( errno == ENOTCONN )) {
                    355:         return 0;
                    356:     } else {
                    357:         return 1;
                    358:     }
                    359: }
                    360: 
                    361: static int parseEnv( struct LSAPI_key_value_pair * pEnvList, int count,
                    362:             char **pBegin, char * pEnd )
                    363: {
                    364:     struct LSAPI_key_value_pair * pEnvEnd;
                    365:     int keyLen = 0, valLen = 0;
                    366:     if ( count > 8192 ) {
                    367:         return -1;
                    368:     }
                    369:     pEnvEnd = pEnvList + count;
                    370:     while( pEnvList != pEnvEnd ) {
                    371:         if ( pEnd - *pBegin < 4 ) {
                    372:             return -1;
                    373:         }
                    374:         keyLen = *((unsigned char *)((*pBegin)++));
                    375:         keyLen = (keyLen << 8) + *((unsigned char *)((*pBegin)++));
                    376:         valLen = *((unsigned char *)((*pBegin)++));
                    377:         valLen = (valLen << 8) + *((unsigned char *)((*pBegin)++));
                    378:         if ( *pBegin + keyLen + valLen > pEnd ) {
                    379:             return -1;
                    380:         }
                    381:         if (( !keyLen )||( !valLen )) {
                    382:             return -1;
                    383:         }
                    384: 
                    385:         pEnvList->pKey = *pBegin;
                    386:         *pBegin += keyLen;
                    387:         pEnvList->pValue = *pBegin;
                    388:         *pBegin += valLen;
                    389: 
                    390:         pEnvList->keyLen = keyLen - 1;
                    391:         pEnvList->valLen = valLen - 1;
                    392:         ++pEnvList;
                    393:     }
                    394:     if ( memcmp( *pBegin, "\0\0\0\0", 4 ) != 0 ) {
                    395:         return -1;
                    396:     }
                    397:     *pBegin += 4;
                    398:     return 0;
                    399: }
                    400: 
                    401: static inline void swapIntEndian( int * pInteger )
                    402: {
                    403:     char * p = (char *)pInteger;
                    404:     register char b;
                    405:     b = p[0];
                    406:     p[0] = p[3];
                    407:     p[3] = b;
                    408:     b = p[1];
                    409:     p[1] = p[2];
                    410:     p[2] = b;
                    411:     
                    412: }
                    413: 
                    414: static inline void fixEndian( LSAPI_Request * pReq )
                    415: {
                    416:     struct lsapi_req_header *p= pReq->m_pHeader;
                    417:     swapIntEndian( &p->m_httpHeaderLen );
                    418:     swapIntEndian( &p->m_reqBodyLen );
                    419:     swapIntEndian( &p->m_scriptFileOff );
                    420:     swapIntEndian( &p->m_scriptNameOff );
                    421:     swapIntEndian( &p->m_queryStringOff );
                    422:     swapIntEndian( &p->m_requestMethodOff );
                    423:     swapIntEndian( &p->m_cntUnknownHeaders );
                    424:     swapIntEndian( &p->m_cntEnv );
                    425:     swapIntEndian( &p->m_cntSpecialEnv );
                    426: }
                    427: 
                    428: static void fixHeaderIndexEndian( LSAPI_Request * pReq )
                    429: {
                    430:     int i;
                    431:     for( i = 0; i < H_TRANSFER_ENCODING; ++i ) {
                    432:         if ( pReq->m_pHeaderIndex->m_headerOff[i] ) {
                    433:             register char b;
                    434:             char * p = (char *)(&pReq->m_pHeaderIndex->m_headerLen[i]);
                    435:             b = p[0];
                    436:             p[0] = p[1];
                    437:             p[1] = b;
                    438:             swapIntEndian( &pReq->m_pHeaderIndex->m_headerOff[i] );
                    439:         }
                    440:     }
                    441:     if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) {
                    442:         struct lsapi_header_offset * pCur, *pEnd;
                    443:         pCur = pReq->m_pUnknownHeader;
                    444:         pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders;
                    445:         while( pCur < pEnd ) {
                    446:             swapIntEndian( &pCur->nameOff );
                    447:             swapIntEndian( &pCur->nameLen );
                    448:             swapIntEndian( &pCur->valueOff );
                    449:             swapIntEndian( &pCur->valueLen );
                    450:             ++pCur;
                    451:         }
                    452:     }    
                    453: }
                    454: 
                    455: static int parseRequest( LSAPI_Request * pReq, int totalLen )
                    456: {
                    457:     int shouldFixEndian;
                    458:     char * pBegin = pReq->m_pReqBuf + sizeof( struct lsapi_req_header );
                    459:     char * pEnd = pReq->m_pReqBuf + totalLen;
                    460:     shouldFixEndian = ( LSAPI_ENDIAN != (
                    461:                 pReq->m_pHeader->m_pktHeader.m_flag & LSAPI_ENDIAN_BIT ) );
                    462:     if ( shouldFixEndian ) {
                    463:         fixEndian( pReq );
                    464:     }
                    465:     if ( (pReq->m_specialEnvListSize < pReq->m_pHeader->m_cntSpecialEnv )&&
                    466:             allocateEnvList( &pReq->m_pSpecialEnvList,
                    467:                               &pReq->m_specialEnvListSize,
                    468:                              pReq->m_pHeader->m_cntSpecialEnv ) == -1 ) {
                    469:         return -1;
                    470:     }
                    471:     if ( (pReq->m_envListSize < pReq->m_pHeader->m_cntEnv )&&
                    472:             allocateEnvList( &pReq->m_pEnvList, &pReq->m_envListSize,
                    473:                              pReq->m_pHeader->m_cntEnv ) == -1 ) {
                    474:         return -1;
                    475:     }
                    476:     if ( parseEnv( pReq->m_pSpecialEnvList,
                    477:                    pReq->m_pHeader->m_cntSpecialEnv,
                    478:                    &pBegin, pEnd ) == -1 ) {
                    479:         return -1;
                    480:     }
                    481:     if ( parseEnv( pReq->m_pEnvList, pReq->m_pHeader->m_cntEnv,
                    482:                    &pBegin, pEnd ) == -1 ) {
                    483:         return -1;
                    484:     }
                    485:     pReq->m_pScriptFile     = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptFileOff;
                    486:     pReq->m_pScriptName     = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptNameOff;
                    487:     pReq->m_pQueryString    = pReq->m_pReqBuf + pReq->m_pHeader->m_queryStringOff;
                    488:     pReq->m_pRequestMethod  = pReq->m_pReqBuf + pReq->m_pHeader->m_requestMethodOff;
                    489:     
                    490:     pBegin = pReq->m_pReqBuf + (( pBegin - pReq->m_pReqBuf + 7 ) & (~0x7));
                    491:     pReq->m_pHeaderIndex = ( struct lsapi_http_header_index * )pBegin;
                    492:     pBegin += sizeof( struct lsapi_http_header_index );
                    493: 
                    494:     pReq->m_pUnknownHeader = (struct lsapi_header_offset *)pBegin;
                    495:     pBegin += sizeof( struct lsapi_header_offset) *
                    496:                     pReq->m_pHeader->m_cntUnknownHeaders;
                    497: 
                    498:     pReq->m_pHttpHeader = pBegin;
                    499:     pBegin += pReq->m_pHeader->m_httpHeaderLen;
                    500:     if ( pBegin != pEnd ) {
                    501:         return -1;
                    502:     }
                    503: 
                    504:     if ( shouldFixEndian ) {
                    505:         fixHeaderIndexEndian( pReq );
                    506:     }
                    507: 
                    508:     return 0;
                    509: }
                    510: 
                    511: static int s_accept_notify = 0;
                    512: 
                    513: static struct lsapi_packet_header ack = {'L', 'S',
                    514:                 LSAPI_REQ_RECEIVED, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} };
                    515: static inline int notify_req_received( int fd )
                    516: {
                    517:     if ( write( fd, &ack, LSAPI_PACKET_HEADER_LEN )
                    518:          < LSAPI_PACKET_HEADER_LEN ) {
                    519:         return -1;
                    520:     }
                    521:     return 0;
                    522: }
                    523: 
                    524: 
                    525: static int readReq( LSAPI_Request * pReq )
                    526: {
                    527:     int len;
                    528:     int packetLen;
                    529:     if ( !pReq ) {
                    530:         return -1;
                    531:     }
                    532:     if ( pReq->m_reqBufSize < 8192 ) {
                    533:         if ( allocateBuf( pReq, 8192 ) == -1 ) {
                    534:             return -1;
                    535:         }
                    536:     }
                    537: 
                    538:     while ( pReq->m_bufRead < LSAPI_PACKET_HEADER_LEN ) {
                    539:         len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf, pReq->m_reqBufSize );
                    540:         if ( len <= 0 ) {
                    541:             return -1;
                    542:         }
                    543:         pReq->m_bufRead += len;
                    544:     }
                    545:     pReq->m_reqState = LSAPI_ST_REQ_HEADER;
                    546: 
                    547:     packetLen = verifyHeader( &pReq->m_pHeader->m_pktHeader, LSAPI_BEGIN_REQUEST );
                    548:     if ( packetLen < 0 ) {
                    549:         return -1;
                    550:     }
                    551:     if ( packetLen > LSAPI_MAX_HEADER_LEN ) {
                    552:         return -1;
                    553:     }
                    554: 
                    555:     if ( packetLen + 1024 > pReq->m_reqBufSize ) {
                    556:         if ( allocateBuf( pReq, packetLen + 1024 ) == -1 ) {
                    557:             return -1;
                    558:         }
                    559:     }
                    560:     while( packetLen > pReq->m_bufRead ) {
                    561:         len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf + pReq->m_bufRead, packetLen - pReq->m_bufRead );
                    562:         if ( len <= 0 ) {
                    563:             return -1;
                    564:         }
                    565:         pReq->m_bufRead += len;
                    566:     }
                    567:     if ( parseRequest( pReq, packetLen ) < 0 ) {
                    568:         return -1;
                    569:     }
                    570:     pReq->m_bufProcessed = packetLen;
                    571:     pReq->m_reqState = LSAPI_ST_REQ_BODY | LSAPI_ST_RESP_HEADER;
                    572: 
                    573:     if ( !s_accept_notify )
                    574:         return notify_req_received( pReq->m_fd );
                    575:     else
                    576:         return 0;
                    577: }
                    578: 
                    579: 
                    580: 
                    581: int LSAPI_Init(void)
                    582: {
                    583:     if ( !g_inited ) {
                    584:         lsapi_signal(SIGPIPE, lsapi_sigpipe);
                    585:         lsapi_signal(SIGUSR1, lsapi_siguser1);
                    586: 
                    587: #if defined(SIGXFSZ) && defined(SIG_IGN)
                    588:         signal(SIGXFSZ, SIG_IGN);
                    589: #endif
                    590:         /* let STDOUT function as STDERR, 
                    591:            just in case writing to STDOUT directly */
                    592:         dup2( 2, 1 );
                    593: 
                    594:         if ( LSAPI_InitRequest( &g_req, LSAPI_SOCK_FILENO ) == -1 ) {
                    595:             return -1;
                    596:         }
                    597:         g_inited = 1;
                    598:         s_ppid = getppid();
                    599:     }
                    600:     return 0;
                    601: }
                    602: 
                    603: void LSAPI_Stop(void)
                    604: {
                    605:     g_running = 0;
                    606: }
                    607: 
                    608: int LSAPI_IsRunning(void)
                    609: {
                    610:     return g_running;
                    611: }
                    612: 
                    613: int LSAPI_InitRequest( LSAPI_Request * pReq, int fd )
                    614: {
                    615:     if ( !pReq ) {
                    616:         return -1;
                    617:     }
                    618:     memset( pReq, 0, sizeof( LSAPI_Request ) );
                    619:     if ( allocateIovec( pReq, 16 ) == -1 ) {
                    620:         return -1;
                    621:     }
                    622:     pReq->m_pRespBuf = pReq->m_pRespBufPos = (char *)malloc( LSAPI_RESP_BUF_SIZE );
                    623:     if ( !pReq->m_pRespBuf ) {
                    624:         return -1;
                    625:     }
                    626:     pReq->m_pRespBufEnd = pReq->m_pRespBuf + LSAPI_RESP_BUF_SIZE;
                    627:     pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec + 1;
                    628:     pReq->m_respPktHeaderEnd = &pReq->m_respPktHeader[5];
                    629:     if ( allocateRespHeaderBuf( pReq, LSAPI_INIT_RESP_HEADER_LEN ) == -1 ) {
                    630:         return -1;
                    631:     }
                    632:  
                    633:     if ( isPipe( fd ) ) {
                    634:         pReq->m_fdListen = -1;
                    635:         pReq->m_fd = fd;
                    636:     } else {
                    637:         pReq->m_fdListen = fd;
                    638:         pReq->m_fd = -1;
                    639:         lsapi_set_nblock( fd, 1 );
                    640:     }
                    641:     return 0;
                    642: }
                    643: 
                    644: int LSAPI_Is_Listen( void )
                    645: {
                    646:     return LSAPI_Is_Listen_r( &g_req );
                    647: }
                    648: 
                    649: int LSAPI_Is_Listen_r( LSAPI_Request * pReq)
                    650: {
                    651:     return pReq->m_fdListen != -1;
                    652: }
                    653: 
                    654: 
                    655: 
                    656: int LSAPI_Accept_r( LSAPI_Request * pReq )
                    657: {
                    658:     char        achPeer[128];
                    659:     socklen_t   len;
                    660:     int         nodelay = 1;
                    661:     
                    662:     if ( !pReq ) {
                    663:         return -1;
                    664:     }
                    665:     if ( LSAPI_Finish_r( pReq ) == -1 ) {
                    666:         return -1;
                    667:     }
                    668:     while( g_running ) {
                    669:         if ( pReq->m_fd == -1 ) {
                    670:             if ( pReq->m_fdListen != -1) {
                    671:                 len = sizeof( achPeer );
                    672:                 pReq->m_fd = accept( pReq->m_fdListen,
                    673:                             (struct sockaddr *)&achPeer, &len );
                    674:                 if ( pReq->m_fd == -1 ) {
                    675:                     if (( errno == EINTR )||( errno == EAGAIN)) {
                    676:                         continue;
                    677:                     } else {
                    678:                         return -1;
                    679:                     }
                    680:                 } else {
                    681:                     lsapi_set_nblock( pReq->m_fd , 0 );
                    682:                     if (((struct sockaddr *)&achPeer)->sa_family == AF_INET ) {    
                    683:                         setsockopt(pReq->m_fd, IPPROTO_TCP, TCP_NODELAY,
                    684:                                 (char *)&nodelay, sizeof(nodelay));
                    685:                     }
                    686: 
                    687:                     if ( s_accept_notify )
                    688:                         return notify_req_received( pReq->m_fd );
                    689: 
                    690:                 }
                    691:             } else {
                    692:                 return -1;
                    693:             }
                    694:         }
                    695:         if ( !readReq( pReq ) ) {
                    696:             break;
                    697:         }
                    698:         lsapi_close( pReq->m_fd );
                    699:         pReq->m_fd = -1;
                    700:         LSAPI_Reset_r( pReq );
                    701:     }
                    702:     return 0;
                    703: }
                    704: 
                    705: static struct lsapi_packet_header   finish = {'L', 'S',
                    706:                 LSAPI_RESP_END, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} };
                    707: 
                    708: int LSAPI_Finish_r( LSAPI_Request * pReq )
                    709: {
                    710:     /* finish req body */
                    711:     if ( !pReq ) {
                    712:         return -1;
                    713:     }
                    714:     if (pReq->m_reqState) {
                    715:         if ( pReq->m_fd != -1 ) {
                    716:             if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) {
                    717:                 LSAPI_FinalizeRespHeaders_r( pReq );
                    718:             }
                    719:             if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) {
                    720:                 Flush_RespBuf_r( pReq );
                    721:             }
                    722:             
                    723:             pReq->m_pIovecCur->iov_base = (void *)&finish;
                    724:             pReq->m_pIovecCur->iov_len  = LSAPI_PACKET_HEADER_LEN;
                    725:             pReq->m_totalLen += LSAPI_PACKET_HEADER_LEN;
                    726:             ++pReq->m_pIovecCur;
                    727:             LSAPI_Flush_r( pReq );
                    728:         }
                    729:         LSAPI_Reset_r( pReq );
                    730:     }
                    731:     return 0;
                    732: }
                    733: 
                    734: 
                    735: void LSAPI_Reset_r( LSAPI_Request * pReq )
                    736: {
                    737:     pReq->m_pRespBufPos         = pReq->m_pRespBuf;
                    738:     pReq->m_pIovecCur           = pReq->m_pIovecToWrite = pReq->m_pIovec + 1;
                    739:     pReq->m_pRespHeaderBufPos   = pReq->m_pRespHeaderBuf;
                    740:     
                    741:     memset( &pReq->m_pHeaderIndex, 0,
                    742:             (char *)(pReq->m_respHeaderLen) - (char *)&pReq->m_pHeaderIndex );
                    743: }
                    744: 
                    745: 
                    746: int LSAPI_Release_r( LSAPI_Request * pReq )
                    747: {
                    748:     if ( pReq->m_pReqBuf ) {
                    749:         free( pReq->m_pReqBuf );
                    750:     }
                    751:     if ( pReq->m_pSpecialEnvList ) {
                    752:         free( pReq->m_pSpecialEnvList );
                    753:     }
                    754:     if ( pReq->m_pEnvList ) {
                    755:         free( pReq->m_pEnvList );
                    756:     }
                    757:     if ( pReq->m_pRespHeaderBuf ) {
                    758:         free( pReq->m_pRespHeaderBuf );  
                    759:     }
                    760:     return 0;
                    761: }
                    762: 
                    763: 
                    764: char * LSAPI_GetHeader_r( LSAPI_Request * pReq, int headerIndex )
                    765: {
                    766:     int off;
                    767:     if ( !pReq || ((unsigned int)headerIndex > H_TRANSFER_ENCODING) ) {
                    768:         return NULL;
                    769:     }
                    770:     off = pReq->m_pHeaderIndex->m_headerOff[ headerIndex ];
                    771:     if ( !off ) {
                    772:         return NULL;
                    773:     }
                    774:     if ( *(pReq->m_pHttpHeader + off + 
                    775:            pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) ) {
                    776:         *( pReq->m_pHttpHeader + off + 
                    777:             pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) = 0;
                    778:     }
                    779:     return pReq->m_pHttpHeader + off;
                    780: }
                    781: 
                    782: static int readBodyToReqBuf( LSAPI_Request * pReq )
                    783: {
                    784:     int bodyLeft;
                    785:     int len = pReq->m_bufRead - pReq->m_bufProcessed;
                    786:     if ( len > 0 ) {
                    787:         return len;
                    788:     }
                    789:     pReq->m_bufRead = pReq->m_bufProcessed = pReq->m_pHeader->m_pktHeader.m_packetLen.m_iLen;
                    790: 
                    791:     bodyLeft = pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead;
                    792:     len = pReq->m_reqBufSize - pReq->m_bufRead;
                    793:     if ( len < 0 ) {
                    794:         return -1;
                    795:     }
                    796:     if ( len > bodyLeft ) {
                    797:         len = bodyLeft;
                    798:     }
                    799:     len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf + pReq->m_bufRead, len );
                    800:     if ( len > 0 ) {
                    801:         pReq->m_bufRead += len;
                    802:     }
                    803:     return len;
                    804: }
                    805: 
                    806: 
                    807: int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq )
                    808: {
                    809:     if (!pReq || (pReq->m_fd ==-1) ) {
                    810:         return EOF;
                    811:     }
                    812:     if ( pReq->m_bufProcessed >= pReq->m_bufRead ) {
                    813:         if ( readBodyToReqBuf( pReq ) <= 0 ) {
                    814:             return EOF;
                    815:         }
                    816:     }
                    817:     ++pReq->m_reqBodyRead;
                    818:     return (unsigned char)*(pReq->m_pReqBuf + pReq->m_bufProcessed++);
                    819: }
                    820: 
                    821: 
                    822: 
                    823: int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, int bufLen, int *getLF )
                    824: {
                    825:     int len;
                    826:     int left;
                    827:     char * pBufEnd = pBuf + bufLen - 1;
                    828:     char * pBufCur = pBuf;
                    829:     char * pCur;
                    830:     char * p;
                    831:     if (!pReq || (pReq->m_fd ==-1) ||( !pBuf )||(bufLen < 0 )|| !getLF ) {
                    832:         return -1;
                    833:     }
                    834:     *getLF = 0;
                    835:     while( (left = pBufEnd - pBufCur ) > 0 ) {
                    836:         
                    837:         len = pReq->m_bufRead - pReq->m_bufProcessed;
                    838:         if ( len <= 0 ) {
                    839:             if ( (len = readBodyToReqBuf( pReq )) <= 0 ) {
                    840:                 *getLF = 1;
                    841:                 break;
                    842:             }
                    843:         }
                    844:         if ( len > left ) {
                    845:             len = left;
                    846:         }
                    847:         pCur = pReq->m_pReqBuf + pReq->m_bufProcessed;
                    848:         p = memchr( pCur, '\n', len );
                    849:         if ( p ) {
                    850:             len = p - pCur + 1;
                    851:         }
                    852:         memmove( pBufCur, pCur, len );
                    853:         pBufCur += len;
                    854:         pReq->m_bufProcessed += len;
                    855: 
                    856:         pReq->m_reqBodyRead += len;
                    857:         
                    858:         if ( p ) {
                    859:             *getLF = 1;
                    860:             break;
                    861:         }
                    862:     }
                    863:     *pBufCur = 0;
                    864:   
                    865:     return pBufCur - pBuf;
                    866: }
                    867: 
                    868: 
                    869: int LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, int bufLen )
                    870: {
                    871:     int len;
                    872:     int total;
                    873:     /* char *pOldBuf = pBuf; */
                    874:     if (!pReq || (pReq->m_fd ==-1) || ( !pBuf )||(bufLen < 0 )) {
                    875:         return -1;
                    876:     }
                    877:     total = pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead;
                    878:     
                    879:     if ( total <= 0 ) {
                    880:         return 0;
                    881:     }
                    882:     if ( total < bufLen ) {
                    883:         bufLen = total;
                    884:     }
                    885: 
                    886:     total = 0;
                    887:     len = pReq->m_bufRead - pReq->m_bufProcessed;
                    888:     if ( len > 0 ) {
                    889:         if ( len > bufLen ) {
                    890:             len = bufLen;
                    891:         }
                    892:         memmove( pBuf, pReq->m_pReqBuf + pReq->m_bufProcessed, len );
                    893:         pReq->m_bufProcessed += len;
                    894:         total += len;
                    895:         pBuf += len;
                    896:         bufLen -= len;
                    897:     }
                    898:     while( bufLen > 0 ) {
                    899:         len = lsapi_read( pReq->m_fd, pBuf, bufLen );
                    900:         if ( len > 0 ) {
                    901:             total += len;
                    902:             pBuf += len;
                    903:             bufLen -= len;
                    904:         } else {
                    905:             if ( len <= 0 ) {
                    906:                 if ( !total) {
                    907:                     return -1;
                    908:                 }
                    909:                 break;
                    910:             }
                    911:         }
                    912:     }
                    913:     pReq->m_reqBodyRead += total;
                    914:     return total;
                    915:         
                    916: }
                    917: 
                    918: 
                    919: int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len )
                    920: {
                    921:     struct lsapi_packet_header * pHeader;
                    922:     const char * pEnd;
                    923:     const char * p;
                    924:     int bufLen;
                    925:     int toWrite;
                    926:     int packetLen;
                    927:     
                    928:     if ( !pReq || !pBuf || (pReq->m_fd == -1) ) {
                    929:         return -1;
                    930:     }
                    931:     if ( len < pReq->m_pRespBufEnd - pReq->m_pRespBufPos ) {
                    932:         memmove( pReq->m_pRespBufPos, pBuf, len );
                    933:         pReq->m_pRespBufPos += len;
                    934:         return len;
                    935:     }
                    936:     
                    937:     if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) {
                    938:         LSAPI_FinalizeRespHeaders_r( pReq );
                    939:     }
                    940:     pReq->m_reqState |= LSAPI_ST_RESP_BODY;
                    941:     
                    942:     pHeader = pReq->m_respPktHeader;
                    943:     p       = pBuf;
                    944:     pEnd    = pBuf + len;
                    945:     bufLen  = pReq->m_pRespBufPos - pReq->m_pRespBuf;
                    946:     
                    947:     while( ( toWrite = pEnd - p ) > 0 ) {
                    948:         packetLen = toWrite + bufLen;
                    949:         if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen) {
                    950:             packetLen = LSAPI_MAX_DATA_PACKET_LEN;
                    951:             toWrite = packetLen - bufLen;
                    952:         }
                    953:         
                    954:         lsapi_buildPacketHeader( pHeader, LSAPI_RESP_STREAM,
                    955:                             packetLen + LSAPI_PACKET_HEADER_LEN );
                    956:         pReq->m_totalLen += packetLen + LSAPI_PACKET_HEADER_LEN;
                    957: 
                    958:         pReq->m_pIovecCur->iov_base = (void *)pHeader;
                    959:         pReq->m_pIovecCur->iov_len  = LSAPI_PACKET_HEADER_LEN;
                    960:         ++pReq->m_pIovecCur;
                    961:         ++pHeader;
                    962:         if ( bufLen > 0 ) {
                    963:             pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespBuf;
                    964:             pReq->m_pIovecCur->iov_len  = bufLen;
                    965:             pReq->m_pRespBufPos = pReq->m_pRespBuf;
                    966:             ++pReq->m_pIovecCur;       
                    967:             bufLen = 0;
                    968:         }
                    969: 
                    970:         pReq->m_pIovecCur->iov_base = (void *)p;
                    971:         pReq->m_pIovecCur->iov_len  = toWrite;
                    972:         ++pReq->m_pIovecCur;
                    973:         p += toWrite;
                    974: 
                    975:         if ( pHeader >= pReq->m_respPktHeaderEnd - 1) {
                    976:             if ( LSAPI_Flush_r( pReq ) == -1 ) {
                    977:                 return -1;
                    978:             }
                    979:             pHeader = pReq->m_respPktHeader;
                    980:         }
                    981:     }
                    982:     if ( pHeader != pReq->m_respPktHeader ) {
                    983:         if ( LSAPI_Flush_r( pReq ) == -1 ) {
                    984:             return -1;
                    985:         }
                    986:     }
                    987:     return p - pBuf;
                    988: }
                    989: 
                    990: void Flush_RespBuf_r( LSAPI_Request * pReq )
                    991: {
                    992:     struct lsapi_packet_header * pHeader = pReq->m_respPktHeader;
                    993:     int bufLen = pReq->m_pRespBufPos - pReq->m_pRespBuf;
                    994:     pReq->m_reqState |= LSAPI_ST_RESP_BODY;
                    995:     lsapi_buildPacketHeader( pHeader, LSAPI_RESP_STREAM,
                    996:                         bufLen + LSAPI_PACKET_HEADER_LEN );
                    997:     pReq->m_totalLen += bufLen + LSAPI_PACKET_HEADER_LEN;
                    998: 
                    999:     pReq->m_pIovecCur->iov_base = (void *)pHeader;
                   1000:     pReq->m_pIovecCur->iov_len  = LSAPI_PACKET_HEADER_LEN;
                   1001:     ++pReq->m_pIovecCur;
                   1002:     ++pHeader;
                   1003:     if ( bufLen > 0 ) {
                   1004:         pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespBuf;
                   1005:         pReq->m_pIovecCur->iov_len  = bufLen;
                   1006:         pReq->m_pRespBufPos = pReq->m_pRespBuf;
                   1007:         ++pReq->m_pIovecCur;       
                   1008:         bufLen = 0;
                   1009:     }
                   1010: }
                   1011: 
                   1012: 
                   1013: 
                   1014: 
                   1015: int LSAPI_Flush_r( LSAPI_Request * pReq )
                   1016: {
                   1017:     int ret = 0;
                   1018:     int n;
                   1019:     if ( !pReq ) {
                   1020:         return -1;
                   1021:     }
                   1022:     n = pReq->m_pIovecCur - pReq->m_pIovecToWrite;
                   1023:     if (( 0 == n )&&( pReq->m_pRespBufPos == pReq->m_pRespBuf )) {
                   1024:         return 0;
                   1025:     }
                   1026:     if ( pReq->m_fd == -1 ) {
                   1027:         pReq->m_pRespBufPos = pReq->m_pRespBuf;
                   1028:         pReq->m_totalLen = 0;
                   1029:         pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec;
                   1030:         return -1;
                   1031:     }
                   1032:     if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) {
                   1033:         LSAPI_FinalizeRespHeaders_r( pReq );
                   1034:     }
                   1035:     if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) {
                   1036:         Flush_RespBuf_r( pReq );
                   1037:     }
                   1038:     
                   1039:     n = pReq->m_pIovecCur - pReq->m_pIovecToWrite;
                   1040:     if ( n > 0 ) {
                   1041:         
                   1042:         ret = lsapi_writev( pReq->m_fd, &pReq->m_pIovecToWrite,
                   1043:                   n, pReq->m_totalLen );
                   1044:         if ( ret < pReq->m_totalLen ) {
                   1045:             lsapi_close( pReq->m_fd );
                   1046:             pReq->m_fd = -1;
                   1047:             ret = -1;
                   1048:         }
                   1049:         pReq->m_totalLen = 0;
                   1050:         pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec;
                   1051:     }
                   1052:     return ret;
                   1053: }
                   1054: 
                   1055: 
                   1056: int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len )
                   1057: {
                   1058:     struct lsapi_packet_header header;
                   1059:     const char * pEnd;
                   1060:     const char * p;
                   1061:     int packetLen;
                   1062:     int totalLen;
                   1063:     int ret;
                   1064:     struct iovec iov[2];
                   1065:     struct iovec *pIov;
                   1066:     
                   1067:     if ( !pReq ) {
                   1068:         return -1;
                   1069:     }
                   1070:     if (( pReq->m_fd == -1 )||(pReq->m_fd == pReq->m_fdListen )) {
                   1071:         return write( 2, pBuf, len );
                   1072:     }
                   1073:     if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) {
                   1074:         LSAPI_Flush_r( pReq );
                   1075:     }
                   1076:     
                   1077:     p       = pBuf;
                   1078:     pEnd    = pBuf + len;
                   1079: 
                   1080:     while( ( packetLen = pEnd - p ) > 0 ) {
                   1081:         if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen) {
                   1082:             packetLen = LSAPI_MAX_DATA_PACKET_LEN;
                   1083:         }
                   1084: 
                   1085:         lsapi_buildPacketHeader( &header, LSAPI_STDERR_STREAM,
                   1086:                             packetLen + LSAPI_PACKET_HEADER_LEN );
                   1087:         totalLen = packetLen + LSAPI_PACKET_HEADER_LEN;
                   1088: 
                   1089:         iov[0].iov_base = (void *)&header;
                   1090:         iov[0].iov_len  = LSAPI_PACKET_HEADER_LEN;
                   1091: 
                   1092:         iov[1].iov_base = (void *)p;
                   1093:         iov[1].iov_len  = packetLen;
                   1094:         p += packetLen;
                   1095:         pIov = iov;
                   1096:         ret = lsapi_writev( pReq->m_fd, &pIov,
                   1097:                   2, totalLen );
                   1098:         if ( ret < totalLen ) {
                   1099:             lsapi_close( pReq->m_fd );
                   1100:             pReq->m_fd = -1;
                   1101:             ret = -1;
                   1102:         }
                   1103:     }
                   1104:     return p - pBuf;
                   1105: }
                   1106: 
                   1107: static char * GetHeaderVar( LSAPI_Request * pReq, const char * name )
                   1108: {
                   1109:     int i;
                   1110:     for( i = 0; i < H_TRANSFER_ENCODING; ++i ) {
                   1111:         if ( pReq->m_pHeaderIndex->m_headerOff[i] ) {
                   1112:             if ( strcmp( name, CGI_HEADERS[i] ) == 0 ) {
                   1113:                 return pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i];
                   1114:             }
                   1115:         }
                   1116:     }
                   1117:     if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) {
                   1118:         const char *p;
                   1119:         char *pKey;
                   1120:         char *pKeyEnd;
                   1121:         int  keyLen;
                   1122:         struct lsapi_header_offset * pCur, *pEnd;
                   1123:         pCur = pReq->m_pUnknownHeader;
                   1124:         pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders;
                   1125:         while( pCur < pEnd ) {
                   1126:             pKey = pReq->m_pHttpHeader + pCur->nameOff;
                   1127:             keyLen = pCur->nameLen;
                   1128:             pKeyEnd = pKey + keyLen;
                   1129:             p = &name[5];
                   1130: 
                   1131:             while(( pKey < pKeyEnd )&&( *p )) {
                   1132:                 char ch = toupper( *pKey );
                   1133:                 if ((ch != *p )||(( *p == '_' )&&( ch != '-'))) {
                   1134:                     break;
                   1135:                 }
                   1136:                 ++p; ++pKey;
                   1137:             }
                   1138:             if (( pKey == pKeyEnd )&& (!*p )) {
                   1139:                 return pReq->m_pHttpHeader + pCur->valueOff;
                   1140:             }
                   1141:             ++pCur;
                   1142:         }
                   1143:     }
                   1144:     return NULL;
                   1145: }
                   1146: 
                   1147: 
                   1148: char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name )
                   1149: {
                   1150:     struct LSAPI_key_value_pair * pBegin = pReq->m_pEnvList;
                   1151:     struct LSAPI_key_value_pair * pEnd = pBegin + pReq->m_pHeader->m_cntEnv;
                   1152:     if ( !pReq || !name ) {
                   1153:         return NULL;
                   1154:     }
                   1155:     if ( strncmp( name, "HTTP_", 5 ) == 0 ) {
                   1156:         return GetHeaderVar( pReq, name );
                   1157:     }
                   1158:     while( pBegin < pEnd ) {
                   1159:         if ( strcmp( name, pBegin->pKey ) == 0 ) {
                   1160:             return pBegin->pValue;
                   1161:         }
                   1162:         ++pBegin;
                   1163:     }
                   1164:     return NULL;
                   1165: }
                   1166: 
                   1167: int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq,
                   1168:             LSAPI_CB_EnvHandler fn, void * arg )
                   1169: {
                   1170:     int i;
                   1171:     int len = 0;
                   1172:     char * pValue;
                   1173:     int ret;
                   1174:     int count = 0;
                   1175:     if ( !pReq || !fn ) {
                   1176:         return -1;
                   1177:     }
                   1178:     for( i = 0; i < H_TRANSFER_ENCODING; ++i ) {
                   1179:         if ( pReq->m_pHeaderIndex->m_headerOff[i] ) {
                   1180:             len = pReq->m_pHeaderIndex->m_headerLen[i];
                   1181:             pValue = pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i];
                   1182:             *(pValue + len ) = 0;
                   1183:             ret = (*fn)( HTTP_HEADERS[i], HTTP_HEADER_LEN[i],
                   1184:                         pValue, len, arg );
                   1185:             ++count;
                   1186:             if ( ret <= 0 ) {
                   1187:                 return ret;
                   1188:             }
                   1189:         }
                   1190:     }
                   1191:     if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) {
                   1192:         char *pKey;
                   1193:         int  keyLen;
                   1194:         struct lsapi_header_offset * pCur, *pEnd;
                   1195:         pCur = pReq->m_pUnknownHeader;
                   1196:         pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders;
                   1197:         while( pCur < pEnd ) {
                   1198:             pKey = pReq->m_pHttpHeader + pCur->nameOff;
                   1199:             keyLen = pCur->nameLen;
                   1200: 
                   1201:             pValue = pReq->m_pHttpHeader + pCur->valueOff;
                   1202:             *(pValue + pCur->valueLen ) = 0;
                   1203:             ret = (*fn)( pKey, keyLen, 
                   1204:                         pValue, pCur->valueLen, arg );
                   1205:             if ( ret <= 0 ) {
                   1206:                 return ret;
                   1207:             }
                   1208:             ++pCur;
                   1209:         }
                   1210:     }
                   1211:     return count + pReq->m_pHeader->m_cntUnknownHeaders;
                   1212:     
                   1213: }
                   1214: 
                   1215: 
                   1216: int LSAPI_ForeachHeader_r( LSAPI_Request * pReq,
                   1217:             LSAPI_CB_EnvHandler fn, void * arg )
                   1218: {
                   1219:     int i;
                   1220:     int len = 0;
                   1221:     char * pValue;
                   1222:     int ret;
                   1223:     int count = 0;
                   1224:     if ( !pReq || !fn ) {
                   1225:         return -1;
                   1226:     }
                   1227:     for( i = 0; i < H_TRANSFER_ENCODING; ++i ) {
                   1228:         if ( pReq->m_pHeaderIndex->m_headerOff[i] ) {
                   1229:             len = pReq->m_pHeaderIndex->m_headerLen[i];
                   1230:             pValue = pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i];
                   1231:             *(pValue + len ) = 0;
                   1232:             ret = (*fn)( CGI_HEADERS[i], CGI_HEADER_LEN[i],
                   1233:                         pValue, len, arg );
                   1234:             ++count;
                   1235:             if ( ret <= 0 ) {
                   1236:                 return ret;
                   1237:             }
                   1238:         }
                   1239:     }
                   1240:     if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) {
                   1241:         char achHeaderName[256];
                   1242:         char *p;
                   1243:         char *pKey;
                   1244:         char *pKeyEnd ;
                   1245:         int  keyLen;
                   1246:         struct lsapi_header_offset * pCur, *pEnd;
                   1247:         pCur = pReq->m_pUnknownHeader;
                   1248:         pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders;
                   1249:         while( pCur < pEnd ) {
                   1250:             pKey = pReq->m_pHttpHeader + pCur->nameOff;
                   1251:             keyLen = pCur->nameLen;
                   1252:             if ( keyLen > 250 ) {
                   1253:                 keyLen = 250;
                   1254:             }
                   1255: 
                   1256:             pKeyEnd = pKey + keyLen;
                   1257:             memcpy( achHeaderName, "HTTP_", 5 );
                   1258:             p = &achHeaderName[5];
                   1259: 
                   1260:             while( pKey < pKeyEnd ) {
                   1261:                 char ch = *pKey++;
                   1262:                 if ( ch == '-' ) {
                   1263:                     *p++ = '_';
                   1264:                 } else {
                   1265:                     *p++ = toupper( ch );
                   1266:                 }
                   1267:             }
                   1268:             *p = 0;
                   1269:             keyLen += 5;
                   1270: 
                   1271:             pValue = pReq->m_pHttpHeader + pCur->valueOff;
                   1272:             *(pValue + pCur->valueLen ) = 0;
                   1273:             ret = (*fn)( achHeaderName, keyLen, 
                   1274:                         pValue, pCur->valueLen, arg );
                   1275:             if ( ret <= 0 ) {
                   1276:                 return ret;
                   1277:             }
                   1278:             ++pCur;
                   1279:         }
                   1280:     }
                   1281:     return count + pReq->m_pHeader->m_cntUnknownHeaders;
                   1282:     
                   1283: }
                   1284: 
                   1285: static int EnvForeach( struct LSAPI_key_value_pair * pEnv,
                   1286:             int n, LSAPI_CB_EnvHandler fn, void * arg )
                   1287: {
                   1288:     struct LSAPI_key_value_pair * pEnd = pEnv + n;
                   1289:     int ret;
                   1290:     if ( !pEnv || !fn ) {
                   1291:         return -1;
                   1292:     }
                   1293:     while( pEnv < pEnd ) {
                   1294:         ret = (*fn)( pEnv->pKey, pEnv->keyLen,
                   1295:                     pEnv->pValue, pEnv->valLen, arg );
                   1296:         if ( ret <= 0 ) {
                   1297:             return ret;
                   1298:         }
                   1299:         ++pEnv;
                   1300:     }
                   1301:     return n;
                   1302: }
                   1303: 
                   1304: 
                   1305: 
                   1306: int LSAPI_ForeachEnv_r( LSAPI_Request * pReq,
                   1307:             LSAPI_CB_EnvHandler fn, void * arg )
                   1308: {
                   1309:     if ( !pReq || !fn ) {
                   1310:         return -1;
                   1311:     }
                   1312:     if ( pReq->m_pHeader->m_cntEnv > 0 ) {
                   1313:         return EnvForeach( pReq->m_pEnvList, pReq->m_pHeader->m_cntEnv,
                   1314:                     fn, arg );
                   1315:     }
                   1316:     return 0;
                   1317: }
                   1318: 
                   1319: 
                   1320: 
                   1321: int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq,
                   1322:             LSAPI_CB_EnvHandler fn, void * arg )
                   1323: {
                   1324:     if ( !pReq || !fn ) {
                   1325:         return -1;
                   1326:     }
                   1327:     if ( pReq->m_pHeader->m_cntSpecialEnv > 0 ) {
                   1328:         return EnvForeach( pReq->m_pSpecialEnvList,
                   1329:                 pReq->m_pHeader->m_cntSpecialEnv,
                   1330:                     fn, arg );
                   1331:     }
                   1332:     return 0;
                   1333: 
                   1334: }
                   1335: 
                   1336: 
                   1337: 
                   1338: int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq )
                   1339: {
                   1340:     if ( !pReq || !pReq->m_pIovec ) {
                   1341:         return -1;
                   1342:     }
                   1343:     if ( !( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) ) {
                   1344:         return 0;
                   1345:     }
                   1346:     pReq->m_reqState &= ~LSAPI_ST_RESP_HEADER;
                   1347:     if ( pReq->m_pRespHeaderBufPos > pReq->m_pRespHeaderBuf ) {
                   1348:         pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespHeaderBuf;
                   1349:         pReq->m_pIovecCur->iov_len  = pReq->m_pRespHeaderBufPos - pReq->m_pRespHeaderBuf;
                   1350:         pReq->m_totalLen += pReq->m_pIovecCur->iov_len;
                   1351:         ++pReq->m_pIovecCur;
                   1352:     }
                   1353:     
                   1354:     pReq->m_pIovec->iov_len  = sizeof( struct lsapi_resp_header)
                   1355:             + pReq->m_respHeader.m_respInfo.m_cntHeaders * sizeof( short );
                   1356:     pReq->m_totalLen += pReq->m_pIovec->iov_len;
                   1357: 
                   1358:     lsapi_buildPacketHeader( &pReq->m_respHeader.m_pktHeader,
                   1359:                     LSAPI_RESP_HEADER, pReq->m_totalLen  );
                   1360:     pReq->m_pIovec->iov_base = (void *)&pReq->m_respHeader;
                   1361:     pReq->m_pIovecToWrite = pReq->m_pIovec;
                   1362:     return 0;
                   1363: }
                   1364: 
                   1365: 
                   1366: 
                   1367: 
                   1368: int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, char * pBuf, int len )
                   1369: {
                   1370:     if ( !pReq || !pBuf || len <= 0 || len > LSAPI_RESP_HTTP_HEADER_MAX ) {
                   1371:         return -1;
                   1372:     }
                   1373:     if ( pReq->m_reqState & LSAPI_ST_RESP_BODY ) {
                   1374:         return -1;
                   1375:     }
                   1376:     if ( pReq->m_respHeader.m_respInfo.m_cntHeaders >= LSAPI_MAX_RESP_HEADERS ) {
                   1377:         return -1;
                   1378:     }
                   1379:     if ( pReq->m_pRespHeaderBufPos + len + 1 > pReq->m_pRespHeaderBufEnd ) {
                   1380:         int newlen = pReq->m_pRespHeaderBufPos + len + 4096 - pReq->m_pRespHeaderBuf;
                   1381:         newlen -= newlen % 4096;
                   1382:         if ( allocateRespHeaderBuf( pReq, newlen ) == -1 ) {
                   1383:             return -1;
                   1384:         }
                   1385:     }
                   1386:     memmove( pReq->m_pRespHeaderBufPos, pBuf, len );
                   1387:     pReq->m_pRespHeaderBufPos += len;
                   1388:     *pReq->m_pRespHeaderBufPos++ = 0;
                   1389:     ++len;  /* add one byte padding for \0 */
                   1390:     pReq->m_respHeaderLen[pReq->m_respHeader.m_respInfo.m_cntHeaders] = len;
                   1391:     ++pReq->m_respHeader.m_respInfo.m_cntHeaders;
                   1392:     return 0;
                   1393: }
                   1394: 
                   1395: 
                   1396: int LSAPI_CreateListenSock2( const struct sockaddr * pServerAddr, int backlog )
                   1397: {
                   1398:     int ret;
                   1399:     int fd;
                   1400:     int flag = 1;
                   1401:     int addr_len;
                   1402: 
                   1403:     switch( pServerAddr->sa_family ) {
                   1404:     case AF_INET:
                   1405:         addr_len = 16;
                   1406:         break;
                   1407:     case AF_INET6:
                   1408:         addr_len = sizeof( struct sockaddr_in6 );
                   1409:         break;
                   1410:     case AF_UNIX:
                   1411:         addr_len = sizeof( struct sockaddr_un );
                   1412:         unlink( ((struct sockaddr_un *)pServerAddr)->sun_path );
                   1413:         break;
                   1414:     default:
                   1415:         return -1;
                   1416:     }
                   1417: 
                   1418:     fd = socket( pServerAddr->sa_family, SOCK_STREAM, 0 );
                   1419:     if ( fd == -1 ) {
                   1420:         return -1;
                   1421:     }
                   1422: 
                   1423:     fcntl( fd, F_SETFD, FD_CLOEXEC );
                   1424: 
                   1425:     if(setsockopt( fd, SOL_SOCKET, SO_REUSEADDR,
                   1426:                 (char *)( &flag ), sizeof(flag)) == 0) {
                   1427:         ret = bind( fd, pServerAddr, addr_len );
                   1428:         if ( !ret ) {
                   1429:             ret = listen( fd, backlog );
                   1430:             if ( !ret ) {
                   1431:                 return fd;
                   1432:             }
                   1433:         }
                   1434:     }
                   1435: 
                   1436:     ret = errno;
                   1437:     close(fd);
                   1438:     errno = ret;
                   1439:     return -1;
                   1440: 
                   1441: }
                   1442: 
                   1443: int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr )
                   1444: {
                   1445:     char achAddr[256];
                   1446:     char * p = achAddr;
                   1447:     char * pEnd;
                   1448:     struct addrinfo *res, hints;
                   1449:     int  doAddrInfo = 0;
                   1450:     int port;
                   1451:     
                   1452:     if ( !pBind ) {
                   1453:         return -1;
                   1454:     }
                   1455: 
                   1456:     while( isspace( *pBind ) ) {
                   1457:         ++pBind;
                   1458:     }
                   1459: 
                   1460:     strncpy( achAddr, pBind, 256 );
                   1461: 
                   1462:     switch( *p ) {
                   1463:     case '/':
                   1464:         pAddr->sa_family = AF_UNIX;
                   1465:         strncpy( ((struct sockaddr_un *)pAddr)->sun_path, p,
                   1466:                 sizeof(((struct sockaddr_un *)pAddr)->sun_path) );
                   1467:         return 0;
                   1468: 
                   1469:     case '[':
                   1470:         pAddr->sa_family = AF_INET6;
                   1471:         ++p;
                   1472:         pEnd = strchr( p, ']' );
                   1473:         if ( !pEnd )
                   1474:             return -1;
                   1475:         *pEnd++ = 0;
                   1476:         
                   1477:         if ( *p == '*' ) {
                   1478:             strcpy( achAddr, "::" );
                   1479:             p = achAddr;
                   1480:         }
                   1481:         doAddrInfo = 1;
                   1482:         break;
                   1483: 
                   1484:     default:
                   1485:         pAddr->sa_family = AF_INET;
                   1486:         pEnd = strchr( p, ':' );
                   1487:         if ( !pEnd ) {
                   1488:             return -1;
                   1489:         }
                   1490:         *pEnd++ = 0;
                   1491:         
                   1492:         doAddrInfo = 0;
                   1493:         if ( *p == '*' ) {
                   1494:             ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = htonl(INADDR_ANY);
                   1495:         } else {
                   1496:             if (!strcasecmp( p, "localhost" ) ) {
                   1497:                 ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = htonl( INADDR_LOOPBACK );
                   1498:             } else  {
                   1499:                 ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = inet_addr( p );
                   1500:                 if ( ((struct sockaddr_in *)pAddr)->sin_addr.s_addr == INADDR_BROADCAST) {
                   1501:                     doAddrInfo = 1;
                   1502:                 }
                   1503:             }
                   1504:         }
                   1505:         break;
                   1506:     }
                   1507:     if ( *pEnd == ':' ) {
                   1508:         ++pEnd;
                   1509:     }
                   1510:         
                   1511:     port = atoi( pEnd );
                   1512:     if (( port <= 0 )||( port > 65535 )) {
                   1513:         return -1;
                   1514:     }
                   1515:     if ( doAddrInfo ) {
                   1516: 
                   1517:         memset(&hints, 0, sizeof(hints));
                   1518: 
                   1519:         hints.ai_family   = pAddr->sa_family;
                   1520:         hints.ai_socktype = SOCK_STREAM;
                   1521:         hints.ai_protocol = IPPROTO_TCP;
                   1522: 
                   1523:         if ( getaddrinfo(p, NULL, &hints, &res) ) {
                   1524:             return -1;
                   1525:         }
                   1526: 
                   1527:         memcpy(pAddr, res->ai_addr, res->ai_addrlen);
                   1528:         freeaddrinfo(res);
                   1529:     }
                   1530:     
                   1531:     if ( pAddr->sa_family == AF_INET ) {
                   1532:         ((struct sockaddr_in *)pAddr)->sin_port = htons( port );
                   1533:     } else {
                   1534:         ((struct sockaddr_in6 *)pAddr)->sin6_port = htons( port );
                   1535:     }
                   1536:     return 0;
                   1537:     
                   1538: }
                   1539: 
                   1540: int LSAPI_CreateListenSock( const char * pBind, int backlog )
                   1541: {
                   1542:     char serverAddr[128];
                   1543:     int ret;
                   1544:     int fd = -1;
                   1545:     ret = LSAPI_ParseSockAddr( pBind, (struct sockaddr *)serverAddr );
                   1546:     if ( !ret ) {
                   1547:         fd = LSAPI_CreateListenSock2( (struct sockaddr *)serverAddr, backlog );
                   1548:     }
                   1549:     return fd;
                   1550: }
                   1551: 
                   1552: static fn_select_t g_fnSelect = select;
                   1553: 
                   1554: typedef struct _lsapi_child_status
                   1555: {
                   1556:     int     m_pid;
                   1557: 
                   1558:     volatile short   m_iKillSent;
                   1559:     volatile short   m_inProcess;
                   1560: 
                   1561:     volatile long    m_tmWaitBegin;
                   1562:     volatile long    m_tmReqBegin;
                   1563:     volatile long    m_tmLastCheckPoint;
                   1564: }
                   1565: lsapi_child_status;
                   1566: 
                   1567: static lsapi_child_status * s_pChildStatus = NULL;
                   1568: 
                   1569: typedef struct _lsapi_prefork_server
                   1570: {
                   1571:     int m_fd;
                   1572:     int m_iMaxChildren;
                   1573:     int m_iExtraChildren;
                   1574:     int m_iCurChildren;
                   1575:     int m_iMaxIdleChildren;
                   1576:     int m_iServerMaxIdle;
                   1577:     int m_iChildrenMaxIdleTime;
                   1578:     int m_iMaxReqProcessTime;
                   1579:     int m_iAvoidFork;
                   1580:     
                   1581:     lsapi_child_status * m_pChildrenStatus;
                   1582:     
                   1583: }lsapi_prefork_server;
                   1584: 
                   1585: static lsapi_prefork_server * g_prefork_server = NULL;
                   1586: 
                   1587: int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork )
                   1588: {
                   1589:     if ( g_prefork_server ) {
                   1590:         return 0;
                   1591:     }
                   1592:     if ( max_children <= 1 ) {
                   1593:         return -1;
                   1594:     }
                   1595:     if ( max_children >= 10000) {
                   1596:         max_children = 10000;
                   1597:     }
                   1598: 
                   1599:     
                   1600:     g_prefork_server = (lsapi_prefork_server *)malloc( sizeof( lsapi_prefork_server ) );
                   1601:     if ( !g_prefork_server ) {
                   1602:         return -1;
                   1603:     }
                   1604:     memset( g_prefork_server, 0, sizeof( lsapi_prefork_server ) );
                   1605: 
                   1606:     if ( fp != NULL ) {
                   1607:         g_fnSelect = fp;
                   1608:     }
                   1609: 
                   1610:     s_ppid = getppid();
                   1611:     g_prefork_server->m_iAvoidFork = avoidFork;
                   1612:     g_prefork_server->m_iMaxChildren = max_children;
                   1613:     
                   1614:     g_prefork_server->m_iExtraChildren = ( avoidFork ) ? 0 : (max_children / 3) ;
                   1615:     g_prefork_server->m_iMaxIdleChildren = ( avoidFork ) ? (max_children + 1) : (max_children / 3);
                   1616:     g_prefork_server->m_iChildrenMaxIdleTime = 300;
                   1617:     g_prefork_server->m_iMaxReqProcessTime = 300;
                   1618:     return 0;    
                   1619: }
                   1620: 
                   1621: void LSAPI_Set_Server_fd( int fd )
                   1622: {
                   1623:     if( g_prefork_server ) {
                   1624:         g_prefork_server->m_fd = fd;
                   1625:     }
                   1626: }
                   1627: 
                   1628: 
                   1629: static int lsapi_accept( int fdListen )
                   1630: {
                   1631:     int         fd;
                   1632:     int         nodelay = 1;
                   1633:     socklen_t   len;
                   1634:     char        achPeer[128];
                   1635: 
                   1636:     len = sizeof( achPeer );
                   1637:     fd = accept( fdListen, (struct sockaddr *)&achPeer, &len );
                   1638:     if ( fd != -1 ) {
                   1639:         if (((struct sockaddr *)&achPeer)->sa_family == AF_INET ) {
                   1640:             setsockopt( fd, IPPROTO_TCP, TCP_NODELAY,
                   1641:                     (char *)&nodelay, sizeof(nodelay));
                   1642:         }
                   1643: 
                   1644:         if ( s_accept_notify )
                   1645:             notify_req_received( fd );
                   1646:     }
                   1647:     return fd;
                   1648: 
                   1649: }
                   1650: 
                   1651: 
                   1652: 
                   1653: 
                   1654: static int s_req_processed = 0;
                   1655: static int s_max_reqs = 10000;
                   1656: static int s_max_idle_secs = 300;
                   1657: 
                   1658: static int s_stop;
                   1659: 
                   1660: static void lsapi_cleanup(int signal)
                   1661: {
                   1662:     s_stop = signal;
                   1663: }
                   1664: 
                   1665: static lsapi_child_status * find_child_status( int pid )
                   1666: {
                   1667:     lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus;
                   1668:     lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatus + g_prefork_server->m_iMaxChildren * 2;
                   1669:     while( pStatus < pEnd ) {
                   1670:         if ( pStatus->m_pid == pid ) {
                   1671:             return pStatus;
                   1672:         }
                   1673:         ++pStatus;
                   1674:     }
                   1675:     return NULL;
                   1676: }
                   1677: 
                   1678: 
                   1679: 
                   1680: static void lsapi_sigchild( int signal )
                   1681: {
                   1682:     int status, pid;
                   1683:     lsapi_child_status * child_status;
                   1684:     while( 1 ) {
                   1685:         pid = waitpid( -1, &status, WNOHANG|WUNTRACED );
                   1686:         if ( pid <= 0 ) {
                   1687:             break;
                   1688:         }
                   1689:         child_status = find_child_status( pid );
                   1690:         if ( child_status ) {
                   1691:             child_status->m_pid = 0;
                   1692:         }
                   1693:         --g_prefork_server->m_iCurChildren;
                   1694:     }
                   1695: 
                   1696: }
                   1697: 
                   1698: static int lsapi_init_children_status()
                   1699: {
                   1700:     int size = 4096;
                   1701:     
                   1702:     char * pBuf;
                   1703:     size = g_prefork_server->m_iMaxChildren * sizeof( lsapi_child_status ) * 2;
                   1704:     size = (size + 4095 ) / 4096 * 4096;
                   1705:     pBuf =( char*) mmap( NULL, size, PROT_READ | PROT_WRITE,
                   1706:         MAP_ANON | MAP_SHARED, -1, 0 );
                   1707:     if ( pBuf == MAP_FAILED ) {
                   1708:         perror( "Anonymous mmap() failed" );
                   1709:         return -1;
                   1710:     }
                   1711:     memset( pBuf, 0, size );
                   1712:     g_prefork_server->m_pChildrenStatus = (lsapi_child_status *)pBuf;    
                   1713:     return 0;
                   1714: }
                   1715: 
                   1716: static void lsapi_check_child_status( long tmCur )
                   1717: {
                   1718:     int idle = 0;
                   1719:     int tobekilled;
                   1720:     int dying = 0;
                   1721:     lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus;
                   1722:     lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatus + g_prefork_server->m_iMaxChildren * 2;
                   1723:     while( pStatus < pEnd ) {
                   1724:         tobekilled = pStatus->m_iKillSent;
                   1725:         if ( pStatus->m_pid != 0 ) {
                   1726:             if ( !tobekilled ) {
                   1727:                 if ( !pStatus->m_inProcess ) {
                   1728:                     
                   1729:                     if (( g_prefork_server->m_iCurChildren - dying > g_prefork_server->m_iMaxChildren)||
                   1730:                         ( idle >= g_prefork_server->m_iMaxIdleChildren )) {
                   1731:                     
                   1732:                         tobekilled = 1;
                   1733:                     } else {
                   1734:                         if (( s_max_idle_secs> 0)&&(tmCur - pStatus->m_tmWaitBegin > s_max_idle_secs + 5 )) {
                   1735:                             tobekilled = 1;
                   1736:                         }
                   1737:                     }
                   1738:                     if ( !tobekilled ) {
                   1739:                         ++idle;
                   1740:                     }
                   1741:                 } else {
                   1742:                     if ( tmCur - pStatus->m_tmReqBegin > 
                   1743:                          g_prefork_server->m_iMaxReqProcessTime ) {
                   1744:                         tobekilled = 1;
                   1745:                     }
                   1746:                 }
                   1747:             } else {
                   1748:                 if ( pStatus->m_inProcess ) {
                   1749:                     tobekilled = pStatus->m_iKillSent = 0;
                   1750:                 }
                   1751:             }
                   1752:             if ( tobekilled ) {
                   1753:                 tobekilled = 0;
                   1754:                 if ( pStatus->m_iKillSent > 5 ) {
                   1755:                     tobekilled = SIGKILL;
                   1756:                 } else {    
                   1757:                     if ( pStatus->m_iKillSent == 3 ) {
                   1758:                         tobekilled = SIGTERM;
                   1759:                     } else {
                   1760:                         if ( pStatus->m_iKillSent == 1 ) {
                   1761:                             tobekilled = SIGUSR1;
                   1762:                         }
                   1763:                     }
                   1764:                 }
                   1765:                 if ( tobekilled ) {
                   1766:                     kill( pStatus->m_pid, tobekilled );
                   1767:                 }
                   1768:                 ++pStatus->m_iKillSent;
                   1769:                 ++dying;
                   1770:             }
                   1771:                 
                   1772:         } else {
                   1773:             ++dying;
                   1774:         }
                   1775:         ++pStatus;
                   1776:     }
                   1777: }
                   1778: 
                   1779: static int lsapi_all_children_must_die()
                   1780: {
                   1781:     int maxWait;
                   1782:     int sec =0;
                   1783:     g_prefork_server->m_iMaxReqProcessTime = 10;
                   1784:     g_prefork_server->m_iMaxIdleChildren = -1;
                   1785:     maxWait = 15;
                   1786: 
                   1787:     while( g_prefork_server->m_iCurChildren && (sec < maxWait) ) {
                   1788:         lsapi_check_child_status(time(NULL));
                   1789:         sleep( 1 );
                   1790:         sec++;
                   1791:     }
                   1792:     if ( g_prefork_server->m_iCurChildren != 0 ) {
                   1793:         kill( -getpgrp(), SIGKILL );
                   1794:     }
                   1795:     return 0;
                   1796: }
                   1797: 
                   1798: 
                   1799: 
                   1800: static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Request * pReq )
                   1801: {
                   1802:     struct sigaction act, old_term, old_quit, old_int,
                   1803:                     old_usr1, old_child;
                   1804:     lsapi_child_status * child_status;
                   1805:     int             wait_secs = 0;
                   1806:     int             ret = 0;
                   1807:     int             pid;
                   1808:     time_t          lastTime = 0;
                   1809:     time_t          curTime = 0;
                   1810:     fd_set          readfds;
                   1811:     struct timeval  timeout;
                   1812: 
                   1813:     lsapi_init_children_status();
                   1814:     
                   1815:     setsid();
                   1816: 
                   1817:     act.sa_flags = 0;
                   1818:     act.sa_handler = lsapi_sigchild;
                   1819:     if( sigaction( SIGCHLD, &act, &old_child ) ) {
                   1820:         perror( "Can't set signal handler for SIGCHILD" );
                   1821:         return -1;
                   1822:     }
                   1823: 
                   1824:     /* Set up handler to kill children upon exit */
                   1825:     act.sa_flags = 0;
                   1826:     act.sa_handler = lsapi_cleanup;
                   1827:     if( sigaction( SIGTERM, &act, &old_term ) ||
                   1828:         sigaction( SIGINT,  &act, &old_int  ) ||
                   1829:         sigaction( SIGUSR1, &act, &old_usr1 ) ||
                   1830:         sigaction( SIGQUIT, &act, &old_quit )) {
                   1831:         perror( "Can't set signals" );
                   1832:         return -1;
                   1833:     }
                   1834:     s_stop = 0;
                   1835:     while( !s_stop ) {
                   1836:         if ( ret ) {
                   1837:             curTime = time( NULL );
                   1838:         } else {
                   1839:             ++curTime;
                   1840:         }
                   1841:         if (curTime != lastTime ) {
                   1842:             lastTime = curTime;
                   1843:             if (s_ppid && (getppid() != s_ppid )) {
                   1844:                 break;
                   1845:             }
                   1846:             lsapi_check_child_status(curTime );
                   1847:             if (pServer->m_iServerMaxIdle) {
                   1848:                 if ( pServer->m_iCurChildren <= 0 ) {
                   1849:                     ++wait_secs;
                   1850:                     if ( wait_secs > pServer->m_iServerMaxIdle ) {
                   1851:                         return -1;
                   1852:                     }
                   1853:                 } else {
                   1854:                     wait_secs = 0;
                   1855:                 }
                   1856:             }
                   1857:         }
                   1858: 
                   1859:         if ( pServer->m_iCurChildren >= (pServer->m_iMaxChildren + pServer->m_iExtraChildren ) ) {
                   1860:             usleep( 100000 );
                   1861:             continue;
                   1862:         }
                   1863: 
                   1864:         FD_ZERO( &readfds );
                   1865:         FD_SET( pServer->m_fd, &readfds );
                   1866:         timeout.tv_sec = 1; timeout.tv_usec = 0;
                   1867:         if ((ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout)) == 1 ) {
                   1868:             if ( pServer->m_iCurChildren >= 0 ) {
                   1869:                 usleep( 10 );
                   1870:                 FD_ZERO( &readfds );
                   1871:                 FD_SET( pServer->m_fd, &readfds );
                   1872:                 timeout.tv_sec = 0; timeout.tv_usec = 0;
                   1873:                 if ( (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout) == 0 ) {
                   1874:                     continue;
                   1875:                 }
                   1876:             }
                   1877:         } else {
                   1878:             if ( ret == -1 ) {
                   1879:                 if ( errno == EINTR ) {
                   1880:                     continue;
                   1881:                 }
                   1882:                 /* perror( "select()" ); */
                   1883:                 break;
                   1884:             } else {
                   1885:                 continue;
                   1886:             }
                   1887:         }
                   1888: 
                   1889:         pReq->m_fd = lsapi_accept( pServer->m_fd );
                   1890:         if ( pReq->m_fd != -1 ) {
                   1891:             child_status = find_child_status( 0 );
                   1892:             pid = fork();
                   1893:             if ( !pid ) {
                   1894:                 g_prefork_server = NULL;
                   1895:                 s_ppid = getppid();
                   1896:                 s_req_processed = 0;
                   1897:                 s_pChildStatus = child_status;
                   1898:                 child_status->m_iKillSent = 0;
                   1899:                 lsapi_set_nblock( pReq->m_fd, 0 );
                   1900: 
                   1901:                 /* don't catch our signals */
                   1902:                 sigaction( SIGCHLD, &old_child, 0 );
                   1903:                 sigaction( SIGTERM, &old_term, 0 );
                   1904:                 sigaction( SIGQUIT, &old_quit, 0 );
                   1905:                 sigaction( SIGINT,  &old_int,  0 );
                   1906:                 sigaction( SIGUSR1, &old_usr1, 0 );
                   1907:                 return 0;
                   1908:             } else {
                   1909:                 if ( pid == -1 ) {
                   1910:                     perror( "fork() failed, please increase process limit" );
                   1911:                 } else {
                   1912:                     ++pServer->m_iCurChildren;
                   1913:                     if ( child_status ) {
                   1914:                         child_status->m_pid = pid;
                   1915:                         child_status->m_iKillSent = 0;
                   1916:                         child_status->m_tmWaitBegin = time(NULL);
                   1917:                     }
                   1918:                 }
                   1919:             }
                   1920:             close( pReq->m_fd );
                   1921:             pReq->m_fd = -1;
                   1922: 
                   1923:         } else {
                   1924:             if (( errno == EINTR )||( errno == EAGAIN)) {
                   1925:                 continue;
                   1926:             }
                   1927:             perror( "accept() failed" );
                   1928:             return -1;
                   1929:         }
                   1930:     }
                   1931:     sigaction( SIGUSR1, &old_usr1, 0 );
                   1932:     kill( -getpgrp(), SIGUSR1 );
                   1933:     lsapi_all_children_must_die();  /* Sorry, children ;-) */
                   1934:     return -1;
                   1935: 
                   1936: }
                   1937: 
                   1938: int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
                   1939: {
                   1940:     int             fd;
                   1941:     int             ret;
                   1942:     int             wait_secs;
                   1943:     fd_set          readfds;
                   1944:     struct timeval  timeout;
                   1945: 
                   1946:     LSAPI_Finish_r( pReq );
                   1947: 
                   1948: 
                   1949:     if ( g_prefork_server ) {
                   1950:         if ( g_prefork_server->m_fd != -1 ) {
                   1951:             if ( lsapi_prefork_server_accept( g_prefork_server, pReq ) == -1 ) {
                   1952:                 return -1;
                   1953:             }
                   1954:         }
                   1955:     }
                   1956:     if ( s_req_processed >= s_max_reqs ) {
                   1957:         return -1;
                   1958:     }
                   1959: 
                   1960:     if ( s_pChildStatus ) {
                   1961:         s_pChildStatus->m_tmWaitBegin = time( NULL );
                   1962:     }
                   1963:     
                   1964:     while( g_running ) {
                   1965:         if ( pReq->m_fd != -1 ) {
                   1966:             fd = pReq->m_fd;
                   1967:         } else {
                   1968:             if ( pReq->m_fdListen != -1 ) {
                   1969:                 fd = pReq->m_fdListen;
                   1970:             } else {
                   1971:                 return -1;
                   1972:             }
                   1973:         }
                   1974:         wait_secs = 0;
                   1975:         while( 1 ) {
                   1976:             if ( !g_running ) {
                   1977:                 return -1;
                   1978:             }
                   1979:             if (( s_pChildStatus )&&( s_pChildStatus->m_iKillSent )) {
                   1980:                 return -1; 
                   1981:             }
                   1982:             FD_ZERO( &readfds );
                   1983:             FD_SET( fd, &readfds );
                   1984:             timeout.tv_sec = 1;
                   1985:             timeout.tv_usec = 0;
                   1986:             ret = (*g_fnSelect)(fd+1, &readfds, NULL, NULL, &timeout);
                   1987:             if ( ret == 0 ) {
                   1988:                 if ( s_pChildStatus ) {
                   1989:                     s_pChildStatus->m_inProcess = 0;
                   1990:                 }
                   1991:                 ++wait_secs;
                   1992:                 if (( s_max_idle_secs > 0 )&&(wait_secs >= s_max_idle_secs )) {
                   1993:                     return -1;
                   1994:                 }
                   1995:                 if ( s_ppid &&( getppid() != s_ppid)) {
                   1996:                     return -1;
                   1997:                 }
                   1998:             } else {
                   1999:                 if ( ret == -1 ) {
                   2000:                     if ( errno == EINTR ) {
                   2001:                         continue;
                   2002:                     } else {
                   2003:                         return -1;
                   2004:                     }
                   2005:                 } else {
                   2006:                     if ( ret >= 1 ) {
                   2007:                         if (( s_pChildStatus )&&( s_pChildStatus->m_iKillSent )) {
                   2008:                             return -1; 
                   2009:                         }
                   2010:                         if ( fd == pReq->m_fdListen ) {
                   2011:                             pReq->m_fd = lsapi_accept( pReq->m_fdListen );
                   2012:                             if ( pReq->m_fd != -1 ) {
                   2013:                                 fd = pReq->m_fd;
                   2014:                                 lsapi_set_nblock( fd, 0 );
                   2015:                             } else {
                   2016:                                 if (( errno == EINTR )||( errno == EAGAIN)) {
                   2017:                                     continue;
                   2018:                                                                }
                   2019:                                 return -1;
                   2020:                             }
                   2021:                         } else {
                   2022:                             break;
                   2023:                         }
                   2024:                     }
                   2025:                 }
                   2026:             }
                   2027:         }
                   2028:         if ( !readReq( pReq ) ) {
                   2029:             if ( s_pChildStatus ) {
                   2030:                 s_pChildStatus->m_inProcess = 1;
                   2031:                 s_pChildStatus->m_tmReqBegin = s_pChildStatus->m_tmLastCheckPoint = time(NULL);
                   2032:             }
                   2033:             ++s_req_processed;
                   2034:             return 0;
                   2035:         }
                   2036:         lsapi_close( pReq->m_fd );
                   2037:         pReq->m_fd = -1;
                   2038:         LSAPI_Reset_r( pReq );
                   2039:     }
                   2040:     return -1;
                   2041:     
                   2042: }
                   2043: 
                   2044: void LSAPI_Set_Max_Reqs( int reqs )
                   2045: {   
                   2046:     s_max_reqs = reqs;          
                   2047: }
                   2048: 
                   2049: void LSAPI_Set_Max_Idle( int secs )
                   2050: {   
                   2051:     s_max_idle_secs = secs;     
                   2052: }
                   2053: 
                   2054: void LSAPI_Set_Max_Children( int maxChildren )
                   2055: {
                   2056:     if ( g_prefork_server ) {
                   2057:         g_prefork_server->m_iMaxChildren = maxChildren;
                   2058:     }
                   2059: }
                   2060: 
                   2061: void LSAPI_Set_Extra_Children( int extraChildren )
                   2062: {
                   2063:     if (( g_prefork_server )&&( extraChildren >= 0 )) {
                   2064:         g_prefork_server->m_iExtraChildren = extraChildren;
                   2065:     }
                   2066: }
                   2067: 
                   2068: void LSAPI_Set_Max_Process_Time( int secs )
                   2069: {
                   2070:     if (( g_prefork_server )&&( secs > 0 )) {
                   2071:         g_prefork_server->m_iMaxReqProcessTime = secs;
                   2072:     }
                   2073: }
                   2074: 
                   2075: 
                   2076: void LSAPI_Set_Max_Idle_Children( int maxIdleChld )
                   2077: {
                   2078:     if (( g_prefork_server )&&( maxIdleChld > 0 )) {
                   2079:         g_prefork_server->m_iMaxIdleChildren = maxIdleChld;
                   2080:     }
                   2081: }
                   2082: 
                   2083: void LSAPI_Set_Server_Max_Idle_Secs( int serverMaxIdle )
                   2084: {
                   2085:     if ( g_prefork_server ) {
                   2086:         g_prefork_server->m_iServerMaxIdle = serverMaxIdle;
                   2087:     }
                   2088: }
                   2089: 
                   2090: void LSAPI_Set_Slow_Req_Msecs( int msecs )
                   2091: {
                   2092:        s_slow_req_msecs = msecs;
                   2093: }
                   2094: 
                   2095: int  LSAPI_Get_Slow_Req_Msecs()
                   2096: {
                   2097:        return s_slow_req_msecs;
                   2098: }
                   2099: 
                   2100: void LSAPI_No_Check_ppid()
                   2101: {
                   2102:     s_ppid = 0;
                   2103: }
                   2104: 
                   2105: #if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
                   2106: #include <crt_externs.h>
                   2107: #else
                   2108: extern char ** environ;
                   2109: #endif
                   2110: static void unset_lsapi_envs()
                   2111: {
                   2112:     char **env;
                   2113: #if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
                   2114:     env = *_NSGetEnviron();
                   2115: #else
                   2116:     env = environ;
                   2117: #endif
                   2118:     while( env != NULL && *env != NULL ) {
                   2119:         if ( !strncmp(*env, "LSAPI_", 6) || 
                   2120:              !strncmp( *env, "PHP_LSAPI_", 10 ) ) {   
                   2121:             char ** del = env;
                   2122:             do {
                   2123:                 *del = del[1];
                   2124:             } while( *del++ );
                   2125:         } else {
                   2126:             ++env;
                   2127:         }
                   2128:     }  
                   2129: }
                   2130: 
                   2131: void LSAPI_Init_Env_Parameters( fn_select_t fp )
                   2132: {
                   2133:     const char *p;
                   2134:     int n;
                   2135:     int avoidFork = 0;
                   2136:     p = getenv( "PHP_LSAPI_MAX_REQUESTS" );
                   2137:     if ( !p ) {
                   2138:         p = getenv( "LSAPI_MAX_REQS" );
                   2139:     }
                   2140:     if ( p ) {
                   2141:         n = atoi( p );
                   2142:         if ( n > 0 ) {
                   2143:             LSAPI_Set_Max_Reqs( n );
                   2144:         }
                   2145:     }
                   2146: 
                   2147:     p = getenv( "LSAPI_AVOID_FORK" );
                   2148:     if ( p ) {
                   2149:         avoidFork = atoi( p );
                   2150:     }    
                   2151: 
                   2152:     p = getenv( "LSAPI_ACCEPT_NOTIFY" );
                   2153:     if ( p ) {
                   2154:         s_accept_notify = atoi( p );
                   2155:     }    
                   2156: 
                   2157:     p = getenv( "LSAPI_SLOW_REQ_MSECS" );
                   2158:     if ( p ) {
                   2159:         n = atoi( p );
                   2160:         LSAPI_Set_Slow_Req_Msecs( n );
                   2161:     }    
                   2162: 
                   2163: 
                   2164: #if defined( RLIMIT_CORE )
                   2165:     p = getenv( "LSAPI_ALLOW_CORE_DUMP" );
                   2166:     if ( !p ) {
                   2167:         struct rlimit limit = { 0, 0 };
                   2168:         setrlimit( RLIMIT_CORE, &limit );
                   2169:     }
                   2170: #endif    
                   2171: 
                   2172:     p = getenv( "LSAPI_MAX_IDLE" );
                   2173:     if ( p ) {
                   2174:         n = atoi( p );
                   2175:         LSAPI_Set_Max_Idle( n );
                   2176:     }
                   2177: 
                   2178:     if ( LSAPI_Is_Listen() ) {
                   2179:         n = 0;
                   2180:         p = getenv( "PHP_LSAPI_CHILDREN" );
                   2181:         if ( !p ) {
                   2182:             p = getenv( "LSAPI_CHILDREN" );
                   2183:         }
                   2184:         if ( p ) {
                   2185:             n = atoi( p );
                   2186:         }
                   2187:         if ( n > 1 ) {
                   2188:             LSAPI_Init_Prefork_Server( n, fp, avoidFork );
                   2189:             LSAPI_Set_Server_fd( g_req.m_fdListen );
                   2190:         }
                   2191: 
                   2192:         p = getenv( "LSAPI_EXTRA_CHILDREN" );
                   2193:         if ( p ) {
                   2194:             LSAPI_Set_Extra_Children( atoi( p ) );
                   2195:         }
                   2196:         
                   2197:         p = getenv( "LSAPI_MAX_IDLE_CHILDREN" );
                   2198:         if ( p ) {
                   2199:             LSAPI_Set_Max_Idle_Children( atoi( p ) );
                   2200:         }
                   2201:         p = getenv( "LSAPI_PGRP_MAX_IDLE" );
                   2202:         if ( p ) {
                   2203:             LSAPI_Set_Server_Max_Idle_Secs( atoi( p ) );
                   2204:         }
                   2205:         
                   2206:         p = getenv( "LSAPI_MAX_PROCESS_TIME" );
                   2207:         if ( p ) {     
                   2208:             LSAPI_Set_Max_Process_Time( atoi( p ) );
                   2209:         }
                   2210:         if ( getenv( "LSAPI_PPID_NO_CHECK" ) ) {
                   2211:             LSAPI_No_Check_ppid();
                   2212:         }
                   2213:     }
                   2214:     unset_lsapi_envs();
                   2215: }
                   2216: 
                   2217: 
                   2218: /*
                   2219:  * Local variables:
                   2220:  * tab-width: 4
                   2221:  * c-basic-offset: 4
                   2222:  * End:
                   2223:  * vim600: sw=4 ts=4 fdm=marker
                   2224:  * vim<600: sw=4 ts=4
                   2225:  */
                   2226: 
                   2227: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>