@@ -84,6 +84,9 @@ DEFINE_KIND(k_poll);
84
84
#define val_sock (o ) ((SOCKET)(int_val)val_data(o))
85
85
#define val_poll (o ) ((polldata*)val_data(o))
86
86
87
+ static field f_host ;
88
+ static field f_port ;
89
+
87
90
/**
88
91
<doc>
89
92
<h1>Socket</h1>
@@ -119,6 +122,8 @@ static value socket_init() {
119
122
init_done = true;
120
123
}
121
124
#endif
125
+ f_host = val_id ("host" );
126
+ f_port = val_id ("port" );
122
127
return val_true ;
123
128
}
124
129
@@ -849,6 +854,83 @@ static value socket_set_fast_send( value s, value f ) {
849
854
return val_null ;
850
855
}
851
856
857
+ /**
858
+ socket_send_to : 'socket -> buf:string -> pos:int -> length:int -> addr:{host:'int32,port:int} -> int
859
+ <doc>
860
+ Send data from an unconnected UDP socket to the given address.
861
+ </doc>
862
+ **/
863
+ static value socket_send_to ( value o , value data , value pos , value len , value vaddr ) {
864
+ int p ,l ,dlen ;
865
+ value host , port ;
866
+ struct sockaddr_in addr ;
867
+ val_check_kind (o ,k_socket );
868
+ val_check (data ,string );
869
+ val_check (pos ,int );
870
+ val_check (len ,int );
871
+ val_check (vaddr ,object );
872
+ host = val_field (vaddr , f_host );
873
+ port = val_field (vaddr , f_port );
874
+ val_check (host ,int32 );
875
+ val_check (port ,int );
876
+ p = val_int (pos );
877
+ l = val_int (len );
878
+ dlen = val_strlen (data );
879
+ memset (& addr ,0 ,sizeof (addr ));
880
+ addr .sin_family = AF_INET ;
881
+ addr .sin_port = htons (val_int (port ));
882
+ * (int * )& addr .sin_addr .s_addr = val_int32 (host );
883
+ if ( p < 0 || l < 0 || p > dlen || p + l > dlen )
884
+ neko_error ();
885
+ POSIX_LABEL (send_again );
886
+ dlen = sendto (val_sock (o ), val_string (data ) + p , l , MSG_NOSIGNAL , (struct sockaddr * )& addr , sizeof (addr ));
887
+ if ( dlen == SOCKET_ERROR ) {
888
+ HANDLE_EINTR (send_again );
889
+ return block_error ();
890
+ }
891
+ return alloc_int (dlen );
892
+ }
893
+
894
+ /**
895
+ socket_recv_from : 'socket -> buf:string -> pos:int -> length:int -> addr:{host:'int32,port:int} -> int
896
+ <doc>
897
+ Read data from an unconnected UDP socket, store the address from which we received data in addr.
898
+ </doc>
899
+ **/
900
+ static value socket_recv_from ( value o , value data , value pos , value len , value addr ) {
901
+ int p ,l ,dlen ,ret ;
902
+ int retry = 0 ;
903
+ struct sockaddr_in saddr ;
904
+ int slen = sizeof (saddr );
905
+ val_check_kind (o ,k_socket );
906
+ val_check (data ,string );
907
+ val_check (pos ,int );
908
+ val_check (len ,int );
909
+ val_check (addr ,object );
910
+ p = val_int (pos );
911
+ l = val_int (len );
912
+ dlen = val_strlen (data );
913
+ if ( p < 0 || l < 0 || p > dlen || p + l > dlen )
914
+ neko_error ();
915
+ POSIX_LABEL (recv_from_again );
916
+ if ( retry ++ > NRETRYS ) {
917
+ sock_tmp t ;
918
+ t .sock = val_sock (o );
919
+ t .buf = val_string (data ) + p ;
920
+ t .size = l ;
921
+ neko_thread_blocking (tmp_recv ,& t );
922
+ ret = t .ret ;
923
+ } else
924
+ ret = recvfrom (val_sock (o ), val_string (data ) + p , l , MSG_NOSIGNAL , (struct sockaddr * )& saddr , & slen );
925
+ if ( ret == SOCKET_ERROR ) {
926
+ HANDLE_EINTR (recv_from_again );
927
+ return block_error ();
928
+ }
929
+ alloc_field (addr ,f_host ,alloc_int32 (* (int * )& saddr .sin_addr ));
930
+ alloc_field (addr ,f_port ,alloc_int (ntohs (saddr .sin_port )));
931
+ return alloc_int (ret );
932
+ }
933
+
852
934
DEFINE_PRIM (socket_init ,0 );
853
935
DEFINE_PRIM (socket_new ,1 );
854
936
DEFINE_PRIM (socket_send ,4 );
@@ -870,6 +952,9 @@ DEFINE_PRIM(socket_shutdown,3);
870
952
DEFINE_PRIM (socket_set_blocking ,2 );
871
953
DEFINE_PRIM (socket_set_fast_send ,2 );
872
954
955
+ DEFINE_PRIM (socket_send_to ,5 );
956
+ DEFINE_PRIM (socket_recv_from ,5 );
957
+
873
958
DEFINE_PRIM (socket_poll_alloc ,1 );
874
959
DEFINE_PRIM (socket_poll ,3 );
875
960
DEFINE_PRIM (socket_poll_prepare ,3 );
0 commit comments