📄 w16sock.c
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape Portable Runtime (NSPR). * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "primpl.h"static int winsockNotPresent = 0;void_PR_MD_INIT_IO(){ int rv; WORD WSAVersion = 0x0101; WSADATA WSAData; rv = WSAStartup( WSAVersion, &WSAData ); if ( rv != 0 ) { _PR_MD_MAP_WSASTARTUP_ERROR(WSAGetLastError()); winsockNotPresent = 1; } return;}void_PR_MD_CLEANUP_BEFORE_EXIT(void){ int rv; int err; rv = WSACleanup(); if ( rv == SOCKET_ERROR ) { err = WSAGetLastError(); PR_ASSERT(0); } return;} /* end _PR_MD_CLEANUP_BEFORE_EXIT() *//* --- SOCKET IO --------------------------------------------------------- */PRStatus _MD_WindowsGetHostName(char *name, PRUint32 namelen){ PRIntn rv; PRInt32 syserror; rv = gethostname(name, (PRInt32) namelen); if (0 == rv) { return PR_SUCCESS; } syserror = WSAGetLastError(); PR_ASSERT(WSANOTINITIALISED != syserror); _PR_MD_MAP_GETHOSTNAME_ERROR(syserror); return PR_FAILURE;}PRInt32_PR_MD_SOCKET(int af, int type, int flags){ SOCKET sock; PRUint32 one = 1; PRInt32 rv; PRInt32 err; if ( winsockNotPresent ) return( (PRInt32)INVALID_SOCKET ); sock = socket(af, type, flags); if (sock == INVALID_SOCKET ) { int rv = GetLastError(); closesocket(sock); _PR_MD_MAP_SOCKET_ERROR(rv); return (PRInt32)INVALID_SOCKET; } /* ** Make the socket Non-Blocking */ rv = ioctlsocket( sock, FIONBIO, &one); if ( rv != 0 ) { err = WSAGetLastError(); return -1; } return (PRInt32)sock;}PRInt32_PR_MD_SOCKETAVAILABLE(PRFileDesc *fd){ PRUint32 result; if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) { PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError()); return -1; } return result;}/*** _MD_CloseSocket() -- Close a socket***/PRInt32_PR_MD_CLOSE_SOCKET(PRInt32 osfd){ PRInt32 rv; rv = closesocket((SOCKET) osfd ); if (rv < 0) _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError()); return rv;}PRInt32 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog){ int rv, err; rv = listen(fd->secret->md.osfd, backlog); if ( rv == SOCKET_ERROR ) { _PR_MD_MAP_LISTEN_ERROR(WSAGetLastError()); return(-1); } return(rv);}PRInt32_PR_MD_ACCEPT(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout ){ PRInt32 osfd = fd->secret->md.osfd; PRThread *me = _PR_MD_CURRENT_THREAD(); PRInt32 err; PRIntn rv; MD_ASSERTINT( *addrlen ); while ((rv = (SOCKET)accept(osfd, (struct sockaddr *) addr, (int *)addrlen)) == INVALID_SOCKET ) { err = WSAGetLastError(); if ( err == WSAEWOULDBLOCK ) { if (fd->secret->nonblocking) { break; } if (_PR_WaitForFD(osfd, PR_POLL_READ, timeout) == 0) { if ( _PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); } else { PR_SetError(PR_IO_TIMEOUT_ERROR, 0); } rv = -1; goto done; } else if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); rv = -1; goto done; } } else if ((err == WSAEINTR) && (!_PR_PENDING_INTERRUPT(me))){ continue; } else { break; } } if (rv < 0) { _PR_MD_MAP_ACCEPT_ERROR(err); }done: if ( rv == INVALID_SOCKET ) return(-1 ); else return(rv);} /* end _MD_Accept() */PRInt32_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout){ PRInt32 osfd = fd->secret->md.osfd; PRThread *me = _PR_MD_CURRENT_THREAD(); PRInt32 rv, err; while ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) { err = WSAGetLastError(); if (err == WSAEISCONN) { rv = 0; break; } /* for winsock1.1, it reports EALREADY as EINVAL */ if ((err == WSAEWOULDBLOCK) ||(err == WSAEALREADY) || (err = WSAEINVAL)) { if (fd->secret->nonblocking) { break; } if (_PR_WaitForFD(osfd, PR_POLL_WRITE, timeout) == 0) { if ( _PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); } else { PR_SetError(PR_IO_TIMEOUT_ERROR, 0); } rv = -1; goto done; } else if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); rv = -1; goto done; } } else if ((err == WSAEINTR) && (!_PR_PENDING_INTERRUPT(me))){ continue; } else { break; } } if (rv < 0) { _PR_MD_MAP_CONNECT_ERROR(err); }done: return rv;}PRInt32_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen){ PRInt32 rv; int one = 1; rv = bind(fd->secret->md.osfd, (const struct sockaddr *)&(addr->inet), addrlen); if (rv == SOCKET_ERROR) { _PR_MD_MAP_BIND_ERROR(WSAGetLastError()); return -1; } return 0;}PRInt32_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout){ PRInt32 osfd = fd->secret->md.osfd; PRThread *me = _PR_MD_CURRENT_THREAD(); PRInt32 rv, err; while ((rv = recv(osfd,buf,amount,flags)) == -1) { err = WSAGetLastError(); if ( err == WSAEWOULDBLOCK ) { if (fd->secret->nonblocking) { break; } if (_PR_WaitForFD(osfd, PR_POLL_READ, timeout) == 0) { if ( _PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); } else { PR_SetError(PR_IO_TIMEOUT_ERROR, 0); } rv = -1; goto done; } else if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); rv = -1; goto done; } } else if ((err == WSAEINTR) && (!_PR_PENDING_INTERRUPT(me))){ continue; } else { break; } } if (rv < 0) { _PR_MD_MAP_RECV_ERROR(err); }done: return(rv);}PRInt32_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout){ PRInt32 osfd = fd->secret->md.osfd; PRThread *me = _PR_MD_CURRENT_THREAD(); PRInt32 rv, err; while ((rv = send(osfd,buf,amount,flags)) == -1) { err = WSAGetLastError(); if ( err == WSAEWOULDBLOCK ) { if (fd->secret->nonblocking) { break; } if (_PR_WaitForFD(osfd, PR_POLL_WRITE, timeout) == 0) { if ( _PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); } else { PR_SetError(PR_IO_TIMEOUT_ERROR, 0); } rv = -1; goto done; } else if (_PR_PENDING_INTERRUPT(me)) { me->flags &= ~_PR_INTERRUPT; PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); rv = -1; goto done; } } else if ((err == WSAEINTR) && (!_PR_PENDING_INTERRUPT(me))){ continue; } else { break; } } if (rv < 0) { _PR_MD_MAP_SEND_ERROR(err); }done: return rv;}PRInt32_PR_MD_SENDTO(PRFileDesc*fd, const void *buf, PRInt32 amount, PRIntn flags, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout){ PRInt32 osfd = fd->secret->md.osfd; PRThread *me = _PR_MD_CURRENT_THREAD(); PRInt32 rv, err; while ((rv = sendto(osfd, buf, amount, flags, (struct sockaddr *) addr, addrlen)) == -1) { err = WSAGetLastError(); if ( err == WSAEWOULDBLOCK ) { if (fd->secret->nonblocking) { break; } if (_PR_WaitForFD(osfd, PR_POLL_WRITE, timeout) == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -