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

📄 os_unix.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		FD_SET(fd, &readFdSetPost);		FD_CLR(fd, &readFdSet);	    }            if(FD_ISSET(fd, &writeFdSetCpy)) {	        numWrPosted++;	        FD_SET(fd, &writeFdSetPost);		FD_CLR(fd, &writeFdSet);	    }        }    }    if(numRdPosted == 0 && numWrPosted == 0)        return 0;    for(fd = 0; fd <= maxFd; fd++) {        /*	 * Do reads and dispatch callback.	 */        if(FD_ISSET(fd, &readFdSetPost)	   && asyncIoTable[AIO_RD_IX(fd)].inUse) {	    numRdPosted--;	    FD_CLR(fd, &readFdSetPost);	    aioPtr = &asyncIoTable[AIO_RD_IX(fd)];	    len = read(aioPtr->fd, aioPtr->buf, aioPtr->len);	    procPtr = aioPtr->procPtr;	    aioPtr->procPtr = NULL;	    clientData = aioPtr->clientData;	    aioPtr->inUse = 0;	    (*procPtr)(clientData, len);	}        /*	 * Do writes and dispatch callback.	 */        if(FD_ISSET(fd, &writeFdSetPost) &&           asyncIoTable[AIO_WR_IX(fd)].inUse) {	    numWrPosted--;	    FD_CLR(fd, &writeFdSetPost);	    aioPtr = &asyncIoTable[AIO_WR_IX(fd)];	    len = write(aioPtr->fd, aioPtr->buf, aioPtr->len);	    procPtr = aioPtr->procPtr;	    aioPtr->procPtr = NULL;	    clientData = aioPtr->clientData;	    aioPtr->inUse = 0;	    (*procPtr)(clientData, len);	}    }    return 0;}/*  * Not all systems have strdup().   * @@@ autoconf should determine whether or not this is needed, but for now.. */static char * str_dup(const char * str){    char * sdup = (char *) malloc(strlen(str) + 1);    if (sdup)        strcpy(sdup, str);    return sdup;}/* *---------------------------------------------------------------------- * * ClientAddrOK -- * *      Checks if a client address is in a list of allowed addresses * * Results: *	TRUE if address list is empty or client address is present *      in the list, FALSE otherwise. * *---------------------------------------------------------------------- */static int ClientAddrOK(struct sockaddr_in *saPtr, const char *clientList){    int result = FALSE;    char *clientListCopy, *cur, *next;    if (clientList == NULL || *clientList == '\0') {        return TRUE;    }    clientListCopy = str_dup(clientList);    for (cur = clientListCopy; cur != NULL; cur = next) {        next = strchr(cur, ',');        if (next != NULL) {            *next++ = '\0';        }        if (inet_addr(cur) == saPtr->sin_addr.s_addr) {            result = TRUE;            break;        }    }    free(clientListCopy);    return result;}/* *---------------------------------------------------------------------- * * AcquireLock -- * *      On platforms that implement concurrent calls to accept *      on a shared listening ipcFd, returns 0.  On other platforms, *	acquires an exclusive lock across all processes sharing a *      listening ipcFd, blocking until the lock has been acquired. * * Results: *      0 for successful call, -1 in case of system error (fatal). * * Side effects: *      This process now has the exclusive lock. * *---------------------------------------------------------------------- */static int AcquireLock(int sock, int fail_on_intr){#ifdef USE_LOCKING    do {        struct flock lock;        lock.l_type = F_WRLCK;        lock.l_start = 0;        lock.l_whence = SEEK_SET;        lock.l_len = 0;        if (fcntl(sock, F_SETLKW, &lock) != -1)            return 0;    } while (errno == EINTR              && ! fail_on_intr              && ! shutdownPending);    return -1;#else    return 0;#endif}/* *---------------------------------------------------------------------- * * ReleaseLock -- * *      On platforms that implement concurrent calls to accept *      on a shared listening ipcFd, does nothing.  On other platforms, *	releases an exclusive lock acquired by AcquireLock. * * Results: *      0 for successful call, -1 in case of system error (fatal). * * Side effects: *      This process no longer holds the lock. * *---------------------------------------------------------------------- */static int ReleaseLock(int sock){#ifdef USE_LOCKING    do {        struct flock lock;        lock.l_type = F_UNLCK;        lock.l_start = 0;        lock.l_whence = SEEK_SET;        lock.l_len = 0;        if (fcntl(sock, F_SETLK, &lock) != -1)            return 0;    } while (errno == EINTR);    return -1;#else    return 0;#endif}/********************************************************************** * Determine if the errno resulting from a failed accept() warrants a * retry or exit().  Based on Apache's http_main.c accept() handling * and Stevens' Unix Network Programming Vol 1, 2nd Ed, para. 15.6. */static int is_reasonable_accept_errno (const int error){    switch (error) {#ifdef EPROTO        /* EPROTO on certain older kernels really means ECONNABORTED, so         * we need to ignore it for them.  See discussion in new-httpd         * archives nh.9701 search for EPROTO.  Also see nh.9603, search         * for EPROTO:  There is potentially a bug in Solaris 2.x x<6, and         * other boxes that implement tcp sockets in userland (i.e. on top of         * STREAMS).  On these systems, EPROTO can actually result in a fatal         * loop.  See PR#981 for example.  It's hard to handle both uses of         * EPROTO. */        case EPROTO:#endif#ifdef ECONNABORTED        case ECONNABORTED:#endif        /* Linux generates the rest of these, other tcp stacks (i.e.         * bsd) tend to hide them behind getsockopt() interfaces.  They         * occur when the net goes sour or the client disconnects after the         * three-way handshake has been done in the kernel but before         * userland has picked up the socket. */#ifdef ECONNRESET        case ECONNRESET:#endif#ifdef ETIMEDOUT        case ETIMEDOUT:#endif#ifdef EHOSTUNREACH        case EHOSTUNREACH:#endif#ifdef ENETUNREACH        case ENETUNREACH:#endif            return 1;        default:            return 0;    }}/********************************************************************** * This works around a problem on Linux 2.0.x and SCO Unixware (maybe * others?).  When a connect() is made to a Unix Domain socket, but its * not accept()ed before the web server gets impatient and close()s, an * accept() results in a valid file descriptor, but no data to read. * This causes a block on the first read() - which never returns! * * Another approach to this is to write() to the socket to provoke a * SIGPIPE, but this is a pain because of the FastCGI protocol, the fact * that whatever is written has to be universally ignored by all FastCGI * web servers, and a SIGPIPE handler has to be installed which returns * (or SIGPIPE is ignored). * * READABLE_UNIX_FD_DROP_DEAD_TIMEVAL = 2,0 by default. * * Making it shorter is probably safe, but I'll leave that to you.  Making * it 0,0 doesn't work reliably.  The shorter you can reliably make it, * the faster your application will be able to recover (waiting 2 seconds * may _cause_ the problem when there is a very high demand). At any rate, * this is better than perma-blocking. */static int is_af_unix_keeper(const int fd){    struct timeval tval = { READABLE_UNIX_FD_DROP_DEAD_TIMEVAL };    fd_set read_fds;    FD_ZERO(&read_fds);    FD_SET(fd, &read_fds);    return select(fd + 1, &read_fds, NULL, NULL, &tval) >= 0 && FD_ISSET(fd, &read_fds);}/* *---------------------------------------------------------------------- * * OS_Accept -- * *	Accepts a new FastCGI connection.  This routine knows whether *      we're dealing with TCP based sockets or NT Named Pipes for IPC. * * Results: *      -1 if the operation fails, otherwise this is a valid IPC fd. * * Side effects: *      New IPC connection is accepted. * *---------------------------------------------------------------------- */int OS_Accept(int listen_sock, int fail_on_intr, const char *webServerAddrs){    int socket = -1;    union {        struct sockaddr_un un;        struct sockaddr_in in;    } sa;    for (;;) {        if (AcquireLock(listen_sock, fail_on_intr))            return -1;        for (;;) {            do {#ifdef HAVE_SOCKLEN                socklen_t len = sizeof(sa);#else                int len = sizeof(sa);#endif                if (shutdownPending) break;                /* There's a window here */                socket = accept(listen_sock, (struct sockaddr *)&sa, &len);            } while (socket < 0                      && errno == EINTR                      && ! fail_on_intr                      && ! shutdownPending);            if (socket < 0) {                if (shutdownPending || ! is_reasonable_accept_errno(errno)) {                    int errnoSave = errno;                    ReleaseLock(listen_sock);                                        if (! shutdownPending) {                        errno = errnoSave;                    }                    return (-1);                }                errno = 0;            }            else {  /* socket >= 0 */                int set = 1;                if (sa.in.sin_family != AF_INET)                    break;#ifdef TCP_NODELAY                /* No replies to outgoing data, so disable Nagle */                setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&set, sizeof(set));#endif                /* Check that the client IP address is approved */                if (ClientAddrOK(&sa.in, webServerAddrs))                    break;                close(socket);            }  /* socket >= 0 */        }  /* for(;;) */        if (ReleaseLock(listen_sock))            return (-1);        if (sa.in.sin_family != AF_UNIX || is_af_unix_keeper(socket))            break;        close(socket);    }  /* while(1) - lock */    return (socket);}/* *---------------------------------------------------------------------- * * OS_IpcClose * *	OS IPC routine to close an IPC connection. * * Results: * * * Side effects: *      IPC connection is closed. * *---------------------------------------------------------------------- */int OS_IpcClose(int ipcFd, int shutdown){    return OS_Close(ipcFd, shutdown);}/* *---------------------------------------------------------------------- * * 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){	union {        struct sockaddr_in in;        struct sockaddr_un un;    } sa;#ifdef HAVE_SOCKLEN    socklen_t len = sizeof(sa);#else    int len = sizeof(sa);#endif    errno = 0;    if (getpeername(sock, (struct sockaddr *)&sa, &len) != 0 && errno == ENOTCONN) {        return TRUE;    }    else {        return FALSE;    }}/* *---------------------------------------------------------------------- * * OS_SetFlags -- * *      Sets selected flag bits in an open file descriptor. * *---------------------------------------------------------------------- */void OS_SetFlags(int fd, int flags){    int val;    if((val = fcntl(fd, F_GETFL, 0)) < 0) {        return;    }    val |= flags;    if(fcntl(fd, F_SETFL, val) < 0) {        return;    }}

⌨️ 快捷键说明

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