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

📄 os_win32.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            {                struct timeval tv;                fd_set rfds;                int sock = fdTable[fd].fid.sock;                int rv;                char trash[1024];                FD_ZERO(&rfds);                do                {#pragma warning( disable : 4127 )                FD_SET((unsigned) sock, &rfds);#pragma warning( default : 4127 )                tv.tv_sec = 2;                tv.tv_usec = 0;                rv = select(sock + 1, &rfds, NULL, NULL, &tv);                }                while (rv > 0 && recv(sock, trash, sizeof(trash), 0) > 0);            }        }        closesocket(fdTable[fd].fid.sock);        break;    default:        ret = -1;       /* fake failure */    }    Win32FreeDescriptor(fd);    return ret;}/* *-------------------------------------------------------------- * * OS_CloseRead -- * *	Cancel outstanding asynchronous reads and prevent subsequent *      reads from completing. * * Results: *	Socket or file is shutdown. Return values mimic Unix shutdown: *		0 success, -1 failure * *-------------------------------------------------------------- */int OS_CloseRead(int fd){    int ret = 0;    /*     * Catch it if fd is a bogus value     */    ASSERT((fd >= 0) && (fd < WIN32_OPEN_MAX));    ASSERT(fdTable[fd].type == FD_SOCKET_ASYNC	|| fdTable[fd].type == FD_SOCKET_SYNC);    if (shutdown(fdTable[fd].fid.sock,SD_RECEIVE) == SOCKET_ERROR)	ret = -1;    return ret;}/* *-------------------------------------------------------------- * * OS_DoIo -- * *	This function was formerly OS_Select.  It's purpose is *      to pull I/O completion events off the queue and dispatch *      them to the appropriate place. * * Results: *	Returns 0. * * Side effects: *	Handlers are called. * *-------------------------------------------------------------- */int OS_DoIo(struct timeval *tmo){    unsigned long fd;    unsigned long bytes;    POVERLAPPED_REQUEST pOv;    struct timeb tb;    int ms;    int ms_last;    int err;    /* XXX     * We can loop in here, but not too long, as wait handlers     * must run.     * For cgi stdin, apparently select returns when io completion     * ports don't, so don't wait the full timeout.     */    if(tmo)	ms = (tmo->tv_sec*1000 + tmo->tv_usec/1000) / 2;    else	ms = 1000;    ftime(&tb);    ms_last = tb.time*1000 + tb.millitm;    while (ms >= 0) {	if(tmo && (ms = tmo->tv_sec*1000 + tmo->tv_usec/1000)> 100)	    ms = 100;	if (!GetQueuedCompletionStatus(hIoCompPort, &bytes, &fd,	    (LPOVERLAPPED *)&pOv, ms) && !pOv) {	    err = WSAGetLastError();	    return 0; /* timeout */        }	ASSERT((fd >= 0) && (fd < WIN32_OPEN_MAX));	/* call callback if descriptor still valid */	ASSERT(pOv);	if(pOv->instance == fdTable[fd].instance)	  (*pOv->procPtr)(pOv->clientData, bytes);	free(pOv);	ftime(&tb);	ms -= (tb.time*1000 + tb.millitm - ms_last);	ms_last = tb.time*1000 + tb.millitm;    }    return 0;}static int isAddrOK(struct sockaddr_in * inet_sockaddr, const char * okAddrs){    static const char *token = " ,;:\t";    char *ipaddr;    char *p;    if (okAddrs == NULL) return TRUE;    ipaddr = inet_ntoa(inet_sockaddr->sin_addr);    p = strstr(okAddrs, ipaddr);    if (p == NULL) return FALSE;    if (p == okAddrs)    {        p += strlen(ipaddr);        return (strchr(token, *p) != NULL);    }    if (strchr(token, *--p) != NULL)    {        p += strlen(ipaddr) + 1;        return (strchr(token, *p) != NULL);    }    return FALSE;}#ifndef NO_WSAACEPTstatic int CALLBACK isAddrOKCallback(LPWSABUF  lpCallerId,                                     LPWSABUF  dc0,                                     LPQOS     dc1,                                     LPQOS     dc2,                                     LPWSABUF  dc3,                                     LPWSABUF  dc4,                                     GROUP     *dc5,                                     DWORD     data){    struct sockaddr_in *sockaddr = (struct sockaddr_in *) lpCallerId->buf;    // Touch the args to avoid warnings    dc0 = NULL; dc1 = NULL; dc2 = NULL; dc3 = NULL; dc4 = NULL; dc5 = NULL;    if ((void *) data == NULL) return CF_ACCEPT;    if (sockaddr->sin_family != AF_INET) return CF_ACCEPT;    return isAddrOK(sockaddr, (const char *) data) ? CF_ACCEPT : CF_REJECT;}#endifstatic void printLastError(const char * text){    LPVOID buf;    FormatMessage(         FORMAT_MESSAGE_ALLOCATE_BUFFER |         FORMAT_MESSAGE_FROM_SYSTEM |         FORMAT_MESSAGE_IGNORE_INSERTS,        NULL,        GetLastError(),        0,        (LPTSTR) &buf,        0,        NULL     );        fprintf(stderr, "%s: %s\n", text, (LPCTSTR) buf);    LocalFree(buf);}static int acceptNamedPipe(){    int ipcFd = -1;    if (! ConnectNamedPipe(hListen, NULL))    {        switch (GetLastError())        {            case ERROR_PIPE_CONNECTED:                // A client connected after CreateNamedPipe but                // before ConnectNamedPipe. Its a good connection.                break;                    case ERROR_IO_PENDING:                // The NamedPipe was opened with an Overlapped structure                // and there is a pending io operation.  mod_fastcgi                 // did this in 2.2.12 (fcgi_pm.c v1.52).            case ERROR_PIPE_LISTENING:                // The pipe handle is in nonblocking mode.            case ERROR_NO_DATA:                // The previous client closed its handle (and we failed                // to call DisconnectNamedPipe)            default:                printLastError("unexpected ConnectNamedPipe() error");        }    }	ipcFd = Win32NewDescriptor(FD_PIPE_SYNC, (int) hListen, -1);	if (ipcFd == -1) 	{		DisconnectNamedPipe(hListen);	}    return ipcFd;}static int acceptSocket(const char *webServerAddrs){    SOCKET hSock;    int ipcFd = -1;    for (;;)    {        struct sockaddr sockaddr;        int sockaddrLen = sizeof(sockaddr);        for (;;)        {            const struct timeval timeout = {1, 0};            fd_set readfds;            FD_ZERO(&readfds);#pragma warning( disable : 4127 )             FD_SET((unsigned int) hListen, &readfds);#pragma warning( default : 4127 )             if (select(0, &readfds, NULL, NULL, &timeout) == 0)            {                if (shutdownPending)                 {                    OS_LibShutdown();                    return -1;                }            }            else             {                break;            }        }    #if NO_WSAACEPT        hSock = accept((SOCKET) hListen, &sockaddr, &sockaddrLen);        if (hSock == INVALID_SOCKET)        {            break;        }        if (isAddrOK((struct sockaddr_in *) &sockaddr, webServerAddrs))        {            break;        }        closesocket(hSock);#else        hSock = WSAAccept((unsigned int) hListen,                                              &sockaddr,                            &sockaddrLen,                                         isAddrOKCallback,                            (DWORD) webServerAddrs);        if (hSock != INVALID_SOCKET)        {            break;        }                if (WSAGetLastError() != WSAECONNREFUSED)        {            break;        }#endif    }    if (hSock == INVALID_SOCKET)     {        /* Use FormatMessage() */        fprintf(stderr, "accept()/WSAAccept() failed: %d", WSAGetLastError());        return -1;    }        ipcFd = Win32NewDescriptor(FD_SOCKET_SYNC, hSock, -1);	if (ipcFd == -1)     {	    closesocket(hSock);	}    return ipcFd;}/* *---------------------------------------------------------------------- * * OS_Accept -- * *  Accepts a new FastCGI connection.  This routine knows whether *  we're dealing with TCP based sockets or NT Named Pipes for IPC. * *  fail_on_intr is ignored in the Win lib. * * Results: *      -1 if the operation fails, otherwise this is a valid IPC fd. * *---------------------------------------------------------------------- */int OS_Accept(int listen_sock, int fail_on_intr, const char *webServerAddrs){    int ipcFd = -1;    // Touch args to prevent warnings    listen_sock = 0; fail_on_intr = 0;    // @todo Muliple listen sockets and sockets other than 0 are not    // supported due to the use of globals.    if (shutdownPending)     {        OS_LibShutdown();        return -1;    }    // The mutex is to keep other processes (and threads, when supported)    // from going into the accept cycle.  The accept cycle needs to    // periodically break out to check the state of the shutdown flag    // and there's no point to having more than one thread do that.        if (acceptMutex != INVALID_HANDLE_VALUE)     {		DWORD ret;#if YOU_WANT_TO_MAKE_THE_PROCESS_HANG_AFTER_FIRST_REQUEST        while ((ret = WaitForSingleObject(acceptMutex, ACCEPT_TIMEOUT)) == WAIT_TIMEOUT)         {			if (shutdownPending) break;		}		if (ret == WAIT_FAILED) {#else        if (WaitForSingleObject(acceptMutex, INFINITE) == WAIT_FAILED) {#endif            printLastError("WaitForSingleObject() failed");            return -1;        }    }        if (shutdownPending)     {        OS_LibShutdown();    }    else if (listenType == FD_PIPE_SYNC)     {        ipcFd = acceptNamedPipe();    }    else if (listenType == FD_SOCKET_SYNC)    {        ipcFd = acceptSocket(webServerAddrs);    }    else    {        fprintf(stderr, "unknown listenType (%d)\n", listenType);    }	        if (acceptMutex != INVALID_HANDLE_VALUE)     {        ReleaseMutex(acceptMutex);    }    return ipcFd;}/* *---------------------------------------------------------------------- * * OS_IpcClose * *	OS IPC routine to close an IPC connection. * * Results: * * * Side effects: *      IPC connection is closed. * *---------------------------------------------------------------------- */int OS_IpcClose(int ipcFd, int shutdown){    if (ipcFd == -1) return 0;    /*     * Catch it if fd is a bogus value     */    ASSERT((ipcFd >= 0) && (ipcFd < WIN32_OPEN_MAX));    ASSERT(fdTable[ipcFd].type != FD_UNUSED);    switch (listenType)    {    case FD_PIPE_SYNC:        /*         * Make sure that the client (ie. a Web Server in this case) has         * read all data from the pipe before we disconnect.         */        if (! FlushFileBuffers(fdTable[ipcFd].fid.fileHandle)) return -1;        if (! DisconnectNamedPipe(fdTable[ipcFd].fid.fileHandle)) return -1;		OS_StopImpersonation();        /* fall through */    case FD_SOCKET_SYNC:        OS_Close(ipcFd, shutdown);        break;    case FD_UNUSED:    default:        return -1;        break;    }    return 0;}/* *---------------------------------------------------------------------- * * OS_IsFcgi -- * *	Determines whether this process is a FastCGI process or not. * * Results: *      Returns 1 if FastCGI, 0 if not. * * Side effects: *      None. * *---------------------------------------------------------------------- */int OS_IsFcgi(int sock){    // Touch args to prevent warnings    sock = 0;    /* XXX This is broken for sock */	return (listenType != FD_UNUSED); }/* *---------------------------------------------------------------------- * * OS_SetFlags -- * *      Sets selected flag bits in an open file descriptor.  Currently *      this is only to put a SOCKET into non-blocking mode. * *---------------------------------------------------------------------- */void OS_SetFlags(int fd, int flags){    unsigned long pLong = 1L;    if (fdTable[fd].type == FD_SOCKET_SYNC && flags == O_NONBLOCK) {        if (ioctlsocket(fdTable[fd].fid.sock, FIONBIO, &pLong) ==	        SOCKET_ERROR) {	    //exit(WSAGetLastError());			SetLastError(WSAGetLastError());			return;        }        if (!CreateIoCompletionPort((HANDLE)fdTable[fd].fid.sock,				    hIoCompPort, fd, 1)) {	    //err = GetLastError();	    //exit(err);			return;	}        fdTable[fd].type = FD_SOCKET_ASYNC;    }    return;}

⌨️ 快捷键说明

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