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; #if 0 { OTResult state; state = OTGetEndpointState(endpoint); err = OTSndOrderlyDisconnect(endpoint); if (err != kOTNoError && err != kOTOutStateErr) goto ErrorExit; state = OTGetEndpointState(endpoint); err = OTUnbind(endpoint); if (err != kOTNoError && err != kOTOutStateErr) goto ErrorExit; state = OTGetEndpointState(endpoint); err = OTSetSynchronous(endpoint); if (err != kOTNoError) goto ErrorExit; err = OTSetBlocking(endpoint); if (err != kOTNoError) goto ErrorExit; } #endif (void) OTSndOrderlyDisconnect(endpoint); err = OTCloseProvider(endpoint); if (err != kOTNoError) goto ErrorExit; return kOTNoError; ErrorExit: macsock_map_error(err); return -1; }
/* GSocket_Shutdown: * Disallow further read/write operations on this socket, close * the fd and disable all callbacks. */ void GSocket_Shutdown(GSocket *socket) { OSStatus err ; int evt; assert(socket != NULL); /* If socket has been created, shutdown it */ if (socket->m_endpoint != kOTInvalidEndpointRef ) { err = OTSndOrderlyDisconnect( socket->m_endpoint ) ; if ( err != kOTNoError ) { } err = OTRcvOrderlyDisconnect( socket->m_endpoint ) ; err = OTUnbind( socket->m_endpoint ) ; err = OTCloseProvider( socket->m_endpoint ) ; socket->m_endpoint = kOTInvalidEndpointRef ; } /* Disable GUI callbacks */ for (evt = 0; evt < GSOCK_MAX_EVENT; evt++) socket->m_cbacks[evt] = NULL; socket->m_detected = 0; _GSocket_Disable_Events(socket); wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable() , socket ) ; }
/* 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); } }
static void change_connection(OTTCP *x) { // This sets in motion the following sequence of events: // - Disconnect the endpoint // - Unbind the endpoint // - If (x->o_inetHost != 0), bind the endpoint again // - connect the endpoint // Each of these events is triggered in the notifier function when the previous // event completes, so the job of this procedure is just to see what state we're // in and start the process. OTResult r; OSStatus s; ChangeState(x, SETTING_UP); r = OTGetEndpointState(x->o_tcp_ep); if (r == T_UNINIT) { // This shouldn't happen ouchstring("OTTCP: Connect: didn't expect endpoint state to be T_UNINIT!"); } else if (r == T_UNBND) { // Endpoint is already unbound, so we're completely disconnected. // If we have a new inetHost, try to bind it if (x->o_inetHost != 0) { BindTheEndpoint(x); // Now we expect T_BINDCOMPLETE } // Now we expect T_BINDCOMPLETE } else if (r == T_IDLE) { // Endpoint is bound, but not connected. s = OTUnbind(x->o_tcp_ep); if (s != kOTNoError) { post("OTTCP: warning: OTUnbind returned %ld", s); } // Now we expect T_UNBINDCOMPLETE } else if (r == T_OUTCON || r == T_DATAXFER) { // We're either starting a connection or the connection is currently established, // so send an orderly disconnect post ("** Sending orderly disconnect "); s = OTSndOrderlyDisconnect(x->o_tcp_ep); if (s != kOTNoError) { post("OTTCP: warning: OTSndOrderlyDisconnect returned %ld", s); } // I guess now we expect T_DISCONNECTCOMPLETE } else if (r == T_INCON) { ouchstring("OTTCP: Connect: didn't expect endpoint state to be T_INCON!"); } else if (r == T_OUTREL) { // We already tried an orderly disconnect, but it still hasn't been acknowledged, // so screw orderliness and try a regular diconnect TCall call; call.addr.len = 0; call.opt.len = 0; call.udata.len = 0; call.addr.maxlen = 0; call.opt.maxlen = 0; call.udata.maxlen = 0; s = OTSndDisconnect(x->o_tcp_ep, &call); if (s != kOTNoError) { post("OTTCP: warning: OTSndDisconnect returned %ld", s); } // Now we expect T_DISCONNECTCOMPLETE } else if (r == T_INREL) { // Our peer wants an orderly disonnect, so let's acknowlegde it! } else { post(" ะตะตะต Unrecognized endpoint state %ld!", r); } }
/* GSocket_Connect: * For stream (connection oriented) sockets, GSocket_Connect() tries * to establish a client connection to a server using the peer address * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the * connection has been successfully established, or one of the error * codes listed below. Note that for nonblocking sockets, a return * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection * request can be completed later; you should use GSocket_Select() * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the * corresponding asynchronous events. * * For datagram (non connection oriented) sockets, GSocket_Connect() * just sets the peer address established with GSocket_SetPeer() as * default destination. * * Error codes: * GSOCK_INVSOCK - the socket is in use or not valid. * GSOCK_INVADDR - the peer address has not been established. * GSOCK_TIMEDOUT - timeout, the connection failed. * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only) * GSOCK_MEMERR - couldn't allocate memory. * GSOCK_IOERR - low-level error. */ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) { InetAddress addr ; TEndpointInfo info; OSStatus err = kOTNoError; TCall peer ; assert(sck != NULL); /* Enable CONNECTION events (needed for nonblocking connections) */ sck->m_detected &= ~GSOCK_CONNECTION_FLAG; if (sck->m_endpoint != kOTInvalidEndpointRef ) { sck->m_error = GSOCK_INVSOCK; return GSOCK_INVSOCK; } if (!sck->m_peer) { sck->m_error = GSOCK_INVADDR; return GSOCK_INVADDR; } /* Streamed or dgram socket? */ sck->m_stream = (stream == GSOCK_STREAMED); sck->m_oriented = TRUE; sck->m_server = FALSE; /* Create the socket */ #if TARGET_CARBON sck->m_endpoint = OTOpenEndpointInContext( OTCreateConfiguration( kTCPName) , 0 , &info , &err , NULL ) ; #else sck->m_endpoint = OTOpenEndpoint( OTCreateConfiguration( kTCPName) , 0 , &info , &err ) ; #endif if ( sck->m_endpoint == kOTInvalidEndpointRef || err != kOTNoError ) { sck->m_endpoint = kOTInvalidEndpointRef ; sck->m_error = GSOCK_IOERR; return GSOCK_IOERR; } err = OTBind( sck->m_endpoint , nil , nil ) ; if ( err != kOTNoError ) { return GSOCK_IOERR; } SetDefaultEndpointModes( sck->m_endpoint , sck ) ; // TODO #if 0 ioctl(sck->m_endpoint, FIONBIO, &arg); #endif _GSocket_Enable_Events(sck); _GAddress_translate_to( sck->m_peer , &addr ) ; memset( &peer , 0 , sizeof( TCall ) ) ; peer.addr.len = sizeof( InetAddress ) ; peer.addr.buf = (unsigned char*) &addr ; err = OTConnect( sck->m_endpoint , &peer , nil ) ; if ( err != noErr ) { /* If connect failed with EINPROGRESS and the GSocket object * is in blocking mode, we select() for the specified timeout * checking for writability to see if the connection request * completes. */ if ((err == kOTNoDataErr ) && (!sck->m_non_blocking)) { if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT) { OTSndOrderlyDisconnect( sck->m_endpoint ) ; sck->m_endpoint = kOTInvalidEndpointRef ; /* sck->m_error is set in _GSocket_Output_Timeout */ return GSOCK_TIMEDOUT; } else { /* int error; WX_SOCKLEN_T len = sizeof(error); getsockopt(sck->m_endpoint, SOL_SOCKET, SO_ERROR, (void*) &error, &len); if (!error) */ return GSOCK_NOERROR; } } /* If connect failed with EINPROGRESS and the GSocket object * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK * (and return GSOCK_WOULDBLOCK) but we don't close the socket; * this way if the connection completes, a GSOCK_CONNECTION * event will be generated, if enabled. */ if ((err == kOTNoDataErr) && (sck->m_non_blocking)) { sck->m_error = GSOCK_WOULDBLOCK; return GSOCK_WOULDBLOCK; } /* If connect failed with an error other than EINPROGRESS, * then the call to GSocket_Connect has failed. */ OTSndOrderlyDisconnect( sck->m_endpoint ) ; sck->m_endpoint = kOTInvalidEndpointRef ; sck->m_error = GSOCK_IOERR; return GSOCK_IOERR; } // OTInetEventHandler(sck, T_CONNECT , kOTNoError , NULL ) ; return GSOCK_NOERROR; }