lib/standard: Added errno and strerror bindings to stdlib.
[nit.git] / lib / socket / socket_c.nit
index 7bf04dc..11bda16 100644 (file)
@@ -28,7 +28,6 @@ in "C Header" `{
        #include <arpa/inet.h>
        #include <netdb.h>
        #include <sys/poll.h>
-       #include <errno.h>
 
        typedef int S_DESCRIPTOR;
        typedef struct sockaddr_in S_ADDR_IN;
@@ -106,24 +105,42 @@ extern FFSocket `{ S_DESCRIPTOR* `}
        new socket(domain: FFSocketAddressFamilies, socketType: FFSocketTypes, protocol: FFSocketProtocolFamilies) `{
                S_DESCRIPTOR *d = NULL; d = (S_DESCRIPTOR*) malloc( sizeof(S_DESCRIPTOR) );
                int ds = socket(domain, socketType, protocol);
+               if(ds == -1){
+                       free(d);
+                       return NULL;
+               }
                memcpy(d, &ds, sizeof(ds));
                return d;
        `}
        fun destroy `{ free(recv); `}
        fun close: Int `{ return close( *recv ); `}
        fun descriptor: Int `{ return *recv; `}
-       fun errno: Int `{ return errno; `}
 
-       fun gethostbyname(n: String): FFSocketHostent import String::to_cstring `{ return gethostbyname(String_to_cstring(n)); `}
+       fun gethostbyname(n: String): FFSocketHostent import String.to_cstring `{ return gethostbyname(String_to_cstring(n)); `}
        fun connect(addrIn: FFSocketAddrIn): Int `{ return connect( *recv, (S_ADDR*)addrIn, sizeof(*addrIn) ); `}
-       fun write(buffer: String): Int import String::to_cstring, String::length `{ return write(*recv, (char*)String_to_cstring(buffer), String_length(buffer)); `}
-
-       fun read: String `{
-               char *c = (char*)malloc(1024);
-               int n = read(*recv, c, 1023);
-               if(n < 0) exit(-1);
-               c[n] = '\0';
-               return NativeString_to_s(c);
+       fun write(buffer: String): Int import String.to_cstring, String.length `{ return write(*recv, (char*)String_to_cstring(buffer), String_length(buffer)); `}
+
+       fun read: String import NativeString.to_s_with_length `{
+               static char c[1024];
+               int n = read(*recv, c, 1024);
+               if(n < 0) {
+                       free(c);
+                       return NativeString_to_s_with_length("",0);
+               }
+               char* ret = malloc(n + 1);
+               memcpy(ret, c, n);
+               ret[n] = '\0';
+               free(c);
+               return NativeString_to_s_with_length(ret, n);
+       `}
+
+       # Sets an option for the socket
+       fun setsockopt(level: FFSocketOptLevels, option_name: FFSocketOptNames, option_value: Int) `{
+               int err = setsockopt(*recv, level, option_name, &option_value, sizeof(int));
+               if(err != 0){
+                       perror("Error on setsockopts : ");
+                       exit(1);
+               }
        `}
 
        fun bind(addrIn: FFSocketAddrIn): Int `{ return bind(*recv, (S_ADDR*)addrIn, sizeof(*addrIn)); `}
@@ -160,7 +177,7 @@ extern FFSocket `{ S_DESCRIPTOR* `}
        private fun i_accept(addrIn: FFSocketAddrIn): FFSocket `{
                S_LEN s = sizeof(S_ADDR);
                S_DESCRIPTOR *d = NULL;
-               d = malloc(sizeof(S_DESCRIPTOR*));
+               d = malloc(sizeof(S_DESCRIPTOR));
                *d = accept(*recv,(S_ADDR*)addrIn, &s);
                return d;
        `}
@@ -175,7 +192,7 @@ end
 extern FFSocketAcceptResult `{ S_ACCEPT_RESULT* `}
        new (socket: FFSocket, addrIn: FFSocketAddrIn) `{
                S_ACCEPT_RESULT *sar = NULL;
-               sar = malloc( sizeof(S_ACCEPT_RESULT*) );
+               sar = malloc( sizeof(S_ACCEPT_RESULT) );
                sar->s_desc = *socket;
                sar->addr_in = *addrIn;
                return sar;
@@ -188,12 +205,12 @@ end
 extern FFSocketAddrIn `{ S_ADDR_IN* `}
        new `{
                S_ADDR_IN *sai = NULL;
-               sai = malloc( sizeof(S_ADDR_IN*) );
+               sai = malloc( sizeof(S_ADDR_IN) );
                return sai;
        `}
        new with(port: Int, family: FFSocketAddressFamilies) `{
                S_ADDR_IN *sai = NULL;
-               sai = malloc( sizeof(S_ADDR_IN*) );
+               sai = malloc( sizeof(S_ADDR_IN) );
                sai->sin_family = family;
                sai->sin_port = htons(port);
                sai->sin_addr.s_addr = INADDR_ANY;
@@ -201,20 +218,20 @@ extern FFSocketAddrIn `{ S_ADDR_IN* `}
        `}
        new with_hostent(hostent: FFSocketHostent, port: Int) `{
                S_ADDR_IN *sai = NULL;
-               sai = malloc( sizeof(S_ADDR_IN*) );
+               sai = malloc( sizeof(S_ADDR_IN) );
                sai->sin_family = hostent->h_addrtype;
                sai->sin_port = htons(port);
                memcpy( (char*)&sai->sin_addr.s_addr, (char*)hostent->h_addr, hostent->h_length );
                return sai;
        `}
-       fun address: String `{ return NativeString_to_s( (char*)inet_ntoa(recv->sin_addr) ); `}
+       fun address: String import NativeString.to_s `{ return NativeString_to_s( (char*)inet_ntoa(recv->sin_addr) ); `}
        fun family: FFSocketAddressFamilies `{ return recv->sin_family; `}
        fun port: Int `{ return ntohs(recv->sin_port); `}
        fun destroy `{ free(recv); `}
 end
 
 extern FFSocketHostent `{ S_HOSTENT* `}
-       private fun i_h_aliases(i: Int): String `{ return NativeString_to_s(recv->h_aliases[i]); `}
+       private fun i_h_aliases(i: Int): String import NativeString.to_s `{ return NativeString_to_s(recv->h_aliases[i]); `}
        private fun i_h_aliases_reachable(i: Int): Bool `{ return (recv->h_aliases[i] != NULL); `}
        fun h_aliases: Array[String]
        do
@@ -227,16 +244,16 @@ extern FFSocketHostent `{ S_HOSTENT* `}
                end
                return d
        end
-       fun h_addr: String `{ return NativeString_to_s( (char*)inet_ntoa(*(S_IN_ADDR*)recv->h_addr) ); `}
+       fun h_addr: String import NativeString.to_s `{ return NativeString_to_s( (char*)inet_ntoa(*(S_IN_ADDR*)recv->h_addr) ); `}
        fun h_addrtype: Int `{ return recv->h_addrtype; `}
        fun h_length: Int `{ return recv->h_length; `}
-       fun h_name: String `{ return NativeString_to_s(recv->h_name); `}
+       fun h_name: String import NativeString.to_s `{ return NativeString_to_s(recv->h_name); `}
 end
 
 extern FFTimeval `{ S_TIMEVAL* `}
        new (seconds: Int, microseconds: Int) `{
                S_TIMEVAL* tv = NULL;
-               tv = malloc( sizeof(S_TIMEVAL*) );
+               tv = malloc( sizeof(S_TIMEVAL) );
                tv->tv_sec = seconds;
                tv->tv_usec = microseconds;
                return tv;
@@ -249,7 +266,7 @@ end
 extern FFSocketSet `{ S_FD_SET* `}
        new `{
                S_FD_SET *f = NULL;
-               f = malloc( sizeof(S_FD_SET*) );
+               f = malloc( sizeof(S_FD_SET) );
                return f;
        `}
        fun set(s: FFSocket) `{ FD_SET( *s, recv ); `}
@@ -307,7 +324,28 @@ extern FFSocketProtocolFamilies `{ int `}
        new pf_inet6 `{ return PF_INET6; `}
        new pf_max `{ return PF_MAX; `}
 end
-
+# Level on which to set options
+extern FFSocketOptLevels `{ int `}
+       # Dummy for IP (As defined in C)
+       new ip `{ return IPPROTO_IP;`}
+       # Control message protocol
+       new icmp `{ return IPPROTO_ICMP;`}
+       # Use TCP
+       new tcp `{ return IPPROTO_TCP; `}
+       # Socket level options
+       new socket `{ return SOL_SOCKET; `}
+end
+# Options for socket, use with setsockopt
+extern FFSocketOptNames `{ int `}
+       # Enables debugging information
+       new debug `{ return SO_DEBUG; `}
+       # Authorizes the broadcasting of messages
+       new broadcast `{ return SO_BROADCAST; `}
+       # Authorizes the reuse of the local address
+       new reuseaddr `{ return SO_REUSEADDR; `}
+       # Authorizes the use of keep-alive packets in a connection
+       new keepalive `{ return SO_KEEPALIVE; `}
+end
 # Used for the poll function of a socket, mix several Poll values to check for events on more than one type of event
 extern FFSocketPollValues `{ int `}
        new pollin `{ return POLLIN; `}           # Data other than high-priority data may be read without blocking.