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

📄 ncbi_socket.c

📁 ncbi源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        assert(0);        break;    }}extern ESwitch SOCK_SetDataLoggingAPI(ESwitch log){    ESwitch old = s_Log;    if (log == eDefault)        log = eOff;    s_Log = log;    return old;}extern ESwitch SOCK_SetDataLogging(SOCK sock, ESwitch log){    ESwitch old = sock->log;    sock->log = log;    return old;}/****************************************************************************** *  API Initialization and Shutdown/Cleanup */extern void SOCK_AllowSigPipeAPI(void){#ifdef NCBI_OS_UNIX    s_AllowSigPipe = 1/*true - API will not mask SIGPIPE out at init*/;#endif /*NCBI_OS_UNIX*/    return;}#if 0/*defined(_DEBUG) && !defined(NDEBUG)*/#  if !defined(__GNUC__) && !defined(offsetof)#    define offsetof(T, F) ((size_t)((char*) &(((T*) 0)->F) - (char*) 0))#  endifstatic void s_ShowDataLayout(void){    CORE_LOGF(eLOG_Note, ("SOCK data layout:\n"                          "    Sizeof(SOCK_struct) = %u, offsets follow\n"                          "\tsock:      %u\n"                          "\tid:        %u\n"                          "\thost:      %u\n"                          "\tport:      %u\n"                          "\tbitfield:  16 bits\n"                          "\tr_timeout: %u\n"                          "\tr_tv:      %u\n"                          "\tr_to:      %u\n"                          "\tw_timeout: %u\n"                          "\tw_tv:      %u\n"                          "\tw_to:      %u\n"                          "\tc_timeout: %u\n"                          "\tc_tv:      %u\n"                          "\tc_to:      %u\n"                          "\tr_buf:     %u\n"                          "\tw_buf:     %u\n"                          "\tw_len:     %u\n"                          "\tn_read:    %u\n"                          "\tn_written: %u\n"                          "\tn_in:      %u\n"                          "\tn_out:     %u"#  ifdef NCBI_OS_UNIX                          "\n\tfile:      %u"#  endif /*NCBI_OS_UNIX*/                          , (unsigned int) sizeof(SOCK_struct),                          (unsigned int) offsetof(SOCK_struct, sock),                          (unsigned int) offsetof(SOCK_struct, id),                          (unsigned int) offsetof(SOCK_struct, host),                          (unsigned int) offsetof(SOCK_struct, port),                          (unsigned int) offsetof(SOCK_struct, r_timeout),                          (unsigned int) offsetof(SOCK_struct, r_tv),                          (unsigned int) offsetof(SOCK_struct, r_to),                          (unsigned int) offsetof(SOCK_struct, w_timeout),                          (unsigned int) offsetof(SOCK_struct, w_tv),                          (unsigned int) offsetof(SOCK_struct, w_to),                          (unsigned int) offsetof(SOCK_struct, c_timeout),                          (unsigned int) offsetof(SOCK_struct, c_tv),                          (unsigned int) offsetof(SOCK_struct, c_to),                          (unsigned int) offsetof(SOCK_struct, r_buf),                          (unsigned int) offsetof(SOCK_struct, w_buf),                          (unsigned int) offsetof(SOCK_struct, w_len),                          (unsigned int) offsetof(SOCK_struct, n_read),                          (unsigned int) offsetof(SOCK_struct, n_written),                          (unsigned int) offsetof(SOCK_struct, n_in),                          (unsigned int) offsetof(SOCK_struct, n_out)#  ifdef NCBI_OS_UNIX                          , (unsigned int) offsetoff(SOCK_struct, file)#  endif /*NCBI_OS_UNIX*/                          ));}#endifextern EIO_Status SOCK_InitializeAPI(void){    static int/*bool*/ s_AtExitSet = 0;    CORE_LOCK_WRITE;    if ( s_Initialized ) {        CORE_UNLOCK;        return eIO_Success;    }#if 0/*defined(_DEBUG) && !defined(NDEBUG)*/    s_ShowDataLayout();#endif#if defined(NCBI_OS_MSWIN)    {{        WSADATA wsadata;        int x_errno = WSAStartup(MAKEWORD(1,1), &wsadata);        if (x_errno != 0) {            CORE_UNLOCK;            CORE_LOG_ERRNO_EX(eLOG_Error, x_errno, SOCK_STRERROR(x_errno),                              "[SOCK::InitializeAPI]  Failed WSAStartup()");            return eIO_Unknown;        }    }}#elif defined(NCBI_OS_UNIX)    if ( !s_AllowSigPipe ) {        struct sigaction sa;        if (sigaction(SIGPIPE, 0, &sa) < 0  ||  sa.sa_handler == SIG_DFL) {            memset(&sa, 0, sizeof(sa));            sa.sa_handler = SIG_IGN;            sigaction(SIGPIPE, &sa, 0);        }    }#endif /*platform-specific init*/    s_Initialized = 1/*true*/;    if ( !s_AtExitSet ) {        atexit((void (*)(void)) SOCK_ShutdownAPI);        s_AtExitSet = 1;    }    CORE_UNLOCK;    return eIO_Success;}extern EIO_Status SOCK_ShutdownAPI(void){    CORE_LOCK_WRITE;    if ( !s_Initialized ) {        CORE_UNLOCK;        return eIO_Success;    }    s_Initialized = 0/*false*/;#if defined(NCBI_OS_MSWIN)    {{        int x_errno = WSACleanup() ? SOCK_ERRNO : 0;        CORE_UNLOCK;        if ( x_errno ) {            CORE_LOG_ERRNO_EX(eLOG_Warning, x_errno, SOCK_STRERROR(x_errno),                              "[SOCK::ShutdownAPI]  Failed WSACleanup()");            return eIO_Unknown;        }    }}#else    CORE_UNLOCK;#endif /*NCBI_OS_MSWIN*/    return eIO_Success;}/****************************************************************************** *  LSOCK & SOCK AUXILIARIES *//* STimeout <--> struct timeval  conversions */static STimeout *s_tv2to(const struct timeval* tv, STimeout* to){    if ( !tv )        return 0;    to->sec  = (unsigned int) tv->tv_sec;    to->usec = (unsigned int) tv->tv_usec;    return to;}static struct timeval* s_to2tv(const STimeout* to, struct timeval* tv){    if ( !to )        return 0;    tv->tv_sec  = to->usec / 1000000 + to->sec;    tv->tv_usec = to->usec % 1000000;    return tv;}/* Switch the specified socket I/O between blocking and non-blocking mode */static int/*bool*/ s_SetNonblock(TSOCK_Handle sock, int/*bool*/ nonblock){#if defined(NCBI_OS_MSWIN)    unsigned long argp = nonblock ? 1 : 0;    return ioctlsocket(sock, FIONBIO, &argp) == 0;#elif defined(NCBI_OS_UNIX)  ||  defined(NCBI_OS_MAC)    return fcntl(sock, F_SETFL,                 nonblock ?                 fcntl(sock, F_GETFL, 0) | O_NONBLOCK :                 fcntl(sock, F_GETFL, 0) & (int) ~O_NONBLOCK) != -1;#else#   error "Unsupported platform"#endif /*platform-specific ioctl*/}static int/*bool*/ s_SetReuseAddress(TSOCK_Handle x_sock, int/*bool*/ on_off){#if defined(NCBI_OS_UNIX)  ||  defined(NCBI_OS_MSWIN)    /* setsockopt() is not implemented for MAC (in MIT socket emulation lib) */#  ifdef NCBI_OS_MSWIN    BOOL reuse_addr = on_off ? TRUE : FALSE;#  else    int  reuse_addr = on_off ? 1 : 0;#  endif /*NCBI_OS_MSWIN*/    return !setsockopt(x_sock, SOL_SOCKET, SO_REUSEADDR,                        (char*) &reuse_addr, sizeof(reuse_addr));#else    return 1;#endif /*NCBI_OS_UNIX || NCBI_OS_MSWIN*/}static EIO_Status s_Status(SOCK sock, EIO_Event direction){    assert(sock  &&  sock->sock != SOCK_INVALID);    switch ( direction ) {    case eIO_Read:        return sock->type != eSOCK_Datagram  &&  sock->eof            ? eIO_Closed : sock->r_status;    case eIO_Write:        return sock->w_status;    default:        /*should never get here*/        assert(0);        break;    }    return eIO_InvalidArg;}/* compare 2 normialized timeval timeouts: "whether v1 is less than v2" */static int/*bool*/ s_Less(const struct timeval* v1, const struct timeval* v2){    if (!v1)        return 0;    if (!v2)        return !!v1;    if (v1->tv_sec > v2->tv_sec)        return 0;    if (v1->tv_sec < v2->tv_sec)        return 1;    return v1->tv_usec < v2->tv_usec;}/* Select on the socket I/O (multiple sockets). * "Event" field is not considered for entries, whose "sock" field is 0, * "revent" for those entries is always "eIO_Open". For all other entries * only those sockets will be considered, whose "revent" field does not * contain "eIO_Open" value. If at least one non-"eIO_Open" status found * in "revent", the call terminates with "eIO_Success" status (after, * however checking all other entries for validity). No additional checks * are made for the pre-ready entries.  * * This function does not check datagram sockets with the select() system call * at all if the number of requested sockets is more than 1 (cf. SOCK_Poll()). * * If "eIO_Write" event is inquired on a stream socket, and the socket is * marked for upread, then returned "revent" may also include "eIO_Read" to * indicate that some input is available on that socket. * If "eIO_Read" event is inquired on an array (n != 1) including stream * socket(s) and some sockets still have connection/data pending, those * "revent" field may then include "eIO_Write" to indicate that * connection can be completed/data sent. * * Return eIO_Success when at least one socket is found either ready  * (including "eIO_Read" event on "eIO_Write" for upreadable sockets * and "eIO_Write" on "eIO_Read" for sockets in pending state) * or failing ("revent" contains "eIO_Close"). * Return "eIO_Timeout", if timeout expired before any socket became available. * Any other return code indicates some failure. */static EIO_Status s_Select(size_t                n,                           SSOCK_Poll            polls[],                           const struct timeval* tv){    int/*bool*/    write_only = 1;    int/*bool*/    read_only = 1;    int/*bool*/    ready = 0;    int/*bool*/    bad = 0;    fd_set         r_fds, w_fds, e_fds;    int            n_fds;    struct timeval x_tv;    size_t         i;    if ( tv )        x_tv = *tv;    for (;;) { /* (optionally) auto-resume if interrupted by a signal */        struct timeval xx_tv;        n_fds = 0;        FD_ZERO(&r_fds);        FD_ZERO(&w_fds);        FD_ZERO(&e_fds);        for (i = 0; i < n; i++) {            if ( !polls[i].sock ) {                polls[i].revent = eIO_Open;                continue;            }            if ( polls[i].revent ) {                ready = 1;                continue;            }            if (polls[i].event  &&                (EIO_Event)(polls[i].event | eIO_ReadWrite) == eIO_ReadWrite) {                TSOCK_Handle fd = polls[i].sock->sock;                if (fd != SOCK_INVALID) {                    int/*bool*/ ls = IS_LISTENING(polls[i].sock);                    if (!ls && n != 1 && polls[i].sock->type == eSOCK_Datagram)                        continue;                    if (ready  ||  bad)                        continue;                    switch (polls[i].event) {                    case eIO_Write:                    case eIO_ReadWrite:                        if (!ls) {                            if (polls[i].sock->type == eSOCK_Datagram  ||                                polls[i].sock->w_status != eIO_Closed) {                                read_only = 0;                                FD_SET(fd, &w_fds);                                if (polls[i].sock->type == eSOCK_Datagram  ||                                    polls[i].sock->pending)                                    break;                                if (polls[i].event == eIO_Write  &&                                    (polls[i].sock->r_on_w == eOff                                     ||  (polls[i].sock->r_on_w == eDefault                                          &&  s_ReadOnWrite != eOn)))                                    break;                            } else if (polls[i].event == eIO_Write)                                break;                        } else if (polls[i].event == eIO_Write)                            break;                        /*FALLTHRU*/                    case eIO_Read:

⌨️ 快捷键说明

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