* list :
[mono.git] / mono / metadata / socket-io.c
index 2acfb158aae2dca20c34a5b17bf8015629253746..aba200d31c5e5c8fa1c37197dd484ce5f14704bc 100644 (file)
@@ -11,6 +11,8 @@
 
 #include <glib.h>
 #include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
 
 #include <mono/metadata/object.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/metadata/appdomain.h>
 
 #include <sys/time.h> 
+
+#ifdef HAVE_NETDB_H
 #include <netdb.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>     /* defines FIONBIO and FIONREAD */
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>    /* defines SIOCATMARK */
+#endif
+
 
 #undef DEBUG
 
@@ -206,6 +218,7 @@ static gint32 convert_proto(MonoProtocolType mono_proto)
                break;
                
        default:
+               break;
        }
 
        return(proto);
@@ -314,15 +327,21 @@ static gint32 convert_sockopt_level_and_name(MonoSocketOptionLevel mono_level,
                case SocketOptionName_IPOptions:
                        *system_name = IP_OPTIONS;
                        break;
+#ifdef IP_HDRINCL
                case SocketOptionName_HeaderIncluded:
                        *system_name = IP_HDRINCL;
                        break;
+#endif
+#ifdef IP_TOS
                case SocketOptionName_TypeOfService:
                        *system_name = IP_TOS;
                        break;
+#endif
+#ifdef IP_TTL
                case SocketOptionName_IpTimeToLive:
                        *system_name = IP_TTL;
                        break;
+#endif
                case SocketOptionName_MulticastInterface:
                        *system_name = IP_MULTICAST_IF;
                        break;
@@ -445,7 +464,7 @@ static MonoException *get_socket_exception(guint32 error_code)
        return(ex);
 }
 
-SOCKET ves_icall_System_Net_Sockets_Socket_Socket_internal(MonoObject *this, gint32 family, gint32 type, gint32 proto)
+gpointer ves_icall_System_Net_Sockets_Socket_Socket_internal(MonoObject *this, gint32 family, gint32 type, gint32 proto)
 {
        SOCKET sock;
        gint32 sock_family;
@@ -488,9 +507,12 @@ SOCKET ves_icall_System_Net_Sockets_Socket_Socket_internal(MonoObject *this, gin
                return(NULL);
        }
        
-       return(sock);
+       return(GUINT_TO_POINTER (sock));
 }
 
+/* FIXME: the SOCKET parameter (here and in other functions in this
+ * file) is really an IntPtr which needs to be converted to a guint32.
+ */
 void ves_icall_System_Net_Sockets_Socket_Close_internal(SOCKET sock)
 {
        closesocket(sock);
@@ -498,7 +520,10 @@ void ves_icall_System_Net_Sockets_Socket_Close_internal(SOCKET sock)
 
 gint32 ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal(void)
 {
+#ifdef DEBUG
        g_message(G_GNUC_PRETTY_FUNCTION ": returning %d", WSAGetLastError());
+#endif
+
        return(WSAGetLastError());
 }
 
@@ -526,7 +551,7 @@ void ves_icall_System_Net_Sockets_Socket_Blocking_internal(SOCKET sock,
        }
 }
 
-SOCKET ves_icall_System_Net_Sockets_Socket_Accept_internal(SOCKET sock)
+gpointer ves_icall_System_Net_Sockets_Socket_Accept_internal(SOCKET sock)
 {
        SOCKET newsock;
        
@@ -536,7 +561,7 @@ SOCKET ves_icall_System_Net_Sockets_Socket_Accept_internal(SOCKET sock)
                return(NULL);
        }
        
