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

📄 prsocket.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	_PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE);	_PR_MD_MAKE_NONBLOCK(f[1]);	_PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE);	return PR_SUCCESS;#elif defined(WINNT)    /*     * A socket pair is often used for interprocess communication,     * so we need to make sure neither socket is associated with     * the I/O completion port; otherwise it can't be used by a     * child process.     *     * The default implementation below cannot be used for NT     * because PR_Accept would have associated the I/O completion     * port with the listening and accepted sockets.     */    SOCKET listenSock;    SOCKET osfd[2];    struct sockaddr_in selfAddr, peerAddr;    int addrLen;    if (!_pr_initialized) _PR_ImplicitInitialization();    osfd[0] = osfd[1] = INVALID_SOCKET;    listenSock = socket(AF_INET, SOCK_STREAM, 0);    if (listenSock == INVALID_SOCKET) {        goto failed;    }    selfAddr.sin_family = AF_INET;    selfAddr.sin_port = 0;    selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* BugZilla: 35408 */    addrLen = sizeof(selfAddr);    if (bind(listenSock, (struct sockaddr *) &selfAddr,            addrLen) == SOCKET_ERROR) {        goto failed;    }    if (getsockname(listenSock, (struct sockaddr *) &selfAddr,            &addrLen) == SOCKET_ERROR) {        goto failed;    }    if (listen(listenSock, 5) == SOCKET_ERROR) {        goto failed;    }    osfd[0] = socket(AF_INET, SOCK_STREAM, 0);    if (osfd[0] == INVALID_SOCKET) {        goto failed;    }    selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);    /*     * Only a thread is used to do the connect and accept.     * I am relying on the fact that connect returns     * successfully as soon as the connect request is put     * into the listen queue (but before accept is called).     * This is the behavior of the BSD socket code.  If     * connect does not return until accept is called, we     * will need to create another thread to call connect.     */    if (connect(osfd[0], (struct sockaddr *) &selfAddr,            addrLen) == SOCKET_ERROR) {        goto failed;    }    /*     * A malicious local process may connect to the listening     * socket, so we need to verify that the accepted connection     * is made from our own socket osfd[0].     */    if (getsockname(osfd[0], (struct sockaddr *) &selfAddr,            &addrLen) == SOCKET_ERROR) {        goto failed;    }    osfd[1] = accept(listenSock, (struct sockaddr *) &peerAddr, &addrLen);    if (osfd[1] == INVALID_SOCKET) {        goto failed;    }    if (peerAddr.sin_port != selfAddr.sin_port) {        /* the connection we accepted is not from osfd[0] */        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);        goto failed;    }    closesocket(listenSock);    f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods());    if (!f[0]) {        closesocket(osfd[0]);        closesocket(osfd[1]);        /* PR_AllocFileDesc() has invoked PR_SetError(). */        return PR_FAILURE;    }    f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods());    if (!f[1]) {        PR_Close(f[0]);        closesocket(osfd[1]);        /* PR_AllocFileDesc() has invoked PR_SetError(). */        return PR_FAILURE;    }    _PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE);    _PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE);    return PR_SUCCESS;failed:    if (listenSock != INVALID_SOCKET) {        closesocket(listenSock);    }    if (osfd[0] != INVALID_SOCKET) {        closesocket(osfd[0]);    }    if (osfd[1] != INVALID_SOCKET) {        closesocket(osfd[1]);    }    return PR_FAILURE;#else /* not Unix or NT */    /*     * default implementation     */    PRFileDesc *listenSock;    PRNetAddr selfAddr, peerAddr;    PRUint16 port;    f[0] = f[1] = NULL;    listenSock = PR_NewTCPSocket();    if (listenSock == NULL) {        goto failed;    }    PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); /* BugZilla: 35408 */    if (PR_Bind(listenSock, &selfAddr) == PR_FAILURE) {        goto failed;    }    if (PR_GetSockName(listenSock, &selfAddr) == PR_FAILURE) {        goto failed;    }    port = ntohs(selfAddr.inet.port);    if (PR_Listen(listenSock, 5) == PR_FAILURE) {        goto failed;    }    f[0] = PR_NewTCPSocket();    if (f[0] == NULL) {        goto failed;    }#ifdef _PR_CONNECT_DOES_NOT_BIND    /*     * If connect does not implicitly bind the socket (e.g., on     * BeOS), we have to bind the socket so that we can get its     * port with getsockname later.     */    PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr);    if (PR_Bind(f[0], &selfAddr) == PR_FAILURE) {        goto failed;    }#endif    PR_InitializeNetAddr(PR_IpAddrLoopback, port, &selfAddr);    /*     * Only a thread is used to do the connect and accept.     * I am relying on the fact that PR_Connect returns     * successfully as soon as the connect request is put     * into the listen queue (but before PR_Accept is called).     * This is the behavior of the BSD socket code.  If     * connect does not return until accept is called, we     * will need to create another thread to call connect.     */    if (PR_Connect(f[0], &selfAddr, PR_INTERVAL_NO_TIMEOUT)            == PR_FAILURE) {        goto failed;    }    /*     * A malicious local process may connect to the listening     * socket, so we need to verify that the accepted connection     * is made from our own socket f[0].     */    if (PR_GetSockName(f[0], &selfAddr) == PR_FAILURE) {        goto failed;    }    f[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT);    if (f[1] == NULL) {        goto failed;    }    if (peerAddr.inet.port != selfAddr.inet.port) {        /* the connection we accepted is not from f[0] */        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);        goto failed;    }    PR_Close(listenSock);    return PR_SUCCESS;failed:    if (listenSock) {        PR_Close(listenSock);    }    if (f[0]) {        PR_Close(f[0]);    }    if (f[1]) {        PR_Close(f[1]);    }    return PR_FAILURE;#endif}PR_IMPLEMENT(PRInt32)PR_FileDesc2NativeHandle(PRFileDesc *fd){    if (fd) {        fd = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER);    }    if (!fd) {        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);        return -1;    }    return fd->secret->md.osfd;}PR_IMPLEMENT(void)PR_ChangeFileDescNativeHandle(PRFileDesc *fd, PRInt32 handle){	if (fd)		fd->secret->md.osfd = handle;}/*** Select compatibility***/PR_IMPLEMENT(void) PR_FD_ZERO(PR_fd_set *set){	memset(set, 0, sizeof(PR_fd_set));}PR_IMPLEMENT(void) PR_FD_SET(PRFileDesc *fh, PR_fd_set *set){	PR_ASSERT( set->hsize < PR_MAX_SELECT_DESC );	set->harray[set->hsize++] = fh;}PR_IMPLEMENT(void) PR_FD_CLR(PRFileDesc *fh, PR_fd_set *set){	PRUint32 index, index2;	for (index = 0; index<set->hsize; index++)		if (set->harray[index] == fh) {			for (index2=index; index2 < (set->hsize-1); index2++) {				set->harray[index2] = set->harray[index2+1];			}			set->hsize--;			break;		}}PR_IMPLEMENT(PRInt32) PR_FD_ISSET(PRFileDesc *fh, PR_fd_set *set){	PRUint32 index;	for (index = 0; index<set->hsize; index++)		if (set->harray[index] == fh) {			return 1;		}	return 0;}PR_IMPLEMENT(void) PR_FD_NSET(PRInt32 fd, PR_fd_set *set){	PR_ASSERT( set->nsize < PR_MAX_SELECT_DESC );	set->narray[set->nsize++] = fd;}PR_IMPLEMENT(void) PR_FD_NCLR(PRInt32 fd, PR_fd_set *set){	PRUint32 index, index2;	for (index = 0; index<set->nsize; index++)		if (set->narray[index] == fd) {			for (index2=index; index2 < (set->nsize-1); index2++) {				set->narray[index2] = set->narray[index2+1];			}			set->nsize--;			break;		}}PR_IMPLEMENT(PRInt32) PR_FD_NISSET(PRInt32 fd, PR_fd_set *set){	PRUint32 index;	for (index = 0; index<set->nsize; index++)		if (set->narray[index] == fd) {			return 1;		}	return 0;}#if !defined(NEED_SELECT)#if !defined(XP_MAC)#include "obsolete/probslet.h"#else#include "probslet.h"#endif#define PD_INCR 20static PRPollDesc *_pr_setfd(    PR_fd_set *set, PRInt16 flags, PRPollDesc *polldesc){    PRUintn fsidx, pdidx;    PRPollDesc *poll = polldesc;    if (NULL == set) return poll;	/* First set the pr file handle osfds */	for (fsidx = 0; fsidx < set->hsize; fsidx++)	{	    for (pdidx = 0; 1; pdidx++)        {            if ((PRFileDesc*)-1 == poll[pdidx].fd)            {                /* our vector is full - extend and condition it */                poll = (PRPollDesc*)PR_Realloc(                    poll, (pdidx + 1 + PD_INCR) * sizeof(PRPollDesc));                if (NULL == poll) goto out_of_memory;                memset(                    poll + pdidx * sizeof(PRPollDesc),                    0, PD_INCR * sizeof(PRPollDesc));                poll[pdidx + PD_INCR].fd = (PRFileDesc*)-1;            }            if ((NULL == poll[pdidx].fd)            || (poll[pdidx].fd == set->harray[fsidx]))            {                /* PR_ASSERT(0 == (poll[pdidx].in_flags & flags)); */                /* either empty or prevously defined */                poll[pdidx].fd = set->harray[fsidx];  /* possibly redundant */                poll[pdidx].in_flags |= flags;  /* possibly redundant */                break;            }        }	}#if 0	/* Second set the native osfds */	for (fsidx = 0; fsidx < set->nsize; fsidx++)	{	    for (pdidx = 0; ((PRFileDesc*)-1 != poll[pdidx].fd); pdidx++)        {            if ((PRFileDesc*)-1 == poll[pdidx].fd)            {                /* our vector is full - extend and condition it */                poll = PR_Realloc(                    poll, (pdidx + PD_INCR) * sizeof(PRPollDesc));                if (NULL == poll) goto out_of_memory;                memset(                    poll + pdidx * sizeof(PRPollDesc),                    0, PD_INCR * sizeof(PRPollDesc));                poll[(pdidx + PD_INCR)].fd = (PRFileDesc*)-1;            }            if ((NULL == poll[pdidx].fd)            || (poll[pdidx].fd == set->narray[fsidx]))            {                /* either empty or prevously defined */                poll[pdidx].fd = set->narray[fsidx];                PR_ASSERT(0 == (poll[pdidx].in_flags & flags));                poll[pdidx].in_flags |= flags;                break;            }        }	}#endif /* 0 */	return poll;out_of_memory:    if (NULL != polldesc) PR_DELETE(polldesc);    return NULL;}  /* _pr_setfd */#endif /* !defined(NEED_SELECT) */PR_IMPLEMENT(PRInt32) PR_Select(    PRInt32 unused, PR_fd_set *pr_rd, PR_fd_set *pr_wr,     PR_fd_set *pr_ex, PRIntervalTime timeout){#if !defined(NEED_SELECT)    PRInt32 npds = 0;     /*    ** Find out how many fds are represented in the three lists.    ** Then allocate a polling descriptor for the logical union    ** (there can't be any overlapping) and call PR_Poll().    */    PRPollDesc *copy, *poll;    static PRBool warning = PR_TRUE;    if (warning) warning = _PR_Obsolete( "PR_Select()", "PR_Poll()");    /* try to get an initial guesss at how much space we need */    npds = 0;    if ((NULL != pr_rd) && ((pr_rd->hsize + pr_rd->nsize - npds) > 0))        npds = pr_rd->hsize + pr_rd->nsize;    if ((NULL != pr_wr) && ((pr_wr->hsize + pr_wr->nsize - npds) > 0))        npds = pr_wr->hsize + pr_wr->nsize;    if ((NULL != pr_ex) && ((pr_ex->hsize + pr_ex->nsize - npds) > 0))        npds = pr_ex->hsize + pr_ex->nsize;    if (0 == npds)    {        PR_Sleep(timeout);        return 0;    }    copy = poll = (PRPollDesc*)PR_Calloc(npds + PD_INCR, sizeof(PRPollDesc));    if (NULL == poll) goto out_of_memory;    poll[npds + PD_INCR - 1].fd = (PRFileDesc*)-1;    poll = _pr_setfd(pr_rd, PR_POLL_READ, poll);    if (NULL == poll) goto out_of_memory;    poll = _pr_setfd(pr_wr, PR_POLL_WRITE, poll);    if (NULL == poll) goto out_of_memory;    poll = _pr_setfd(pr_ex, PR_POLL_EXCEPT, poll);    if (NULL == poll) goto out_of_memory;    unused = 0;    while (NULL != poll[unused].fd && (PRFileDesc*)-1 != poll[unused].fd)    {        ++unused;    }    PR_ASSERT(unused > 0);    npds = PR_Poll(poll, unused, timeout);    if (npds > 0)    {        /* Copy the results back into the fd sets */        if (NULL != pr_rd) pr_rd->nsize = pr_rd->hsize = 0;        if (NULL != pr_wr) pr_wr->nsize = pr_wr->hsize = 0;        if (NULL != pr_ex) pr_ex->nsize = pr_ex->hsize = 0;        for (copy = &poll[unused - 1]; copy >= poll; --copy)        {            if (copy->out_flags & PR_POLL_NVAL)            {                PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);                npds = -1;                break;            }            if (copy->out_flags & PR_POLL_READ)                if (NULL != pr_rd) pr_rd->harray[pr_rd->hsize++] = copy->fd;            if (copy->out_flags & PR_POLL_WRITE)                if (NULL != pr_wr) pr_wr->harray[pr_wr->hsize++] = copy->fd;            if (copy->out_flags & PR_POLL_EXCEPT)                if (NULL != pr_ex) pr_ex->harray[pr_ex->hsize++] = copy->fd;        }    }    PR_DELETE(poll);    return npds;out_of_memory:    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);    return -1;    #endif /* !defined(NEED_SELECT) */    }

⌨️ 快捷键说明

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