diff options
Diffstat (limited to 'packaging/nacl/ports/sdl-net/nacl.patch')
-rw-r--r-- | packaging/nacl/ports/sdl-net/nacl.patch | 1590 |
1 files changed, 0 insertions, 1590 deletions
diff --git a/packaging/nacl/ports/sdl-net/nacl.patch b/packaging/nacl/ports/sdl-net/nacl.patch deleted file mode 100644 index f07fdcffd..000000000 --- a/packaging/nacl/ports/sdl-net/nacl.patch +++ /dev/null @@ -1,1590 +0,0 @@ -diff -Naur a/Makefile.am b/Makefile.am ---- a/Makefile.am 2007-07-21 09:26:47.000000000 +0400 -+++ b/Makefile.am 2015-11-28 01:09:05.901015000 +0300 -@@ -8,7 +8,7 @@ - - libSDL_net_la_SOURCES = \ - SDLnet.c \ -- SDLnetTCP.c \ -+ SDLnetTCP.cpp \ - SDLnetUDP.c \ - SDLnetselect.c \ - SDLnetsys.h -diff -Naur a/Makefile.in b/Makefile.in ---- a/Makefile.in 2007-07-21 11:55:27.000000000 +0400 -+++ b/Makefile.in 2015-11-28 01:09:18.049151000 +0300 -@@ -244,7 +244,7 @@ - - libSDL_net_la_SOURCES = \ - SDLnet.c \ -- SDLnetTCP.c \ -+ SDLnetTCP.cpp \ - SDLnetUDP.c \ - SDLnetselect.c \ - SDLnetsys.h -diff -Naur a/SDLnetselect.c b/SDLnetselect.c ---- a/SDLnetselect.c 2007-07-02 06:04:03.000000000 +0400 -+++ b/SDLnetselect.c 2015-11-30 00:33:29.895731000 +0300 -@@ -111,109 +111,24 @@ - first. This function returns the number of sockets ready for reading, - or -1 if there was an error with the select() system call. - */ --#ifdef MACOS_OPENTRANSPORT --int SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout) --{ --Uint32 stop; --int numReady; -- -- /* Loop, polling the network devices */ -- -- stop = SDL_GetTicks() + timeout; -- -- do -- { -- OTResult status; -- size_t numBytes; -- int i; -- -- numReady = 0; -- -- for (i = set->numsockets-1;i >= 0;--i) -- { -- status = OTLook( set->sockets[i]->channel ); -- if( status > 0 ) -- { -- switch( status ) -- { -- case T_UDERR: -- OTRcvUDErr( set->sockets[i]->channel , nil); -- break; -- case T_DISCONNECT: -- OTRcvDisconnect( set->sockets[i]->channel, nil ); -- break; -- case T_ORDREL: -- OTRcvOrderlyDisconnect(set->sockets[i]->channel ); -- break; -- case T_CONNECT: -- OTRcvConnect( set->sockets[i]->channel, nil ); -- break; -- -- -- default: -- set->sockets[i]->ready = 1; -- ++numReady; -- } -- } -- else if( OTCountDataBytes(set->sockets[i]->channel, &numBytes ) != kOTNoDataErr ) -- { -- set->sockets[i]->ready = 1; -- ++numReady; -- } -- else -- set->sockets[i]->ready = 0; -- } -- -- } while (!numReady && (SDL_GetTicks() < stop)); - -- return(numReady); --} --#else - int SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout) - { - int i; -- SOCKET maxfd; - int retval; -- struct timeval tv; -- fd_set mask; -- -- /* Find the largest file descriptor */ -- maxfd = 0; -- for ( i=set->numsockets-1; i>=0; --i ) { -- if ( set->sockets[i]->channel > maxfd ) { -- maxfd = set->sockets[i]->channel; -- } -- } -- -- /* Check the file descriptors for available data */ -- do { -- errno = 0; -- -- /* Set up the mask of file descriptors */ -- FD_ZERO(&mask); -- for ( i=set->numsockets-1; i>=0; --i ) { -- FD_SET(set->sockets[i]->channel, &mask); -- } - -- /* Set up the timeout */ -- tv.tv_sec = timeout/1000; -- tv.tv_usec = (timeout%1000)*1000; -+ retval = 0; - -- /* Look! */ -- retval = select(maxfd+1, &mask, NULL, NULL, &tv); -- } while ( errno == EINTR ); -- -- /* Mark all file descriptors ready that have data available */ -- if ( retval > 0 ) { -- for ( i=set->numsockets-1; i>=0; --i ) { -- if ( FD_ISSET(set->sockets[i]->channel, &mask) ) { -- set->sockets[i]->ready = 1; -- } -- } -+ for (i = 0; i < set->numsockets; ++i) { -+ if (set->sockets[i]->ready) -+ retval++; -+ else -+#warning SDLNet_CheckSockets can work only with TCPsockets! -+ SDLNet_TCP_Recv (set->sockets[i], NULL, 0); - } -- return(retval); -+ -+ return retval; - } --#endif /* MACOS_OPENTRANSPORT */ - - /* Free a set of sockets allocated by SDL_NetAllocSocketSet() */ - extern void SDLNet_FreeSocketSet(SDLNet_SocketSet set) -diff -Naur a/SDLnetTCP.c b/SDLnetTCP.c ---- a/SDLnetTCP.c 2007-07-15 09:55:42.000000000 +0400 -+++ b/SDLnetTCP.c 1970-01-01 03:00:00.000000000 +0300 -@@ -1,953 +0,0 @@ --/* -- SDL_net: An example cross-platform network library for use with SDL -- Copyright (C) 1997-2004 Sam Lantinga -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Library General Public -- License as published by the Free Software Foundation; either -- version 2 of the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Library General Public License for more details. -- -- You should have received a copy of the GNU Library General Public -- License along with this library; if not, write to the Free -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- -- Sam Lantinga -- slouken@libsdl.org --*/ -- --/* $Id: SDLnetTCP.c 3280 2007-07-15 05:55:42Z slouken $ */ -- --#include "SDLnetsys.h" --#include "SDL_net.h" -- --/* The network API for TCP sockets */ -- --/* Since the UNIX/Win32/BeOS code is so different from MacOS, -- we'll just have two completely different sections here. --*/ -- --#ifdef MACOS_OPENTRANSPORT -- --#include <Events.h> --#include <Threads.h> --#include <OpenTransport.h> --#include <OpenTptInternet.h> --#include <OTDebug.h> -- --struct _TCPsocket { -- int ready; -- SOCKET channel; -- -- // These are taken from GUSI interface. -- // I'm not sure if it's really necessary here yet -- // ( masahiro minami<elsur@aaa.letter.co.jp> ) -- // ( 01/02/19 ) -- OTEventCode curEvent; -- OTEventCode newEvent; -- OTEventCode event; -- OTEventCode curCompletion; -- OTEventCode newCompletion; -- OTEventCode completion; -- OSStatus error; -- TEndpointInfo info; -- Boolean readShutdown; -- Boolean writeShutdown; -- Boolean connected; -- OTConfigurationRef config; // Master configuration. you can clone this. -- TCPsocket nextListener; -- // ( end of new members --- masahiro minami<elsur@aaa.letter.co.jp> -- -- IPaddress remoteAddress; -- IPaddress localAddress; -- int sflag; -- -- // Maybe we don't need this---- it's from original SDL_net -- // (masahiro minami<elsur@aaa.letter.co.jp>) -- // ( 01/02/20 ) -- int rcvdPassConn; --}; -- --// To be used in WaitNextEvent() here and there.... --// (010311 masahiro minami<elsur@aaa.letter.co.jp>) --EventRecord macEvent; -- --#if TARGET_API_MAC_CARBON --/* for Carbon */ --OTNotifyUPP notifier; --#endif -- --/* Input: ep - endpointref on which to negotiate the option -- enableReuseIPMode - desired option setting - true/false -- Return: kOTNoError indicates that the option was successfully negotiated -- OSStatus is an error if < 0, otherwise, the status field is -- returned and is > 0. -- -- IMPORTANT NOTE: The endpoint is assumed to be in synchronous more, otherwise -- this code will not function as desired --*/ -- --/* --NOTE: As this version is written async way, we don't use this function... --(010526) masahiro minami<elsur@aaa.letter.co.jp> --*/ --/* --OSStatus DoNegotiateIPReuseAddrOption(EndpointRef ep, Boolean enableReuseIPMode) -- --{ -- UInt8 buf[kOTFourByteOptionSize]; // define buffer for fourByte Option size -- TOption* opt; // option ptr to make items easier to access -- TOptMgmt req; -- TOptMgmt ret; -- OSStatus err; -- -- if (!OTIsSynchronous(ep)) -- { -- return (-1); -- } -- opt = (TOption*)buf; // set option ptr to buffer -- req.opt.buf = buf; -- req.opt.len = sizeof(buf); -- req.flags = T_NEGOTIATE; // negotiate for option -- -- ret.opt.buf = buf; -- ret.opt.maxlen = kOTFourByteOptionSize; -- -- opt->level = INET_IP; // dealing with an IP Level function -- opt->name = IP_REUSEADDR; -- opt->len = kOTFourByteOptionSize; -- opt->status = 0; -- *(UInt32*)opt->value = enableReuseIPMode; // set the desired option level, true or false -- -- err = OTOptionManagement(ep, &req, &ret); -- -- // if no error then return the option status value -- if (err == kOTNoError) -- { -- if (opt->status != T_SUCCESS) -- err = opt->status; -- else -- err = kOTNoError; -- } -- -- return err; --} --*/ -- --/* A helper function for Mac OpenTransport support*/ --// This function is a complete copy from GUSI --// ( masahiro minami<elsur@aaa.letter.co.jp> ) --// ( 01/02/19 ) --static __inline__ Uint32 CompleteMask(OTEventCode code) --{ -- return 1 << (code & 0x1F); --} -- --/* Notifier for async OT calls */ --static pascal void AsyncTCPNotifier( TCPsocket sock, OTEventCode code, -- OTResult result, void* cookie ) --{ -- --#ifdef DEBUG_NET -- printf("AsyncTCPNotifier got an event : 0x%8.8x\n", code ); --#endif -- -- switch( code & 0x7f000000L) -- { -- case 0: -- sock->newEvent |= code; -- result = 0; -- break; -- case kCOMPLETEEVENT: -- if(!(code & 0x00FFFFE0 )) -- sock->newCompletion |= CompleteMask( code ); -- if( code == T_OPENCOMPLETE ) -- sock->channel = (SOCKET)(cookie); -- break; -- default: -- if( code != kOTProviderWillClose ) -- result = 0; -- } -- // Do we need these ???? TODO -- // sock->SetAsyncMacError( result ); -- // sock->Wakeup(); --} -- --/* Retrieve OT event */ --// This function is taken from GUSI interface. --// ( 01/02/19 masahiro minami<elsur@aaa.letter.co.jp> ) --static void AsyncTCPPopEvent( TCPsocket sock ) --{ -- // Make sure OT calls are not interrupted -- // Not sure if we really need this. -- OTEnterNotifier( sock->channel ); -- -- sock->event |= (sock->curEvent = sock->newEvent ); -- sock->completion |= ( sock->curCompletion = sock->newCompletion ); -- sock->newEvent = sock->newCompletion = 0; -- -- OTLeaveNotifier( sock->channel ); -- -- if( sock->curEvent & T_UDERR) -- { -- // We just clear the error. -- // Should we feed this back to users ? -- // (TODO ) -- OTRcvUDErr( sock->channel, NULL ); -- --#ifdef DEBUG_NET -- printf("AsyncTCPPopEvent T_UDERR recognized"); --#endif -- } -- -- // Remote is disconnecting... -- if( sock->curEvent & ( T_DISCONNECT | T_ORDREL )) -- { -- sock->readShutdown = true; -- } -- -- if( sock->curEvent &T_CONNECT ) -- { -- // Ignore the info of remote (second parameter). -- // Shoule we care ? -- // (TODO) -- OTRcvConnect( sock->channel, NULL ); -- sock->connected = 1; -- } -- -- if( sock->curEvent & T_ORDREL ) -- { -- OTRcvOrderlyDisconnect( sock->channel ); -- } -- -- if( sock->curEvent & T_DISCONNECT ) -- { -- OTRcvDisconnect( sock->channel, NULL ); -- } -- -- // Do we need to ? -- // (masahiro minami<elsur@aaa.letter.co.jp>) -- //YieldToAnyThread(); --} -- --/* Create a new TCPsocket */ --// Because TCPsocket structure gets bigger and bigger, --// I think we'd better have a constructor function and delete function. --// ( 01/02/25 masahiro minami<elsur@aaa.letter.co.jp> ) --static TCPsocket AsyncTCPNewSocket() --{ -- TCPsocket sock; -- -- sock = (TCPsocket)malloc(sizeof(*sock)); -- if ( sock == NULL ) { -- SDLNet_SetError("Out of memory"); -- return NULL; -- } -- -- sock->newEvent = 0; -- sock->event = 0; -- sock->curEvent = 0; -- sock->newCompletion = 0; -- sock->completion = 0; -- sock->curCompletion = 0; -- //sock->info = NULL; -- sock->readShutdown = sock->writeShutdown = sock->connected = false; -- sock->error = 0; -- sock->config = NULL; -- sock->nextListener = NULL; -- sock->sflag = 0; -- return sock; --} -- --// hmmm.... do we need this ??? --// ( 01/02/25 masahiro minami<elsur@aaa.letter.co.jp>) --static void AsycnTCPDeleteSocket( TCPsocket sock ) --{ -- SDLNet_TCP_Close( sock ); --} --/* Open a TCP network socket -- If 'remote' is NULL, this creates a local server socket on the given port, -- otherwise a TCP connection to the remote host and port is attempted. -- The newly created socket is returned, or NULL if there was an error. -- -- ( re-written by masahiro minami<elsur@aaa.letter.co.jp> -- Now endpoint is created in Async mode. -- 01/02/20 ) --*/ --TCPsocket SDLNet_TCP_Open(IPaddress *ip) --{ -- EndpointRef dummy = NULL; -- -- TCPsocket sock = AsyncTCPNewSocket(); -- if( ! sock) -- return NULL; -- -- // Determin whether bind locally, or connect to remote -- if ( (ip->host != INADDR_NONE) && (ip->host != INADDR_ANY) ) -- { -- // ######## Connect to remote -- OTResult stat; -- InetAddress inAddr; -- TBind bindReq; -- -- // Open endpoint -- sock->error = OTAsyncOpenEndpoint( -- OTCreateConfiguration(kTCPName), NULL, &(sock->info), -- (OTNotifyProcPtr)(AsyncTCPNotifier), -- sock ); -- -- AsyncTCPPopEvent( sock ); -- while( !sock->error && !( sock->completion & CompleteMask(T_OPENCOMPLETE))) -- { -- //SetThreadState( kCurrentThreadID, kReadyThreadState, kNoThreadID ); -- //YieldToAnyThread(); -- //WaitNextEvent(everyEvent, &macEvent, 1, NULL); -- AsyncTCPPopEvent( sock ); -- } -- -- if( !sock->channel ) -- { -- SDLNet_SetError("OTAsyncOpenEndpoint failed --- client socket could not be opened"); -- goto error_return; -- } -- -- // Set blocking mode -- // I'm not sure if this is a good solution.... -- // Check out Apple's sample code, OT Virtual Server -- // ( 010314 masahiro minami<elsur@aaa.letter.co.jp>) -- -- sock->error = OTSetBlocking( sock->channel ); -- if( sock->error != kOTNoError ) -- { -- SDLNet_SetError("OTSetBlocking() returned an error"); -- goto error_return; -- } -- -- // Bind the socket -- OTInitInetAddress(&inAddr, 0, 0 ); -- bindReq.addr.len = sizeof( InetAddress ); -- bindReq.addr.buf = (unsigned char*)&inAddr; -- bindReq.qlen = 0; -- -- sock->error = OTBind( sock->channel, &bindReq, NULL ); -- AsyncTCPPopEvent(sock); -- while( !sock->error && !( sock->completion & CompleteMask(T_BINDCOMPLETE))) -- { -- //YieldToAnyThread(); -- //WaitNextEvent(everyEvent, &macEvent, 1, NULL); -- AsyncTCPPopEvent(sock); -- } -- -- -- switch( stat = OTGetEndpointState( sock->channel )) -- { -- InetAddress inAddr; -- TCall sndCall; -- OTResult res; -- -- case T_OUTCON: -- SDLNet_SetError("SDLNet_Open() failed -- T_OUTCON"); -- goto error_return; -- break; -- case T_IDLE: -- sock->readShutdown = false; -- sock->writeShutdown = false; -- sock->event &=~T_CONNECT; -- -- OTMemzero(&sndCall, sizeof(TCall)); -- OTInitInetAddress(&inAddr, ip->port, ip->host ); -- sndCall.addr.len = sizeof(InetAddress); -- sndCall.addr.buf = (unsigned char*)&inAddr; -- sock->connected = 0; -- res = OTConnect( sock->channel, &sndCall, NULL ); -- AsyncTCPPopEvent(sock); -- while( sock->error == kOTNoDataErr || !sock->connected ) -- AsyncTCPPopEvent(sock); -- break; -- default: -- // What's to be done ? (TODO) -- SDLNet_SetError("SDLNet_TCP_Open() failed -- EndpointState not good"); -- goto error_return; -- -- } -- if( !(sock->event & (T_CONNECT|T_DISCONNECT))) -- goto error_return; -- -- AsyncTCPPopEvent( sock ); -- while( !(sock->event & (T_CONNECT|T_DISCONNECT))) -- { -- AsyncTCPPopEvent( sock ); -- } -- // OTConnect successfull -- if( sock->event & T_CONNECT) -- { -- sock->remoteAddress.host = inAddr.fHost; -- sock->remoteAddress.port = inAddr.fPort; -- sock->sflag = false; -- } -- else -- { -- // OTConnect failed -- sock->event &= ~T_DISCONNECT; -- goto error_return; -- } -- } -- else -- { -- // ######## Bind locally -- TBind bindReq; -- InetAddress inAddr; -- -- // First, get InetInterfaceInfo. -- // I don't search for all of them. -- // Does that matter ? -- -- sock->error = OTAsyncOpenEndpoint( -- OTCreateConfiguration("tilisten, tcp"), NULL, &(sock->info), -- (OTNotifyProcPtr)(AsyncTCPNotifier), -- sock); -- AsyncTCPPopEvent( sock ); -- while( !sock->error && !( sock->completion & CompleteMask( T_OPENCOMPLETE))) -- { -- AsyncTCPPopEvent( sock ); -- } -- -- if( ! sock->channel ) -- { -- SDLNet_SetError("OTAsyncOpenEndpoint failed --- server socket could not be opened"); -- goto error_return; -- } -- -- // Create a master OTConfiguration -- sock->config = OTCreateConfiguration(kTCPName); -- if( ! sock->config ) -- { -- SDLNet_SetError("Could not create master OTConfiguration"); -- goto error_return; -- } -- -- // Bind the socket -- OTInitInetAddress(&inAddr, ip->port, 0 ); -- inAddr.fAddressType = AF_INET; -- bindReq.addr.len = sizeof( InetAddress ); -- bindReq.addr.buf = (unsigned char*)&inAddr; -- bindReq.qlen = 35; // This number is NOT well considered. (TODO) -- sock->localAddress.host = inAddr.fHost; -- sock->localAddress.port = inAddr.fPort; -- sock->sflag = true; -- -- sock->error = OTBind( sock->channel, &bindReq, NULL ); -- AsyncTCPPopEvent(sock); -- while( !sock->error && !( sock->completion & CompleteMask(T_BINDCOMPLETE))) -- { -- AsyncTCPPopEvent(sock); -- } -- if( sock->error != kOTNoError ) -- { -- SDLNet_SetError("Could not bind server socket"); -- goto error_return; -- } -- -- if( dummy ) -- OTCloseProvider( dummy ); -- -- } -- -- sock->ready = 0; -- return sock; -- -- error_return: -- if( dummy ) -- OTCloseProvider( dummy ); -- SDLNet_TCP_Close( sock ); -- return NULL; --} -- --/* Accept an incoming connection on the given server socket. -- The newly created socket is returned, or NULL if there was an error. --*/ --TCPsocket SDLNet_TCP_Accept(TCPsocket server) --{ -- -- /* Only server sockets can accept */ -- if ( ! server->sflag ) { -- SDLNet_SetError("Only server sockets can accept()"); -- return(NULL); -- } -- server->ready = 0; -- -- /* Accept a new TCP connection on a server socket */ -- { -- InetAddress peer; -- TCall peerinfo; -- TCPsocket sock = NULL; -- Boolean mustListen = false; -- OTResult err; -- -- memset(&peerinfo, 0, (sizeof peerinfo )); -- peerinfo.addr.buf = (Uint8 *) &peer; -- peerinfo.addr.maxlen = sizeof(peer); -- -- while( mustListen || !sock ) -- { -- // OTListen -- // We do NOT block ---- right thing ? (TODO) -- err = OTListen( server->channel, &peerinfo ); -- -- if( err ) -- goto error_return; -- else -- { -- mustListen = false; -- sock = AsyncTCPNewSocket(); -- if( ! sock ) -- goto error_return; -- } -- } -- if( sock ) -- { -- // OTAsyncOpenEndpoint -- server->error = OTAsyncOpenEndpoint( OTCloneConfiguration( server->config ), -- NULL, &(sock->info), (OTNotifyProcPtr)AsyncTCPNotifier, sock ); -- AsyncTCPPopEvent( sock ); -- while( !sock->error && !( sock->completion & CompleteMask( T_OPENCOMPLETE))) -- { -- AsyncTCPPopEvent( sock ); -- } -- if( ! sock->channel ) -- { -- mustListen = false; -- goto error_return; -- } -- -- // OTAccept -- server->completion &= ~(CompleteMask(T_ACCEPTCOMPLETE)); -- server->error = OTAccept( server->channel, sock->channel, &peerinfo ); -- AsyncTCPPopEvent( server ); -- while( !(server->completion & CompleteMask(T_ACCEPTCOMPLETE))) -- { -- AsyncTCPPopEvent( server ); -- } -- -- switch( server->error ) -- { -- case kOTLookErr: -- switch( OTLook(server->channel )) -- { -- case T_LISTEN: -- mustListen = true; -- break; -- case T_DISCONNECT: -- goto error_return; -- } -- break; -- case 0: -- sock->nextListener = server->nextListener; -- server->nextListener = sock; -- sock->remoteAddress.host = peer.fHost; -- sock->remoteAddress.port = peer.fPort; -- return sock; -- // accept successful -- break; -- default: -- free( sock ); -- } -- } -- sock->remoteAddress.host = peer.fHost; -- sock->remoteAddress.port = peer.fPort; -- sock->sflag = 0; -- sock->ready = 0; -- -- /* The socket is ready */ -- return(sock); -- -- // Error; close the socket and return -- error_return: -- SDLNet_TCP_Close(sock); -- return(NULL); -- } --} -- --/* Get the IP address of the remote system associated with the socket. -- If the socket is a server socket, this function returns NULL. --*/ --IPaddress *SDLNet_TCP_GetPeerAddress(TCPsocket sock) --{ -- if ( sock->sflag ) { -- return(NULL); -- } -- return(&sock->remoteAddress); --} -- --/* Send 'len' bytes of 'data' over the non-server socket 'sock' -- This function returns the actual amount of data sent. If the return value -- is less than the amount of data sent, then either the remote connection was -- closed, or an unknown socket error occurred. --*/ --int SDLNet_TCP_Send(TCPsocket sock, const void *datap, int len) --{ -- const Uint8 *data = (const Uint8 *)datap; /* For pointer arithmetic */ -- int sent, left; -- -- /* Server sockets are for accepting connections only */ -- if ( sock->sflag ) { -- SDLNet_SetError("Server sockets cannot send"); -- return(-1); -- } -- -- /* Keep sending data until it's sent or an error occurs */ -- left = len; -- sent = 0; -- errno = 0; -- do { -- len = OTSnd(sock->channel, (void *)data, left, 0); -- if (len == kOTFlowErr) -- len = 0; -- if ( len > 0 ) { -- sent += len; -- left -= len; -- data += len; -- } -- // Do we need to ? -- // ( masahiro minami<elsur@aaa.letter.co.jp> ) -- // (TODO) -- //WaitNextEvent(everyEvent, &macEvent, 1, NULL); -- //AsyncTCPPopEvent(sock); -- } while ( (left > 0) && (len > 0) ); -- -- return(sent); --} -- --/* Receive up to 'maxlen' bytes of data over the non-server socket 'sock', -- and store them in the buffer pointed to by 'data'. -- This function returns the actual amount of data received. If the return -- value is less than or equal to zero, then either the remote connection was -- closed, or an unknown socket error occurred. --*/ --int SDLNet_TCP_Recv(TCPsocket sock, void *data, int maxlen) --{ -- int len = 0; -- OSStatus res; -- /* Server sockets are for accepting connections only */ -- if ( sock->sflag ) { -- SDLNet_SetError("Server sockets cannot receive"); -- return(-1); -- } -- -- do -- { -- res = OTRcv(sock->channel, data, maxlen-len, 0); -- if (res > 0) { -- len = res; -- } -- --#ifdef DEBUG_NET -- if ( res != kOTNoDataErr ) -- printf("SDLNet_TCP_Recv received ; %d\n", res ); --#endif -- -- AsyncTCPPopEvent(sock); -- if( res == kOTLookErr ) -- { -- res = OTLook(sock->channel ); -- continue; -- } -- } while ( (len == 0) && (res == kOTNoDataErr) ); -- -- sock->ready = 0; -- if ( len == 0 ) { /* Open Transport error */ --#ifdef DEBUG_NET -- printf("Open Transport error: %d\n", res); --#endif -- return(-1); -- } -- return(len); --} -- --/* Close a TCP network socket */ --void SDLNet_TCP_Close(TCPsocket sock) --{ -- if ( sock != NULL ) { -- if ( sock->channel != INVALID_SOCKET ) { -- //closesocket(sock->channel); -- OTSndOrderlyDisconnect( sock->channel ); -- } -- free(sock); -- } --} -- --#else /* !MACOS_OPENTRANSPORT */ -- --struct _TCPsocket { -- int ready; -- SOCKET channel; -- IPaddress remoteAddress; -- IPaddress localAddress; -- int sflag; --}; -- --/* Open a TCP network socket -- If 'remote' is NULL, this creates a local server socket on the given port, -- otherwise a TCP connection to the remote host and port is attempted. -- The newly created socket is returned, or NULL if there was an error. --*/ --TCPsocket SDLNet_TCP_Open(IPaddress *ip) --{ -- TCPsocket sock; -- struct sockaddr_in sock_addr; -- -- /* Allocate a TCP socket structure */ -- sock = (TCPsocket)malloc(sizeof(*sock)); -- if ( sock == NULL ) { -- SDLNet_SetError("Out of memory"); -- goto error_return; -- } -- -- /* Open the socket */ -- sock->channel = socket(AF_INET, SOCK_STREAM, 0); -- if ( sock->channel == INVALID_SOCKET ) { -- SDLNet_SetError("Couldn't create socket"); -- goto error_return; -- } -- -- /* Connect to remote, or bind locally, as appropriate */ -- if ( (ip->host != INADDR_NONE) && (ip->host != INADDR_ANY) ) { -- -- // ######### Connecting to remote -- -- memset(&sock_addr, 0, sizeof(sock_addr)); -- sock_addr.sin_family = AF_INET; -- sock_addr.sin_addr.s_addr = ip->host; -- sock_addr.sin_port = ip->port; -- -- /* Connect to the remote host */ -- if ( connect(sock->channel, (struct sockaddr *)&sock_addr, -- sizeof(sock_addr)) == SOCKET_ERROR ) { -- SDLNet_SetError("Couldn't connect to remote host"); -- goto error_return; -- } -- sock->sflag = 0; -- } else { -- -- // ########## Binding locally -- -- memset(&sock_addr, 0, sizeof(sock_addr)); -- sock_addr.sin_family = AF_INET; -- sock_addr.sin_addr.s_addr = INADDR_ANY; -- sock_addr.sin_port = ip->port; -- --/* -- * Windows gets bad mojo with SO_REUSEADDR: -- * http://www.devolution.com/pipermail/sdl/2005-September/070491.html -- * --ryan. -- */ --#ifndef WIN32 -- /* allow local address reuse */ -- { int yes = 1; -- setsockopt(sock->channel, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes)); -- } --#endif -- -- /* Bind the socket for listening */ -- if ( bind(sock->channel, (struct sockaddr *)&sock_addr, -- sizeof(sock_addr)) == SOCKET_ERROR ) { -- SDLNet_SetError("Couldn't bind to local port"); -- goto error_return; -- } -- if ( listen(sock->channel, 5) == SOCKET_ERROR ) { -- SDLNet_SetError("Couldn't listen to local port"); -- goto error_return; -- } -- -- /* Set the socket to non-blocking mode for accept() */ --#if defined(__BEOS__) && defined(SO_NONBLOCK) -- /* On BeOS r5 there is O_NONBLOCK but it's for files only */ -- { -- long b = 1; -- setsockopt(sock->channel, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); -- } --#elif defined(O_NONBLOCK) -- { -- fcntl(sock->channel, F_SETFL, O_NONBLOCK); -- } --#elif defined(WIN32) -- { -- unsigned long mode = 1; -- ioctlsocket (sock->channel, FIONBIO, &mode); -- } --#elif defined(__OS2__) -- { -- int dontblock = 1; -- ioctl(sock->channel, FIONBIO, &dontblock); -- } --#else --#warning How do we set non-blocking mode on other operating systems? --#endif -- sock->sflag = 1; -- } -- sock->ready = 0; -- --#ifdef TCP_NODELAY -- /* Set the nodelay TCP option for real-time games */ -- { int yes = 1; -- setsockopt(sock->channel, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)); -- } --#endif /* TCP_NODELAY */ -- -- /* Fill in the channel host address */ -- sock->remoteAddress.host = sock_addr.sin_addr.s_addr; -- sock->remoteAddress.port = sock_addr.sin_port; -- -- /* The socket is ready */ -- return(sock); -- --error_return: -- SDLNet_TCP_Close(sock); -- return(NULL); --} -- --/* Accept an incoming connection on the given server socket. -- The newly created socket is returned, or NULL if there was an error. --*/ --TCPsocket SDLNet_TCP_Accept(TCPsocket server) --{ -- TCPsocket sock; -- struct sockaddr_in sock_addr; -- int sock_alen; -- -- /* Only server sockets can accept */ -- if ( ! server->sflag ) { -- SDLNet_SetError("Only server sockets can accept()"); -- return(NULL); -- } -- server->ready = 0; -- -- /* Allocate a TCP socket structure */ -- sock = (TCPsocket)malloc(sizeof(*sock)); -- if ( sock == NULL ) { -- SDLNet_SetError("Out of memory"); -- goto error_return; -- } -- -- /* Accept a new TCP connection on a server socket */ -- sock_alen = sizeof(sock_addr); -- sock->channel = accept(server->channel, (struct sockaddr *)&sock_addr, --#ifdef USE_GUSI_SOCKETS -- (unsigned int *)&sock_alen); --#else -- &sock_alen); --#endif -- if ( sock->channel == SOCKET_ERROR ) { -- SDLNet_SetError("accept() failed"); -- goto error_return; -- } --#ifdef WIN32 -- { -- /* passing a zero value, socket mode set to block on */ -- unsigned long mode = 0; -- ioctlsocket (sock->channel, FIONBIO, &mode); -- } --#elif defined(O_NONBLOCK) -- { -- int flags = fcntl(sock->channel, F_GETFL, 0); -- fcntl(sock->channel, F_SETFL, flags & ~O_NONBLOCK); -- } --#endif /* WIN32 */ -- sock->remoteAddress.host = sock_addr.sin_addr.s_addr; -- sock->remoteAddress.port = sock_addr.sin_port; -- -- sock->sflag = 0; -- sock->ready = 0; -- -- /* The socket is ready */ -- return(sock); -- --error_return: -- SDLNet_TCP_Close(sock); -- return(NULL); --} -- --/* Get the IP address of the remote system associated with the socket. -- If the socket is a server socket, this function returns NULL. --*/ --IPaddress *SDLNet_TCP_GetPeerAddress(TCPsocket sock) --{ -- if ( sock->sflag ) { -- return(NULL); -- } -- return(&sock->remoteAddress); --} -- --/* Send 'len' bytes of 'data' over the non-server socket 'sock' -- This function returns the actual amount of data sent. If the return value -- is less than the amount of data sent, then either the remote connection was -- closed, or an unknown socket error occurred. --*/ --int SDLNet_TCP_Send(TCPsocket sock, const void *datap, int len) --{ -- const Uint8 *data = (const Uint8 *)datap; /* For pointer arithmetic */ -- int sent, left; -- -- /* Server sockets are for accepting connections only */ -- if ( sock->sflag ) { -- SDLNet_SetError("Server sockets cannot send"); -- return(-1); -- } -- -- /* Keep sending data until it's sent or an error occurs */ -- left = len; -- sent = 0; -- errno = 0; -- do { -- len = send(sock->channel, (const char *) data, left, 0); -- if ( len > 0 ) { -- sent += len; -- left -= len; -- data += len; -- } -- } while ( (left > 0) && ((len > 0) || (errno == EINTR)) ); -- -- return(sent); --} -- --/* Receive up to 'maxlen' bytes of data over the non-server socket 'sock', -- and store them in the buffer pointed to by 'data'. -- This function returns the actual amount of data received. If the return -- value is less than or equal to zero, then either the remote connection was -- closed, or an unknown socket error occurred. --*/ --int SDLNet_TCP_Recv(TCPsocket sock, void *data, int maxlen) --{ -- int len; -- -- /* Server sockets are for accepting connections only */ -- if ( sock->sflag ) { -- SDLNet_SetError("Server sockets cannot receive"); -- return(-1); -- } -- -- errno = 0; -- do { -- len = recv(sock->channel, (char *) data, maxlen, 0); -- } while ( errno == EINTR ); -- -- sock->ready = 0; -- return(len); --} -- --/* Close a TCP network socket */ --void SDLNet_TCP_Close(TCPsocket sock) --{ -- if ( sock != NULL ) { -- if ( sock->channel != INVALID_SOCKET ) { -- closesocket(sock->channel); -- } -- free(sock); -- } --} -- --#endif /* MACOS_OPENTRANSPORT */ -diff -Naur a/SDLnetTCP.cpp b/SDLnetTCP.cpp ---- a/SDLnetTCP.cpp 1970-01-01 03:00:00.000000000 +0300 -+++ b/SDLnetTCP.cpp 2015-11-30 00:34:59.378830000 +0300 -@@ -0,0 +1,483 @@ -+/* -+ SDL_net: An example cross-platform network library for use with SDL -+ Copyright (C) 1997-2004 Sam Lantinga -+ -+ This library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Library General Public -+ License as published by the Free Software Foundation; either -+ version 2 of the License, or (at your option) any later version. -+ -+ This library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Library General Public License for more details. -+ -+ You should have received a copy of the GNU Library General Public -+ License along with this library; if not, write to the Free -+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ -+ Sam Lantinga -+ slouken@libsdl.org -+*/ -+ -+/* $Id: SDLnetTCP.c 3280 2007-07-15 05:55:42Z slouken $ */ -+ -+#include "SDLnetsys.h" -+#include "SDL_net.h" -+ -+#include "ppapi_simple/ps.h" -+#include "ppapi/cpp/tcp_socket.h" -+#include "ppapi/cpp/instance_handle.h" -+#include "ppapi/cpp/message_loop.h" -+#include "ppapi/cpp/instance.h" -+#include "ppapi/c/ppb_net_address.h" -+#include "ppapi/cpp/var.h" -+#include "ppapi/utility/completion_callback_factory.h" -+ -+#include "pthread.h" -+#include <condition_variable> -+#include <mutex> -+ -+/* The network API for TCP sockets */ -+ -+#define BUFFER_SIZE 2000 -+ -+struct _TCPsocket { -+ int ready; -+ pp::TCPSocket channel; -+ IPaddress remoteAddress; -+ IPaddress localAddress; -+ int sflag; -+ -+ bool readInProgress; -+ int bufferAmount; -+ int bufferOffset; -+ char buffer [BUFFER_SIZE]; -+}; -+ -+class SDLNetSynchronizer { -+ public: -+ pp::CompletionCallbackFactory <SDLNetSynchronizer> factory; -+ pp::InstanceHandle handle; -+ pp::Instance instance; -+ -+ static pp::MessageLoop loop; -+ -+ pp::TCPSocket sock_result; -+ int32_t result; -+ bool ready; -+ std::condition_variable cv; -+ std::mutex mtx; -+ -+ SDLNetSynchronizer () : factory (this), handle (PSGetInstanceId ()), instance (PSGetInstanceId ()) { -+ ready = false; -+ if (loop.is_null ()) -+ loop = pp::MessageLoop::GetForMainThread (); -+ } -+ -+ int32_t Connect (pp::TCPSocket &sock, IPaddress *ip_addr) { -+ int32_t code; -+ PP_NetAddress_IPv4 ipv4_addr; -+ IpToIpv4 (ip_addr, &ipv4_addr); -+ -+ pp::CompletionCallback cb = factory.NewCallback ( -+ &SDLNetSynchronizer::ConnectWork, -+ sock, -+ pp::NetAddress (handle, ipv4_addr) -+ ); -+ -+ loop.PostWork (cb, 0); -+ wait (); -+ -+ return result; -+ } -+ -+ int32_t Bind (pp::TCPSocket &sock, IPaddress *ip_addr) { -+ PP_NetAddress_IPv4 ipv4_addr; -+ IpToIpv4 (ip_addr, &ipv4_addr); -+ -+ -+ pp::CompletionCallback cb = factory.NewCallback ( -+ &SDLNetSynchronizer::BindWork, -+ sock, -+ pp::NetAddress (handle, ipv4_addr) -+ ); -+ -+ loop.PostWork (cb, 0); -+ -+ wait (); -+ return result; -+ } -+ -+ int32_t Listen (pp::TCPSocket &sock, int32_t backlog) { -+ -+ pp::CompletionCallback cb = factory.NewCallback ( -+ &SDLNetSynchronizer::ListenWork, -+ sock, backlog -+ ); -+ -+ loop.PostWork (cb, 0); -+ -+ wait (); -+ return result; -+ } -+ -+ void WriteWork (int32_t result, pp::TCPSocket &sock, const char *data, size_t size) { -+ sock.Write ( -+ data, size, -+ factory.NewCallback (&SDLNetSynchronizer::resultCallback) -+ ); -+ } -+ -+ int32_t Write (pp::TCPSocket &sock, const char *data, size_t size) { -+ pp::CompletionCallback cb = factory.NewCallback ( -+ &SDLNetSynchronizer::WriteWork, -+ sock, data, size -+ ); -+ -+ loop.PostWork (cb, 0); -+ -+ wait (); -+ return result; -+ } -+ -+ void ReadAsyncCallback (int32_t result, TCPsocket sock) { -+ if (result <= 0) -+ return; -+ -+ sock->bufferOffset = 0; -+ sock->bufferAmount = result; -+ sock->ready = 1; -+ sock->readInProgress = false; -+ } -+ -+ void ReadAsyncWork (int32_t result, TCPsocket sock) { -+ sock->channel.Read ( -+ sock->buffer, BUFFER_SIZE, -+ factory.NewCallback (&SDLNetSynchronizer::ReadAsyncCallback, sock) -+ ); -+ } -+ -+ void ReadAsync (TCPsocket sock) { -+ pp::CompletionCallback cb = factory.NewCallback ( -+ &SDLNetSynchronizer::ReadAsyncWork, -+ sock -+ ); -+ -+ sock->readInProgress = true; -+ loop.PostWork (cb, 0); -+ } -+ -+ void AcceptWork (int32_t result, pp::TCPSocket &sock) { -+ sock.Accept ( -+ factory.NewCallbackWithOutput (&SDLNetSynchronizer::acceptCallback) -+ ); -+ } -+ -+ pp::TCPSocket Accept (pp::TCPSocket &sock, int32_t &out) { -+ pp::CompletionCallback cb = factory.NewCallback ( -+ &SDLNetSynchronizer::AcceptWork, -+ sock -+ ); -+ -+ loop.PostWork (cb, 0); -+ -+ wait (); -+ out = result; -+ return sock_result; -+ } -+ -+ void IpToIpv4 (IPaddress *ip_addr, PP_NetAddress_IPv4 *ipv4_addr) { -+ ipv4_addr->port = ip_addr->port; -+ for (int i = 0; i < 4; ++i) -+ ipv4_addr->addr[i] = (ip_addr->host >> (8 * i)) & 0xFF; -+ } -+ -+ void NetToIp (pp::NetAddress net_addr, IPaddress *ip_addr) { -+ PP_NetAddress_IPv4 ipv4_addr; -+ net_addr.DescribeAsIPv4Address (&ipv4_addr); -+ Ipv4ToIp (&ipv4_addr, ip_addr); -+ } -+ -+ void Ipv4ToIp (PP_NetAddress_IPv4 *ipv4_addr, IPaddress *ip_addr) { -+ ip_addr->port = ipv4_addr->port; -+ ip_addr->host = 0; -+ for (int i = 0; i < 4; ++i) -+ ip_addr->host ^= (((uint32_t) ipv4_addr->addr[i]) << (8 * i)); -+ } -+ -+ void postMessage (std::string msg) { -+ instance.PostMessage (pp::Var (msg)); -+ } -+ -+ void postMessage (int32_t msg) { -+ instance.PostMessage (pp::Var (msg)); -+ } -+ -+ private: -+ void ConnectWork (int32_t result, pp::TCPSocket &sock, pp::NetAddress &addr) { -+ sock.Connect ( -+ addr, -+ factory.NewCallback (&SDLNetSynchronizer::resultCallback) -+ ); -+ } -+ -+ void BindWork (int32_t result, pp::TCPSocket &sock, pp::NetAddress &addr) { -+ sock.Bind ( -+ addr, -+ factory.NewCallback (&SDLNetSynchronizer::resultCallback) -+ ); -+ } -+ -+ void ListenWork (int32_t result, pp::TCPSocket &sock, int32_t backlog) { -+ sock.Listen ( -+ backlog, -+ factory.NewCallback (&SDLNetSynchronizer::resultCallback) -+ ); -+ } -+ -+ void resultCallback (int32_t res) { -+ result = res; -+ unlock (); -+ } -+ -+ void acceptCallback (int32_t res, pp::TCPSocket sock) { -+ result = res; -+ sock_result = sock; -+ -+ unlock(); -+ } -+ -+ void wait () { -+ std::unique_lock <std::mutex> lck (mtx); -+ while (!ready) -+ cv.wait (lck); -+ ready = false; -+ } -+ -+ void unlock () { -+ std::unique_lock <std::mutex> lck (mtx); -+ ready = true; -+ cv.notify_all (); -+ } -+}; -+ -+pp::MessageLoop SDLNetSynchronizer::loop = pp::MessageLoop (); -+ -+SDLNetSynchronizer *__read_syncer = NULL; -+ -+/* Open a TCP network socket -+ If 'remote' is NULL, this creates a local server socket on the given port, -+ otherwise a TCP connection to the remote host and port is attempted. -+ The newly created socket is returned, or NULL if there was an error. -+*/ -+TCPsocket SDLNet_TCP_Open (IPaddress *ip) -+{ -+ TCPsocket sock; -+ SDLNetSynchronizer syncer; -+ -+ /* Allocate a TCP socket structure */ -+ sock = (TCPsocket)malloc (sizeof (*sock)); -+ if ( sock == NULL ) { -+ SDLNet_SetError ("Out of memory"); -+ goto error_return; -+ } -+ -+ sock->channel = pp::TCPSocket (syncer.handle); -+ -+ /* Connect to remote, or bind locally, as appropriate */ -+ if ( (ip->host != INADDR_NONE) && (ip->host != INADDR_ANY) ) { -+ -+ // ######### Connecting to remote -+ -+ /* Connect to the remote host */ -+ if ( syncer.Connect (sock->channel, ip) != PP_OK ) { -+ SDLNet_SetError("Couldn't connect to remote host"); -+ goto error_return; -+ } -+ sock->sflag = 0; -+ -+ } else { -+ -+ // ########## Binding locally -+ -+ /* Bind the socket for listening */ -+ if ( syncer.Bind (sock->channel, ip) != PP_OK ) { -+ SDLNet_SetError("Couldn't bind to local port"); -+ goto error_return; -+ } -+ -+ if ( syncer.Listen (sock->channel, 5) != PP_OK ) { -+ SDLNet_SetError("Couldn't listen to local port"); -+ goto error_return; -+ } -+ -+ /* Set the socket to non-blocking mode for accept() */ -+ -+ { -+ /* In nacl O_NONBLOCK is defined */ -+ // fcntl(sock->channel, F_SETFL, O_NONBLOCK); -+ } -+ -+ sock->sflag = 1; -+ } -+ -+ sock->readInProgress = 0; -+ sock->ready = 0; -+ sock->bufferOffset = sock->bufferAmount = 0; -+ -+#ifdef TCP_NODELAY -+ /* Set the nodelay TCP option for real-time games */ -+ { int yes = 1; -+ setsockopt(sock->channel, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)); -+ } -+#endif /* TCP_NODELAY */ -+ -+ /* Fill in the channel host address */ -+ sock->remoteAddress = *ip; -+ -+ /* The socket is ready */ -+ return(sock); -+ -+error_return: -+ SDLNet_TCP_Close(sock); -+ return(NULL); -+} -+ -+/* Accept an incoming connection on the given server socket. -+ The newly created socket is returned, or NULL if there was an error. -+*/ -+TCPsocket SDLNet_TCP_Accept(TCPsocket server) -+{ -+ TCPsocket sock; -+ SDLNetSynchronizer syncer; -+ int acc_res; -+ -+ /* Only server sockets can accept */ -+ if ( ! server->sflag ) { -+ SDLNet_SetError("Only server sockets can accept()"); -+ return(NULL); -+ } -+ server->ready = 0; -+ -+ /* Allocate a TCP socket structure */ -+ sock = (TCPsocket)malloc (sizeof (*sock)); -+ if ( sock == NULL ) { -+ SDLNet_SetError("Out of memory"); -+ goto error_return; -+ } -+ -+ /* Accept a new TCP connection on a server socket */ -+ sock->channel = syncer.Accept (server->channel, acc_res); -+ -+ if ( acc_res != PP_OK ) { -+ SDLNet_SetError("accept() failed"); -+ goto error_return; -+ } -+ -+ -+ { -+ /* int flags = fcntl(sock->channel, F_GETFL, 0); -+ fcntl(sock->channel, F_SETFL, flags & ~O_NONBLOCK); */ -+ } -+ -+ syncer.NetToIp ((sock->channel).GetRemoteAddress (), &sock->remoteAddress); -+ -+ sock->sflag = 0; -+ sock->ready = 0; -+ -+ /* The socket is ready */ -+ return(sock); -+ -+error_return: -+ SDLNet_TCP_Close(sock); -+ return(NULL); -+} -+ -+/* Get the IP address of the remote system associated with the socket. -+ If the socket is a server socket, this function returns NULL. -+*/ -+IPaddress *SDLNet_TCP_GetPeerAddress(TCPsocket sock) -+{ -+ if ( sock->sflag ) { -+ return(NULL); -+ } -+ return(&sock->remoteAddress); -+} -+ -+/* Send 'len' bytes of 'data' over the non-server socket 'sock' -+ This function returns the actual amount of data sent. If the return value -+ is less than the amount of data sent, then either the remote connection was -+ closed, or an unknown socket error occurred. -+*/ -+int SDLNet_TCP_Send(TCPsocket sock, const void *datap, int len) -+{ -+ SDLNetSynchronizer syncer; -+ Uint8 *data = (Uint8 *)datap; /* For pointer arithmetic */ -+ int sent, left; -+ -+ /* Server sockets are for accepting connections only */ -+ if ( sock->sflag ) { -+ SDLNet_SetError("Server sockets cannot send"); -+ return(-1); -+ } -+ -+ /* Keep sending data until it's sent or an error occurs */ -+ left = len; -+ sent = 0; -+ errno = 0; -+ do { -+ len = syncer.Write (sock->channel, (const char *) data, left); -+ if ( len > 0 ) { -+ sent += len; -+ left -= len; -+ data += len; -+ } -+ } while ( (left > 0) && (len >= 0 || errno == EINTR) ); -+ -+ return(sent); -+} -+ -+/* Receive up to 'maxlen' bytes of data over the non-server socket 'sock', -+ and store them in the buffer pointed to by 'data'. -+ This function returns the actual amount of data received. If the return -+ value is less than or equal to zero, then either the remote connection was -+ closed, or an unknown socket error occurred. -+*/ -+int SDLNet_TCP_Recv(TCPsocket sock, void *data, int maxlen) -+{ -+ SDLNetSynchronizer syncer; -+ int len = 0; -+ -+ /* Server sockets are for accepting connections only */ -+ if ( sock->sflag ) { -+ SDLNet_SetError("Server sockets cannot receive"); -+ return(-1); -+ } -+ -+ if ( sock->ready && maxlen > 0 ) { -+ len = std::min (sock->bufferAmount - sock->bufferOffset, maxlen); -+ memcpy (data, sock->buffer + sock->bufferOffset, len); -+ sock->bufferOffset += len; -+ if ( sock->bufferOffset == sock->bufferAmount ) -+ sock->ready = 0; -+ } -+ -+ if ( sock->ready == 0 && sock->readInProgress == 0) { -+ if (__read_syncer == NULL) -+ __read_syncer = new SDLNetSynchronizer (); -+ __read_syncer->ReadAsync (sock); -+ } -+ -+ return(len); -+} -+ -+/* Close a TCP network socket */ -+void SDLNet_TCP_Close(TCPsocket sock) -+{ -+ SDLNetSynchronizer syncer; -+ if ( sock != NULL ) { -+ sock->channel.Close (); -+ free (sock); -+ } -+} |