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

📄 macsockotpt.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        _MD_closesocket(newosfd);    macsock_map_error(err);    return -1;}PRInt32 _MD_connect(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout){    OSStatus err;    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;    PRThread *me = _PR_MD_CURRENT_THREAD();    TCall sndCall;    TBind bindReq;    PRNetAddr bindAddr;    if (endpoint == NULL) {        err = kEBADFErr;        goto ErrorExit;    }            if (addr == NULL) {        err = kEFAULTErr;        goto ErrorExit;    }        // Bind to a local port; let the system assign it.    bindAddr.inet.family = AF_INET;    bindAddr.inet.port = bindAddr.inet.ip = 0;    bindReq.addr.maxlen = PR_NETADDR_SIZE (&bindAddr);    bindReq.addr.len = 0;    bindReq.addr.buf = (UInt8*) &bindAddr;    bindReq.qlen = 0;        PR_Lock(fd->secret->md.miscLock);    PrepareForAsyncCompletion(me, fd->secret->md.osfd);        fd->secret->md.misc.thread = me;    err = OTBind(endpoint, &bindReq, NULL);    if (err != kOTNoError) {      me->io_pending = PR_FALSE;      PR_Unlock(fd->secret->md.miscLock);      goto ErrorExit;    }    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);    PR_Unlock(fd->secret->md.miscLock);    err = me->md.osErrCode;    if (err != kOTNoError)        goto ErrorExit;    memset(&sndCall, 0 , sizeof(sndCall));    sndCall.addr.maxlen = addrlen;    sndCall.addr.len = addrlen;    sndCall.addr.buf = (UInt8*) addr;    if (!fd->secret->nonblocking) {          PrepareForAsyncCompletion(me, fd->secret->md.osfd);      PR_ASSERT(fd->secret->md.write.thread == NULL);      fd->secret->md.write.thread = me;    }    err = OTConnect (endpoint, &sndCall, NULL);    if (err == kOTNoError) {      PR_ASSERT(!"OTConnect returned kOTNoError in async mode!?!");	    }    if (fd->secret->nonblocking) {      if (err == kOTNoDataErr)      err = EINPROGRESS;      goto ErrorExit;    } else {      if (err != kOTNoError && err != kOTNoDataErr) {        me->io_pending = PR_FALSE;        goto ErrorExit;      }    }	    WaitOnThisThread(me, timeout);    err = me->md.osErrCode;    if (err != kOTNoError)        goto ErrorExit;    return kOTNoError;ErrorExit:    macsock_map_error(err);    return -1;}// Errors:// EBADF -- bad socket id// EFAULT -- bad bufferstatic PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,                                PRIntn flags, PRIntervalTime timeout, SndRcvOpCode opCode){    OSStatus err;    OTResult result;    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;    PRThread *me = _PR_MD_CURRENT_THREAD();    PRInt32 bytesLeft = amount;    PR_ASSERT(flags == 0 ||        (opCode == kSTREAM_RECEIVE && flags == PR_MSG_PEEK));    PR_ASSERT(opCode == kSTREAM_SEND || opCode == kSTREAM_RECEIVE);        if (endpoint == NULL) {        err = kEBADFErr;        goto ErrorExit;    }            if (buf == NULL) {        err = kEFAULTErr;        goto ErrorExit;    }    PR_ASSERT(opCode == kSTREAM_SEND ? fd->secret->md.write.thread == NULL :                                       fd->secret->md.read.thread  == NULL);    while (bytesLeft > 0)    {        Boolean disabledNotifications = OTEnterNotifier(endpoint);            PrepareForAsyncCompletion(me, fd->secret->md.osfd);            if (opCode == kSTREAM_SEND) {        	do {				fd->secret->md.write.thread = me;				fd->secret->md.writeReady = PR_FALSE;				// expect the worst	            result = OTSnd(endpoint, buf, bytesLeft, NULL);				fd->secret->md.writeReady = (result != kOTFlowErr);				if (fd->secret->nonblocking)							// hope for the best					break;				else {					// We drop through on anything other than a blocking write.					if (result != kOTFlowErr)						break;					// Blocking write, but the pipe is full. Turn notifications on and					// wait for an event, hoping that it's a T_GODATA event.                    if (disabledNotifications) {                        OTLeaveNotifier(endpoint);                        disabledNotifications = false;                    }					WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);					result = me->md.osErrCode;					if (result != kOTNoError) // got interrupted, or some other error						break;					// Prepare to loop back and try again					disabledNotifications = OTEnterNotifier(endpoint);  			   		PrepareForAsyncCompletion(me, fd->secret->md.osfd);  				}			}			while(1);        } else {        	do {				fd->secret->md.read.thread = me;				fd->secret->md.readReady = PR_FALSE;				// expect the worst				            result = OTRcv(endpoint, buf, bytesLeft, NULL);	            if (fd->secret->nonblocking) {					fd->secret->md.readReady = (result != kOTNoDataErr);					break;				} else {					if (result != kOTNoDataErr) {			      		// If we successfully read a blocking socket, check for more data.			      		// According to IM:OT, we should be able to rely on OTCountDataBytes			      		// to tell us whether there is a nonzero amount of data pending.			        	size_t count;			        	OSErr tmpResult;			        	tmpResult = OTCountDataBytes(endpoint, &count);				        fd->secret->md.readReady = ((tmpResult == kOTNoError) && (count > 0));						break;				    }					// Blocking read, but no data available. Turn notifications on and					// wait for an event on this endpoint, and hope that we get a T_DATA event.                    if (disabledNotifications) {                        OTLeaveNotifier(endpoint);                        disabledNotifications = false;                    }					WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);					result = me->md.osErrCode;					if (result != kOTNoError) // interrupted thread, etc.						break;					// Prepare to loop back and try again					disabledNotifications = OTEnterNotifier(endpoint);  			   		PrepareForAsyncCompletion(me, fd->secret->md.osfd);  				}			}			// Retry read if we had to wait for data to show up.			while(1);        }		me->io_pending = PR_FALSE;		        if (opCode == kSTREAM_SEND)            fd->secret->md.write.thread = NULL;        else            fd->secret->md.read.thread  = NULL;        // turn notifications back on        if (disabledNotifications)            OTLeaveNotifier(endpoint);        if (result > 0) {            buf = (void *) ( (UInt32) buf + (UInt32)result );            bytesLeft -= result;            if (opCode == kSTREAM_RECEIVE) {                amount = result;                goto NormalExit;            }        } else {			switch (result) {				case kOTLookErr:				    PR_ASSERT(!"call to OTLook() required after all.");					break;								case kOTFlowErr:				case kOTNoDataErr:				case kEAGAINErr:				case kEWOULDBLOCKErr:					if (fd->secret->nonblocking) {										    if (bytesLeft == amount) {  // no data was sent						    err = result;						    goto ErrorExit;						}												// some data was sent						amount -= bytesLeft;						goto NormalExit;					}					WaitOnThisThread(me, timeout);					err = me->md.osErrCode;					if (err != kOTNoError)						goto ErrorExit;									break;									case kOTOutStateErr:	// if provider already closed, fall through to handle error					if (fd->secret->md.orderlyDisconnect) {						amount = 0;						goto NormalExit;					}					// else fall through				default:					err = result;					goto ErrorExit;			}		}    }NormalExit:    PR_ASSERT(opCode == kSTREAM_SEND ? fd->secret->md.write.thread == NULL :                                       fd->secret->md.read.thread  == NULL);    return amount;ErrorExit:    PR_ASSERT(opCode == kSTREAM_SEND ? fd->secret->md.write.thread == NULL :                                       fd->secret->md.read.thread  == NULL);    macsock_map_error(err);    return -1;}PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount,                                PRIntn flags, PRIntervalTime timeout){    return (SendReceiveStream(fd, buf, amount, flags, timeout, kSTREAM_RECEIVE));}PRInt32 _MD_send(PRFileDesc *fd,const void *buf, PRInt32 amount,                                PRIntn flags, PRIntervalTime timeout){    return (SendReceiveStream(fd, (void *)buf, amount, flags, timeout, kSTREAM_SEND));}// Errors:// EBADF -- bad socket id// EFAULT -- bad bufferstatic PRInt32 SendReceiveDgram(PRFileDesc *fd, void *buf, PRInt32 amount,                                PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen,                                PRIntervalTime timeout, SndRcvOpCode opCode){    OSStatus err;    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;    PRThread *me = _PR_MD_CURRENT_THREAD();    PRInt32 bytesLeft = amount;    TUnitData dgram;    PR_ASSERT(flags == 0);        if (endpoint == NULL) {        err = kEBADFErr;        goto ErrorExit;    }            if (buf == NULL || addr == NULL) {        err = kEFAULTErr;        goto ErrorExit;    }        if (opCode != kDGRAM_SEND && opCode != kDGRAM_RECEIVE) {        err = kEINVALErr;        goto ErrorExit;    }            memset(&dgram, 0 , sizeof(dgram));    dgram.addr.maxlen = *addrlen;    dgram.addr.len = *addrlen;    dgram.addr.buf = (UInt8*) addr;    dgram.udata.maxlen = amount;    dgram.udata.len = amount;    dgram.udata.buf = (UInt8*) buf;        while (bytesLeft > 0) {            PrepareForAsyncCompletion(me, fd->secret->md.osfd);            if (opCode == kDGRAM_SEND) {			fd->secret->md.write.thread = me;			fd->secret->md.writeReady = PR_FALSE;				// expect the worst            err = OTSndUData(endpoint, &dgram);			if (err != kOTFlowErr)							// hope for the best				fd->secret->md.writeReady = PR_TRUE;		} else {			fd->secret->md.read.thread = me;			fd->secret->md.readReady = PR_FALSE;				// expect the worst			            err = OTRcvUData(endpoint, &dgram, NULL);			if (err != kOTNoDataErr)							// hope for the best				fd->secret->md.readReady = PR_TRUE;		}        if (err == kOTNoError) {            buf = (void *) ( (UInt32) buf + (UInt32)dgram.udata.len );            bytesLeft -= dgram.udata.len;            dgram.udata.buf = (UInt8*) buf;                me->io_pending = PR_FALSE;        } else {            PR_ASSERT(err == kOTNoDataErr || err == kOTOutStateErr);            WaitOnThisThread(me, timeout);            err = me->md.osErrCode;            if (err != kOTNoError)                goto ErrorExit;        }    }    if (opCode == kDGRAM_RECEIVE)        *addrlen = dgram.addr.len;    return amount;ErrorExit:    macsock_map_error(err);    return -1;}PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,                                PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen,                               PRIntervalTime timeout){    return (SendReceiveDgram(fd, buf, amount, flags, addr, addrlen,                            timeout, kDGRAM_RECEIVE));}PRInt32 _MD_sendto(PRFileDesc *fd,const void *buf, PRInt32 amount,                                PRIntn flags, PRNetAddr *addr, PRUint32 addrlen,                               PRIntervalTime timeout){    return (SendReceiveDgram(fd, (void *)buf, amount, flags, addr, &addrlen,                            timeout, kDGRAM_SEND));}PRInt32 _MD_closesocket(PRInt32 osfd){    OSStatus err;    EndpointRef endpoint = (EndpointRef) osfd;    PRThread *me = _PR_MD_CURRENT_THREAD();    if (endpoint == NULL) {        err = kEBADFErr;        goto ErrorExit;    }            if (me->io_pending && me->io_fd == osfd)        me->io_pending = PR_FALSE;    (void) OTSndOrderlyDisconnect(endpoint);    err = OTCloseProvider(endpoint);    if (err != kOTNoError)        goto ErrorExit;    return kOTNoError;ErrorExit:    macsock_map_error(err);    return -1;}PRInt32 _MD_writev(PRFileDesc *fd, const struct PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout){#pragma unused (fd, iov, iov_size, timeout)    PR_ASSERT(0);    _PR_MD_CURRENT_THREAD()->md.osErrCode = unimpErr;    return -1;}// OT endpoint states are documented here:// http://gemma.apple.com/techpubs/mac/NetworkingOT/NetworkingWOT-27.html#MARKER-9-65//static PRBool GetState(PRFileDesc *fd, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady){    OTResult resultOT;    // hack to emulate BSD sockets; say that a socket that has disconnected    // is still readable.    size_t   availableData = 1;    if (!fd->secret->md.orderlyDisconnect)        OTCountDataBytes((EndpointRef)fd->secret->md.osfd, &availableData);

⌨️ 快捷键说明

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