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

📄 os2sock.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape Portable Runtime (NSPR). *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//* OS/2 Sockets module * *//*Note from DSR111297 - it should be noted that there are two flavors of select() on OS/2    *//*There is standard BSD (which is kind of slow) and a new flavor of select() that takes      *//*an integer list of sockets, the number of read sockets, write sockets, except sockets, and *//*a millisecond count for timeout. In the interest of performance I have choosen the OS/2    *//*specific version of select(). See OS/2 TCP/IP Programmer's Toolkit for more info.          */ #include "primpl.h"#ifdef XP_OS2_EMX #include <sys/time.h> /* For timeval. */#endif#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5#define READ_FD   1#define WRITE_FD  2void_PR_MD_INIT_IO(){    sock_init();}/* --- SOCKET IO --------------------------------------------------------- */PRInt32_PR_MD_SOCKET(int domain, int type, int flags){    PRInt32 osfd, err;    osfd = socket(domain, type, flags);    if (osfd == -1)     {        err = sock_errno();        _PR_MD_MAP_SOCKET_ERROR(err);    }    return(osfd);}/*** _MD_CloseSocket() -- Close a socket***/PRInt32_MD_CloseSocket(PRInt32 osfd){    PRInt32 rv, err;    rv = soclose(osfd);    if (rv == -1) {        err = sock_errno();        _PR_MD_MAP_CLOSE_ERROR(err);    }    return rv;}PRInt32_MD_SocketAvailable(PRFileDesc *fd){    PRInt32 result;    if (ioctl(fd->secret->md.osfd, FIONREAD, (char *) &result, sizeof(result)) < 0) {        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, sock_errno());        return -1;    }    return result;}static PRInt32socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout ){    PRInt32 rv = -1;    PRThread *me = _PR_MD_CURRENT_THREAD();    PRIntervalTime epoch, now, elapsed, remaining;    PRBool wait_for_remaining;    PRInt32 syserror;#ifdef BSD_SELECT    struct timeval tv;    fd_set rd_wr;#else    int socks[1];    long lTimeout;#endif    switch (timeout) {        case PR_INTERVAL_NO_WAIT:            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);            break;        case PR_INTERVAL_NO_TIMEOUT:            /*             * This is a special case of the 'default' case below.             * Please see the comments there.             */#ifdef BSD_SELECT            tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;            tv.tv_usec = 0;            FD_ZERO(&rd_wr);            do {                FD_SET(osfd, &rd_wr);                if (fd_type == READ_FD)                    rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);                else                    rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);#else            lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;             do {                socks[0] = osfd;                if (fd_type == READ_FD)                    rv = _MD_SELECT(socks, 1, 0, 0, lTimeout);                else                    rv = _MD_SELECT(socks, 0, 1, 0, lTimeout);#endif                                    if (rv == -1 && (syserror = sock_errno()) != SOCEINTR) {                    _PR_MD_MAP_SELECT_ERROR(syserror);                    break;                }                if (_PR_PENDING_INTERRUPT(me)) {                    me->flags &= ~_PR_INTERRUPT;                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);                    rv = -1;                    break;                }            } while (rv == 0 || (rv == -1 && syserror == EINTR));            break;        default:            now = epoch = PR_IntervalNow();            remaining = timeout;#ifdef BSD_SELECT            FD_ZERO(&rd_wr);#endif            do {                /*                 * We block in _MD_SELECT for at most                 * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,                 * so that there is an upper limit on the delay                 * before the interrupt bit is checked.                 */#ifdef BSD_SELECT                wait_for_remaining = PR_TRUE;                tv.tv_sec = PR_IntervalToSeconds(remaining);                if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {                    wait_for_remaining = PR_FALSE;                    tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;                    tv.tv_usec = 0;                } else {                    tv.tv_usec = PR_IntervalToMicroseconds(                        remaining -                        PR_SecondsToInterval(tv.tv_sec));                }                FD_SET(osfd, &rd_wr);                if (fd_type == READ_FD)                    rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);                else                    rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);#else                wait_for_remaining = PR_TRUE;                lTimeout = PR_IntervalToMilliseconds(remaining);                if (lTimeout > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) {                    wait_for_remaining = PR_FALSE;                    lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;                }                socks[0] = osfd;                if (fd_type == READ_FD)                    rv = _MD_SELECT(socks, 1, 0, 0, lTimeout);                else                    rv = _MD_SELECT(socks, 0, 1, 0, lTimeout);#endif                /*                 * we don't consider EINTR a real error                 */                if (rv == -1 && (syserror = sock_errno()) != SOCEINTR) {                    _PR_MD_MAP_SELECT_ERROR(syserror);                    break;                }                if (_PR_PENDING_INTERRUPT(me)) {                    me->flags &= ~_PR_INTERRUPT;                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);                    rv = -1;                    break;                }                /*                 * We loop again if _MD_SELECT timed out or got interrupted                 * by a signal, and the timeout deadline has not passed yet.                 */                if (rv == 0 || (rv == -1 && syserror == SOCEINTR)) {                    /*                     * If _MD_SELECT timed out, we know how much time                     * we spent in blocking, so we can avoid a                     * PR_IntervalNow() call.                     */                    if (rv == 0) {                        if (wait_for_remaining) {                            now += remaining;                        } else {#ifdef BSD_SELECT                            now += PR_SecondsToInterval(tv.tv_sec)                                + PR_MicrosecondsToInterval(tv.tv_usec);#else                            now += PR_MillisecondsToInterval(lTimeout);#endif                        }                    } else {                        now = PR_IntervalNow();                    }                    elapsed = (PRIntervalTime) (now - epoch);                    if (elapsed >= timeout) {                        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);                        rv = -1;                        break;                    } else {                        remaining = timeout - elapsed;                    }                }            } while (rv == 0 || (rv == -1 && syserror == SOCEINTR));            break;        }    return(rv);}PRInt32_MD_Accept(PRFileDesc *fd, PRNetAddr *addr,           PRUint32 *addrlen, PRIntervalTime timeout){    PRInt32 osfd = fd->secret->md.osfd;    PRInt32 rv, err;    PRThread *me = _PR_MD_CURRENT_THREAD();    while ((rv = accept(osfd, (struct sockaddr*) addr, (int*)addrlen)) == -1)    {        err = sock_errno();        if ((err == SOCEWOULDBLOCK) || (err == SOCECONNABORTED))        {            if (fd->secret->nonblocking) {                break;            }                if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)                    goto done;        } else if ((err == SOCEINTR) && (!_PR_PENDING_INTERRUPT(me))){            continue;        } else {            break;        }    }    if (rv < 0) {        _PR_MD_MAP_ACCEPT_ERROR(err);    }done:    return(rv);}PRInt32_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen,                PRIntervalTime timeout){    PRInt32 rv, err;    PRThread *me = _PR_MD_CURRENT_THREAD();    PRInt32 osfd = fd->secret->md.osfd;     /*      * We initiate the connection setup by making a nonblocking connect()      * call.  If the connect() call fails, there are two cases we handle      * specially:      * 1. The connect() call was interrupted by a signal.  In this case      *    we simply retry connect().      * 2. The NSPR socket is nonblocking and connect() fails with      *    EINPROGRESS.  We first wait until the socket becomes writable.      *    Then we try to find out whether the connection setup succeeded      *    or failed.      */retry:    if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1)    {        err = sock_errno();        if (err == SOCEINTR) {            if (_PR_PENDING_INTERRUPT(me)) {                me->flags &= ~_PR_INTERRUPT;                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);                return -1;            }            goto retry;        }        if (!fd->secret->nonblocking && (err == SOCEINPROGRESS))        {            /*             * socket_io_wait() may return -1 or 1.             */

⌨️ 快捷键说明

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