-       return(newsock);
+       return(GUINT_TO_POINTER (newsock));
 }
 
 void ves_icall_System_Net_Sockets_Socket_Listen_internal(SOCKET sock,
@@ -777,13 +802,14 @@ gint32 ves_icall_System_Net_Sockets_Socket_RecvFrom_internal(SOCKET sock, MonoAr
        buf=mono_array_addr(buffer, guchar, offset);
        
        ret=recvfrom(sock, buf, count, recvflags, sa, &sa_size);
-       g_free(sa);
        
        if(ret==SOCKET_ERROR) {
+               g_free(sa);
                mono_raise_exception(get_socket_exception(WSAGetLastError()));
        }
 
        *sockaddr=create_object_from_sockaddr(sa, sa_size);
+       g_free(sa);
        
        return(ret);
 }
@@ -854,13 +880,13 @@ gint32 ves_icall_System_Net_Sockets_Socket_SendTo_internal(SOCKET sock, MonoArra
        return(ret);
 }
 
-static SOCKET Socket_to_SOCKET(MonoObject *socket)
+static SOCKET Socket_to_SOCKET(MonoObject *sockobj)
 {
        SOCKET sock;
        MonoClassField *field;
        
-       field=mono_class_get_field_from_name(socket->vtable->klass, "socket");
-       sock=*(SOCKET *)(((char *)socket)+field->offset);
+       field=mono_class_get_field_from_name(sockobj->vtable->klass, "socket");
+       sock=*(SOCKET *)(((char *)sockobj)+field->offset);
 
        return(sock);
 }
@@ -1146,13 +1172,8 @@ void ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal(SOCKET sock, g
                        ret=setsockopt(sock, system_level, system_name,
                                       &linger, valsize);
                        break;
-#ifdef HAVE_IP_ADD_MEMBERSHIP
                case SocketOptionName_AddMembership:
-#endif
-#ifdef HAVE_IP_DROP_MEMBERSHIP
                case SocketOptionName_DropMembership:
-#endif
-#if defined (HAVE_IP_ADD_MEMBERSHIP) || defined (HAVE_IP_DROP_MEMBERSHIP)
                {
 #ifdef HAVE_STRUCT_IP_MREQN
                        struct ip_mreqn mreq;
@@ -1180,7 +1201,6 @@ void ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal(SOCKET sock, g
                                          &mreq, sizeof (mreq));
                        break;
                }
-#endif /* HAVE_IP_[ADD,DROP]_MEMBERSHIP */
                default:
                        /* Throw an exception */
                        mono_raise_exception(get_socket_exception(WSAEINVAL));
@@ -1270,14 +1290,14 @@ static gboolean hostent_to_IPHostEntry(struct hostent *he, MonoString **h_name,
        return(TRUE);
 }
 
-extern gboolean ves_icall_System_Net_Dns_GetHostByName_internal(MonoString *host, MonoString **h_name, MonoArray **h_aliases, MonoArray **h_addr_list)
+extern MonoBoolean ves_icall_System_Net_Dns_GetHostByName_internal(MonoString *host, MonoString **h_name, MonoArray **h_aliases, MonoArray **h_addr_list)
 {
        char *hostname;
        struct hostent *he;
        
        hostname=mono_string_to_utf8(host);
        he=gethostbyname(hostname);
-       free(hostname);
+       g_free(hostname);
        
        if(he==NULL) {
                return(FALSE);
@@ -1302,7 +1322,7 @@ inet_pton (int family, const char *address, void *inaddrp)
 #else
                /* assume the system has inet_addr(), if it doesn't
                   have that we're pretty much screwed... */
-               in_addr_t inaddr;
+               guint32 inaddr;
                
                if (!strcmp (address, "255.255.255.255")) {
                        /* special-case hack */
@@ -1316,17 +1336,16 @@ inet_pton (int family, const char *address, void *inaddrp)
                                return 0;
                }
                
-               memcpy (inaddrp, &inaddr, sizeof (in_addr_t));
+               memcpy (inaddrp, &inaddr, sizeof (guint32));
                return 1;
 #endif /* HAVE_INET_ATON */
        }
        
-       errno = EAFNOSUPPRT;
        return -1;
 }
 #endif /* !HAVE_INET_PTON */
 
-extern gboolean ves_icall_System_Net_Dns_GetHostByAddr_internal(MonoString *addr, MonoString **h_name, MonoArray **h_aliases, MonoArray **h_addr_list)
+extern MonoBoolean ves_icall_System_Net_Dns_GetHostByAddr_internal(MonoString *addr, MonoString **h_name, MonoArray **h_aliases, MonoArray **h_addr_list)
 {
        struct in_addr inaddr;
        struct hostent *he;
@@ -1334,16 +1353,33 @@ extern gboolean ves_icall_System_Net_Dns_GetHostByAddr_internal(MonoString *addr
        
        address = mono_string_to_utf8 (addr);
        if (inet_pton (AF_INET, address, &inaddr) <= 0) {
-               free (address);
+               g_free (address);
                return FALSE;
        }
        
+       g_free (address);
        if ((he = gethostbyaddr ((char *) &inaddr, sizeof (inaddr), AF_INET)) == NULL)
                return FALSE;
        
        return(hostent_to_IPHostEntry(he, h_name, h_aliases, h_addr_list));
 }
 
+extern MonoBoolean ves_icall_System_Net_Dns_GetHostName_internal(MonoString **h_name)
+{
+       guchar hostname[256];
+       int ret;
+       
+       ret=gethostname (hostname, sizeof(hostname));
+       if(ret==-1) {
+               return(FALSE);
+       }
+       
+       *h_name=mono_string_new(mono_domain_get (), hostname);
+
+       return(TRUE);
+}
+
+
 void mono_network_init(void)
 {
        WSADATA wsadata;