static PRStatus PR_CALLBACK SocketConnectContinue(
    PRFileDesc *fd, PRInt16 out_flags)
{
    PROsfd osfd;
    int err;

    if (out_flags & PR_POLL_NVAL) {
        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
        return PR_FAILURE;
    }
    if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0) {
        PR_ASSERT(out_flags == 0);
        PR_SetError(PR_IN_PROGRESS_ERROR, 0);
        return PR_FAILURE;
    }

    osfd = fd->secret->md.osfd;

#if defined(XP_UNIX)

    err = _MD_unix_get_nonblocking_connect_error(osfd);
    if (err != 0) {
        _PR_MD_MAP_CONNECT_ERROR(err);
        return PR_FAILURE;
    }
    return PR_SUCCESS;

#elif defined(WIN32) || defined(WIN16)

#if defined(WIN32)
    /*
     * The sleep circumvents a bug in Win32 WinSock.
     * See Microsoft Knowledge Base article ID: Q165989.
     */
    Sleep(0);
#endif /* WIN32 */

    if (out_flags & PR_POLL_EXCEPT) {
        int len = sizeof(err);
        if (getsockopt(osfd, (int)SOL_SOCKET, SO_ERROR, (char *) &err, &len)
                == SOCKET_ERROR) {
            _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
            return PR_FAILURE;
        }
        if (err != 0) {
            _PR_MD_MAP_CONNECT_ERROR(err);
        } else {
            PR_SetError(PR_UNKNOWN_ERROR, 0);
        }
        return PR_FAILURE;
    }

    PR_ASSERT(out_flags & PR_POLL_WRITE);
    return PR_SUCCESS;

#elif defined(XP_OS2)

    err = _MD_os2_get_nonblocking_connect_error(osfd);
    if (err != 0) {
        _PR_MD_MAP_CONNECT_ERROR(err);
        return PR_FAILURE;
    }
    return PR_SUCCESS;

#elif defined(XP_BEOS)

#ifdef BONE_VERSION  /* bug 122364 */
    /* temporary workaround until getsockopt(SO_ERROR) works in BONE */
    if (out_flags & PR_POLL_EXCEPT) {
        PR_SetError(PR_CONNECT_REFUSED_ERROR, 0);
        return PR_FAILURE;
    }
    PR_ASSERT(out_flags & PR_POLL_WRITE);
    return PR_SUCCESS;
#else
    err = _MD_beos_get_nonblocking_connect_error(fd);
    if( err != 0 ) {
        _PR_MD_MAP_CONNECT_ERROR(err);
        return PR_FAILURE;
    }
    else
        return PR_SUCCESS;
#endif /* BONE_VERSION */

#else
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return PR_FAILURE;
#endif
}
示例#2
0
PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
{
    PRInt32 osfd;
    PRFileDesc *bottom = pd->fd;
    int err, len;

    if (pd->out_flags & PR_POLL_NVAL) {
        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
        return PR_FAILURE;
    }
    if ((pd->out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0) {
        PR_ASSERT(pd->out_flags == 0);
        PR_SetError(PR_IN_PROGRESS_ERROR, 0);
        return PR_FAILURE;
    }

    while (bottom->lower != NULL) {
        bottom = bottom->lower;
    }
    osfd = bottom->secret->md.osfd;

#if defined(XP_UNIX)

    err = _MD_unix_get_nonblocking_connect_error(osfd);
    if (err != 0) {
        _PR_MD_MAP_CONNECT_ERROR(err);
        return PR_FAILURE;
    }
    return PR_SUCCESS;

#elif defined(WIN32) || defined(WIN16)

    if (pd->out_flags & PR_POLL_EXCEPT) {
#if defined(WIN32)
/* Note: There is a bug in Win32 WinSock. The sleep circumvents the
** bug. See wtc. /s lth.
*/
        Sleep(0);
#endif /* WIN32 */
        len = sizeof(err);
        if (getsockopt(osfd, (int)SOL_SOCKET, SO_ERROR, (char *) &err, &len)
                == SOCKET_ERROR) {
            _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
            return PR_FAILURE;
        }
        if (err != 0) {
            _PR_MD_MAP_CONNECT_ERROR(err);
        } else {
            PR_SetError(PR_UNKNOWN_ERROR, 0);
        }
        return PR_FAILURE;
    }

    PR_ASSERT(pd->out_flags & PR_POLL_WRITE);
    return PR_SUCCESS;

#elif defined(XP_OS2)

    if (pd->out_flags & PR_POLL_EXCEPT) {
        len = sizeof(err);
        if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &len)
                < 0) {
            _PR_MD_MAP_GETSOCKOPT_ERROR(sock_errno());
            return PR_FAILURE;
        }
        if (err != 0) {
            _PR_MD_MAP_CONNECT_ERROR(err);
        } else {
            PR_SetError(PR_UNKNOWN_ERROR, 0);
        }
        return PR_FAILURE;
    }

    PR_ASSERT(pd->out_flags & PR_POLL_WRITE);
    return PR_SUCCESS;

#elif defined(XP_MAC)

    err = _MD_mac_get_nonblocking_connect_error(osfd);
    if (err == -1)
        return PR_FAILURE;
	else     
		return PR_SUCCESS;

#else
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return PR_FAILURE;
#endif
}