]> git.mxchange.org Git - simgear.git/blobdiff - simgear/io/sg_socket.cxx
Extended .btg format to support a 'points' primitive.
[simgear.git] / simgear / io / sg_socket.cxx
index c7f70200bfb54471596970ee76bcac8e40c9ecfa..2d9d4eeb5fd56f492f0d684bc23336631e277bb2 100644 (file)
@@ -23,7 +23,7 @@
 
 #include <simgear/compiler.h>
 
-#if !defined(_MSC_VER)
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
 #  include <sys/time.h>                // select()
 #  include <sys/types.h>       // socket(), bind(), select(), accept()
 #  include <sys/socket.h>      // socket(), bind(), listen(), accept()
@@ -48,9 +48,9 @@ SGSocket::SGSocket( const string& host, const string& port,
     port_str(port),
     save_len(0)
 {
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(__MINGW32__)
     if (!wsock_init && !wsastartup()) {
-       FG_LOG( FG_IO, FG_ALERT, "Winsock not available");
+       SG_LOG( SG_IO, SG_ALERT, "Winsock not available");
     }
 #endif
 
@@ -60,7 +60,7 @@ SGSocket::SGSocket( const string& host, const string& port,
        sock_style = SOCK_STREAM;
     } else {
        sock_style = SOCK_DGRAM;
-       FG_LOG( FG_IO, FG_ALERT,
+       SG_LOG( SG_IO, SG_ALERT,
                "Error: SGSocket() unknown style = " << style );
     }
 
@@ -75,7 +75,7 @@ SGSocket::~SGSocket() {
 SGSocket::SocketType SGSocket::make_server_socket () {
     struct sockaddr_in name;
 
-#if defined( __CYGWIN__ ) || defined( __CYGWIN32__ ) || defined( sgi ) || defined( _MSC_VER )
+#if defined( __CYGWIN__ ) || defined( __CYGWIN32__ ) || defined( sgi ) || defined( _MSC_VER ) || defined(__MINGW32__) || defined( __APPLE__ )
     int length;
 #else
     socklen_t length;
@@ -84,7 +84,7 @@ SGSocket::SocketType SGSocket::make_server_socket () {
     // Create the socket.
     sock = socket (PF_INET, sock_style, 0);
     if (sock == INVALID_SOCKET) {
-        FG_LOG( FG_IO, FG_ALERT, 
+        SG_LOG( SG_IO, SG_ALERT, 
                 "Error: socket() failed in make_server_socket()" );
         return INVALID_SOCKET;
     }
@@ -95,7 +95,7 @@ SGSocket::SocketType SGSocket::make_server_socket () {
     name.sin_port = htons(port); // set port to zero to let system pick
     name.sin_addr.s_addr = htonl (INADDR_ANY);
     if (bind (sock, (struct sockaddr *) &name, sizeof (name)) != 0) {
-           FG_LOG( FG_IO, FG_ALERT,
+           SG_LOG( SG_IO, SG_ALERT,
                    "Error: bind() failed in make_server_socket()" );
         return INVALID_SOCKET;
     }
@@ -103,7 +103,7 @@ SGSocket::SocketType SGSocket::make_server_socket () {
     // Find the assigned port number
     length = sizeof(struct sockaddr_in);
     if ( getsockname(sock, (struct sockaddr *) &name, &length) ) {
-       FG_LOG( FG_IO, FG_ALERT,
+       SG_LOG( SG_IO, SG_ALERT,
                "Error: getsockname() failed in make_server_socket()" );
         return INVALID_SOCKET;
     }
@@ -117,12 +117,12 @@ SGSocket::SocketType SGSocket::make_client_socket () {
     struct sockaddr_in name;
     struct hostent *hp;
      
-    FG_LOG( FG_IO, FG_INFO, "Make client socket()" );
+    SG_LOG( SG_IO, SG_INFO, "Make client socket()" );
 
     // Create the socket.
     sock = socket (PF_INET, sock_style, 0);
     if (sock == INVALID_SOCKET) {
-        FG_LOG( FG_IO, FG_ALERT, 
+        SG_LOG( SG_IO, SG_ALERT, 
                 "Error: socket() failed in make_server_socket()" );
         return INVALID_SOCKET;
     }
@@ -132,6 +132,10 @@ SGSocket::SocketType SGSocket::make_client_socket () {
 
     // get the hosts official name/info
     hp = gethostbyname( hostname.c_str() );
+    if (hp == NULL) {
+       SG_LOG( SG_IO, SG_ALERT, "Error: hostname lookup failed" );
+       return INVALID_SOCKET;
+    }
 
     // Connect this socket to the host and the port specified on the
     // command line
@@ -146,7 +150,7 @@ SGSocket::SocketType SGSocket::make_client_socket () {
                 sizeof(struct sockaddr_in)) != 0 )
     {
        closesocket(sock);
-       FG_LOG( FG_IO, FG_ALERT, 
+       SG_LOG( SG_IO, SG_ALERT, 
                "Error: connect() failed in make_client_socket()" );
        return INVALID_SOCKET;
     }
@@ -157,7 +161,7 @@ SGSocket::SocketType SGSocket::make_client_socket () {
 
 // Wrapper functions
 size_t SGSocket::readsocket( int fd, void *buf, size_t count ) {
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(__MINGW32__)
     return ::recv( fd, (char *)buf, count, 0 );
 #else
     return ::read( fd, buf, count );
@@ -165,14 +169,14 @@ size_t SGSocket::readsocket( int fd, void *buf, size_t count ) {
 }
 
 size_t SGSocket::writesocket( int fd, const void *buf, size_t count ) {
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(__MINGW32__)
     return ::send( fd, (const char*)buf, count, 0 );
 #else
     return ::write( fd, buf, count );
 #endif
 }
 
-#if !defined(_MSC_VER)
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
 int SGSocket::closesocket( int fd ) {
     return ::close( fd );
 }
@@ -201,11 +205,11 @@ bool SGSocket::open( const SGProtocolDir d ) {
        // pick any available port.
        sock = make_server_socket();
        if ( sock == INVALID_SOCKET ) {
-           FG_LOG( FG_IO, FG_ALERT, "socket creation failed" );
+           SG_LOG( SG_IO, SG_ALERT, "socket creation failed" );
            return false;
        }
 
-       FG_LOG( FG_IO, FG_INFO, "socket is connected to port = " << port );
+       SG_LOG( SG_IO, SG_INFO, "socket is connected to port = " << port );
 
        if ( sock_style == SOCK_DGRAM ) {
            // Non-blocking UDP
@@ -235,19 +239,19 @@ bool SGSocket::open( const SGProtocolDir d ) {
        sock = make_server_socket();
        // TODO: check for error.
 
-       FG_LOG( FG_IO, FG_INFO, "socket is connected to port = " << port );
+       SG_LOG( SG_IO, SG_INFO, "socket is connected to port = " << port );
 
        // Blocking TCP
        // Specify the maximum length of the connection queue
        listen( sock, SG_MAX_SOCKET_QUEUE );
     } else {
-       FG_LOG( FG_IO, FG_ALERT, 
+       SG_LOG( SG_IO, SG_ALERT, 
                "Error:  bidirection mode not available for UDP sockets." );
        return false;
     }
 
     if ( sock < 0 ) {
-       FG_LOG( FG_IO, FG_ALERT, "Error opening socket: " << hostname
+       SG_LOG( SG_IO, SG_ALERT, "Error opening socket: " << hostname
                << ":" << port );
        return false;
     }
@@ -296,7 +300,7 @@ int SGSocket::read( char *buf, int length ) {
        }
 
        if ( result != length ) {
-           FG_LOG( FG_IO, FG_INFO, 
+           SG_LOG( SG_IO, SG_INFO, 
                    "Warning: read() not enough bytes." );
        }
     }
@@ -335,9 +339,8 @@ int SGSocket::readline( char *buf, int length ) {
            // cout << "sock_stream\n";
            if ( msgsock == INVALID_SOCKET ) {
                // cout << "msgsock == invalid\n";
-               msgsock = accept(sock, 0, 0);
-               closesocket(sock);
-               sock = msgsock;
+               msgsock = sock;
+               sock = accept(msgsock, 0, 0);
            } else {
                // cout << "ready to read\n";
                char *buf_ptr = save_buf + save_len;
@@ -355,10 +358,9 @@ int SGSocket::readline( char *buf, int length ) {
                // could cause problems so if you see connections
                // dropping for unexplained reasons, LOOK HERE!
                if ( result == 0 && save_len == 0 && first_read == true ) {
-                   FG_LOG( FG_IO, FG_ALERT, 
+                   SG_LOG( SG_IO, SG_ALERT, 
                            "Connection closed by foreign host." );
-                   closesocket(sock);
-                   open( get_dir() );
+                    close();
                }
            }
        } else {
@@ -412,7 +414,7 @@ int SGSocket::write( const char *buf, const int length ) {
     bool error_condition = false;
 
     if ( writesocket(sock, buf, length) < 0 ) {
-       FG_LOG( FG_IO, FG_ALERT, "Error writing to socket: " << port );
+       SG_LOG( SG_IO, SG_ALERT, "Error writing to socket: " << port );
        error_condition = true;
     }
 
@@ -433,7 +435,7 @@ int SGSocket::write( const char *buf, const int length ) {
     if ( FD_ISSET(sock, &ready) ) {
        int msgsock = accept(sock, 0, 0);
        if ( msgsock < 0 ) {
-           FG_LOG( FG_IO, FG_ALERT, 
+           SG_LOG( SG_IO, SG_ALERT, 
                    "Error: accept() failed in write()" );
            return 0;
        } else {
@@ -441,7 +443,7 @@ int SGSocket::write( const char *buf, const int length ) {
        }
     }
 
-    FG_LOG( FG_IO, FG_INFO, "Client connections = " << 
+    SG_LOG( SG_IO, SG_INFO, "Client connections = " << 
            client_connections.size() );
     for ( int i = 0; i < (int)client_connections.size(); ++i ) {
        int msgsock = client_connections[i];
@@ -452,7 +454,7 @@ int SGSocket::write( const char *buf, const int length ) {
 
        // write the interesting data to the socket
        if ( writesocket(msgsock, buf, length) == SOCKET_ERROR ) {
-           FG_LOG( FG_IO, FG_ALERT, "Error writing to socket: " << port );
+           SG_LOG( SG_IO, SG_ALERT, "Error writing to socket: " << port );
            error_condition = true;
        } else {
 #ifdef _POSIX_SYNCHRONIZED_IO
@@ -490,6 +492,10 @@ bool SGSocket::close() {
     }
 
     closesocket( sock );
+    if ( sock_style == SOCK_STREAM && msgsock != INVALID_SOCKET ) {
+       sock = msgsock;
+       msgsock = INVALID_SOCKET;
+    }
     return true;
 }
 
@@ -500,11 +506,11 @@ bool SGSocket::nonblock() {
        return 0;
     }
 
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(__MINGW32__)
     u_long arg = 1;
     if (ioctlsocket( sock, FIONBIO, &arg ) != 0) {
         int error_code = WSAGetLastError();
-        FG_LOG( FG_IO, FG_ALERT, 
+        SG_LOG( SG_IO, SG_ALERT, 
                 "Error " << error_code << ": unable to set non-blocking mode"
 );
             return false;
@@ -515,7 +521,7 @@ bool SGSocket::nonblock() {
     return true;
 }
 
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(__MINGW32__)
 
 bool SGSocket::wsock_init = false;
 
@@ -529,14 +535,14 @@ SGSocket::wsastartup() {
     int err = WSAStartup( wVersionRequested, &wsaData );
     if (err != 0)
     {
-        FG_LOG( FG_IO, FG_ALERT, "Error: Couldn't load winsock" );
+        SG_LOG( SG_IO, SG_ALERT, "Error: Couldn't load winsock" );
         return false;
     }
 
 #if 0
     if ( LOBYTE( wsaData.wVersion ) != 2 ||
         HIBYTE( wsaData.wVersion ) != 2 ) {
-        FG_LOG( FG_IO, FG_ALERT, "Couldn't load a suitable winsock");
+        SG_LOG( SG_IO, SG_ALERT, "Couldn't load a suitable winsock");
         WSACleanup( );
         return false;
     }