📄 prsocket.c
字号:
#ifdef _PR_INET6 if (addr && (AF_INET6 == addr->raw.family)) addr->raw.family = PR_AF_INET6;#endif PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); PR_ASSERT(IsValidNetAddrLen(addr, al) == PR_TRUE); return fd2;}#ifdef WINNTPR_IMPLEMENT(PRFileDesc*) PR_NTFast_Accept(PRFileDesc *fd, PRNetAddr *addr,PRIntervalTime timeout){ PRInt32 osfd; PRFileDesc *fd2; PRIntn al; PRThread *me = _PR_MD_CURRENT_THREAD(); PRNetAddr addrCopy; if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); return 0; } if (_PR_IO_PENDING(me)) { PR_SetError(PR_IO_PENDING_ERROR, 0); return 0; } if (addr == NULL) { addr = &addrCopy; } al = PR_NETADDR_SIZE(addr); osfd = _PR_MD_FAST_ACCEPT(fd, addr, &al, timeout, PR_TRUE, NULL, NULL); if (osfd == -1) { return 0; } fd2 = PR_AllocFileDesc(osfd, PR_GetTCPMethods()); if (!fd2) { _PR_MD_CLOSE_SOCKET(osfd); } else { fd2->secret->nonblocking = fd->secret->nonblocking; fd2->secret->md.io_model_committed = PR_TRUE; PR_ASSERT(al == PR_NETADDR_SIZE(addr)); fd2->secret->md.accepted_socket = PR_TRUE; memcpy(&fd2->secret->md.peer_addr, addr, al);#ifdef _PR_INET6 if (AF_INET6 == addr->raw.family) addr->raw.family = PR_AF_INET6;#endif } return fd2;}#endif /* WINNT */static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr){ PRInt32 result; const PRNetAddr *addrp = addr;#if defined(_PR_INET6) PRNetAddr addrCopy;#endif PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);#ifdef XP_UNIX if (addr->raw.family == AF_UNIX) { /* Disallow relative pathnames */ if (addr->local.path[0] != '/') { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return PR_FAILURE; } }#endif /* XP_UNIX */#if defined(_PR_INET6) if (addr->raw.family == PR_AF_INET6) { addrCopy = *addr; addrCopy.raw.family = AF_INET6; addrp = &addrCopy; }#endif result = _PR_MD_BIND(fd, addrp, PR_NETADDR_SIZE(addr)); if (result < 0) { return PR_FAILURE; } return PR_SUCCESS;}static PRStatus PR_CALLBACK SocketListen(PRFileDesc *fd, PRIntn backlog){ PRInt32 result; result = _PR_MD_LISTEN(fd, backlog); if (result < 0) { return PR_FAILURE; } return PR_SUCCESS;}static PRStatus PR_CALLBACK SocketShutdown(PRFileDesc *fd, PRIntn how){ PRInt32 result; result = _PR_MD_SHUTDOWN(fd, how); if (result < 0) { return PR_FAILURE; } return PR_SUCCESS;}static PRInt32 PR_CALLBACK SocketRecv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,PRIntervalTime timeout){ PRInt32 rv; PRThread *me = _PR_MD_CURRENT_THREAD(); if ((flags != 0) && (flags != PR_MSG_PEEK)) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return -1; } if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); return -1; } if (_PR_IO_PENDING(me)) { PR_SetError(PR_IO_PENDING_ERROR, 0); return -1; } PR_LOG(_pr_io_lm, PR_LOG_MAX, ("recv: fd=%p osfd=%d buf=%p amount=%d flags=%d", fd, fd->secret->md.osfd, buf, amount, flags));#ifdef _PR_HAVE_PEEK_BUFFER if (fd->secret->peekBytes != 0) { rv = (amount < fd->secret->peekBytes) ? amount : fd->secret->peekBytes; memcpy(buf, fd->secret->peekBuffer, rv); if (flags == 0) { /* consume the bytes in the peek buffer */ fd->secret->peekBytes -= rv; if (fd->secret->peekBytes != 0) { memmove(fd->secret->peekBuffer, fd->secret->peekBuffer + rv, fd->secret->peekBytes); } } return rv; } /* allocate peek buffer, if necessary */ if ((PR_MSG_PEEK == flags) && _PR_FD_NEED_EMULATE_MSG_PEEK(fd)) { PR_ASSERT(0 == fd->secret->peekBytes); /* impose a max size on the peek buffer */ if (amount > _PR_PEEK_BUFFER_MAX) { amount = _PR_PEEK_BUFFER_MAX; } if (fd->secret->peekBufSize < amount) { if (fd->secret->peekBuffer) { PR_Free(fd->secret->peekBuffer); } fd->secret->peekBufSize = amount; fd->secret->peekBuffer = PR_Malloc(amount); if (NULL == fd->secret->peekBuffer) { fd->secret->peekBufSize = 0; PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return -1; } } }#endif rv = _PR_MD_RECV(fd, buf, amount, flags, timeout); PR_LOG(_pr_io_lm, PR_LOG_MAX, ("recv -> %d, error = %d, os error = %d", rv, PR_GetError(), PR_GetOSError()));#ifdef _PR_HAVE_PEEK_BUFFER if ((PR_MSG_PEEK == flags) && _PR_FD_NEED_EMULATE_MSG_PEEK(fd)) { if (rv > 0) { memcpy(fd->secret->peekBuffer, buf, rv); fd->secret->peekBytes = rv; } }#endif return rv;}static PRInt32 PR_CALLBACK SocketRead(PRFileDesc *fd, void *buf, PRInt32 amount){ return SocketRecv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);}static PRInt32 PR_CALLBACK SocketSend(PRFileDesc *fd, const void *buf, PRInt32 amount,PRIntn flags, PRIntervalTime timeout){ PRInt32 temp, count; PRThread *me = _PR_MD_CURRENT_THREAD(); if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); return -1; } if (_PR_IO_PENDING(me)) { PR_SetError(PR_IO_PENDING_ERROR, 0); return -1; } count = 0; while (amount > 0) { PR_LOG(_pr_io_lm, PR_LOG_MAX, ("send: fd=%p osfd=%d buf=%p amount=%d", fd, fd->secret->md.osfd, buf, amount)); temp = _PR_MD_SEND(fd, buf, amount, flags, timeout); if (temp < 0) { count = -1; break; } count += temp; if (fd->secret->nonblocking) { break; } buf = (const void*) ((const char*)buf + temp); amount -= temp; } PR_LOG(_pr_io_lm, PR_LOG_MAX, ("send -> %d", count)); return count;}static PRInt32 PR_CALLBACK SocketWrite(PRFileDesc *fd, const void *buf, PRInt32 amount){ return SocketSend(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);}static PRStatus PR_CALLBACK SocketClose(PRFileDesc *fd){ if (!fd || !fd->secret || (fd->secret->state != _PR_FILEDESC_OPEN && fd->secret->state != _PR_FILEDESC_CLOSED)) { PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); return PR_FAILURE; } if (fd->secret->state == _PR_FILEDESC_OPEN) { if (_PR_MD_CLOSE_SOCKET(fd->secret->md.osfd) < 0) { return PR_FAILURE; } fd->secret->state = _PR_FILEDESC_CLOSED; }#ifdef _PR_HAVE_PEEK_BUFFER if (fd->secret->peekBuffer) { PR_ASSERT(fd->secret->peekBufSize > 0); PR_DELETE(fd->secret->peekBuffer); fd->secret->peekBufSize = 0; fd->secret->peekBytes = 0; }#endif PR_FreeFileDesc(fd); return PR_SUCCESS;}static PRInt32 PR_CALLBACK SocketAvailable(PRFileDesc *fd){ PRInt32 rv;#ifdef _PR_HAVE_PEEK_BUFFER if (fd->secret->peekBytes != 0) { return fd->secret->peekBytes; }#endif rv = _PR_MD_SOCKETAVAILABLE(fd); return rv; }static PRInt64 PR_CALLBACK SocketAvailable64(PRFileDesc *fd){ PRInt64 rv;#ifdef _PR_HAVE_PEEK_BUFFER if (fd->secret->peekBytes != 0) { LL_I2L(rv, fd->secret->peekBytes); return rv; }#endif LL_I2L(rv, _PR_MD_SOCKETAVAILABLE(fd)); return rv; }static PRStatus PR_CALLBACK SocketSync(PRFileDesc *fd){#if defined(XP_MAC)#pragma unused (fd)#endif return PR_SUCCESS;}static PRInt32 PR_CALLBACK SocketSendTo( PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout){ PRInt32 temp, count; const PRNetAddr *addrp = addr;#if defined(_PR_INET6) PRNetAddr addrCopy;#endif PRThread *me = _PR_MD_CURRENT_THREAD(); if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); return -1; } if (_PR_IO_PENDING(me)) { PR_SetError(PR_IO_PENDING_ERROR, 0); return -1; } PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);#if defined(_PR_INET6) if (addr->raw.family == PR_AF_INET6) { addrCopy = *addr; addrCopy.raw.family = AF_INET6; addrp = &addrCopy; }#endif count = 0; while (amount > 0) { temp = _PR_MD_SENDTO(fd, buf, amount, flags, addrp, PR_NETADDR_SIZE(addr), timeout); if (temp < 0) { count = -1; break; } count += temp; if (fd->secret->nonblocking) { break; } buf = (const void*) ((const char*)buf + temp); amount -= temp; } return count;}static PRInt32 PR_CALLBACK SocketRecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout){ PRInt32 rv; PRUint32 al; PRThread *me = _PR_MD_CURRENT_THREAD(); if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); return -1; } if (_PR_IO_PENDING(me)) { PR_SetError(PR_IO_PENDING_ERROR, 0); return -1; } al = sizeof(PRNetAddr); rv = _PR_MD_RECVFROM(fd, buf, amount, flags, addr, &al, timeout);#ifdef _PR_INET6 if (addr && (AF_INET6 == addr->raw.family)) addr->raw.family = PR_AF_INET6;#endif return rv;}static PRInt32 PR_CALLBACK SocketAcceptRead(PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, void *buf, PRInt32 amount,PRIntervalTime timeout){ PRInt32 rv; PRThread *me = _PR_MD_CURRENT_THREAD(); if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); return -1; } if (_PR_IO_PENDING(me)) { PR_SetError(PR_IO_PENDING_ERROR, 0); return -1; } /* The socket must be in blocking mode. */ if (sd->secret->nonblocking) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return -1; } *nd = NULL;#if defined(WINNT) { PRInt32 newSock; PRNetAddr *raddrCopy; if (raddr == NULL) { raddr = &raddrCopy; } rv = _PR_MD_ACCEPT_READ(sd, &newSock, raddr, buf, amount, timeout); if (rv < 0) { rv = -1; } else { /* Successfully accepted and read; create the new PRFileDesc */ *nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods()); if (*nd == 0) { _PR_MD_CLOSE_SOCKET(newSock); /* PR_AllocFileDesc() has invoked PR_SetError(). */ rv = -1; } else { (*nd)->secret->md.io_model_committed = PR_TRUE; (*nd)->secret->md.accepted_socket = PR_TRUE; memcpy(&(*nd)->secret->md.peer_addr, *raddr, PR_NETADDR_SIZE(*raddr));#ifdef _PR_INET6 if (AF_INET6 == *raddr->raw.family) *raddr->raw.family = PR_AF_INET6;#endif } } }#else rv = PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout);#endif return rv;}#ifdef WINNTPR_IMPLEMENT(PRInt32) PR_NTFast_AcceptRead(PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, void *buf, PRInt32 amount,PRIntervalTime timeout){ PRInt32 rv; PRInt32 newSock; PRThread *me = _PR_MD_CURRENT_THREAD(); PRNetAddr *raddrCopy; if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); return -1; } if (_PR_IO_PENDING(me)) { PR_SetError(PR_IO_PENDING_ERROR, 0); return -1; } *nd = NULL; if (raddr == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -