@@ -587,6 +587,56 @@ JANET_CORE_FN(cfun_net_connect,
587587 net_sched_connect (stream );
588588}
589589
590+ JANET_CORE_FN (cfun_net_socket ,
591+ "(net/socket &opt type)" ,
592+ "Creates a new unbound socket. Type is an optional keyword, "
593+ "either a :stream (usually tcp), or :datagram (usually udp). The default is :stream." ) {
594+ janet_arity (argc , 0 , 1 );
595+
596+ int socktype = janet_get_sockettype (argv , argc , 0 );
597+
598+ /* Create socket */
599+ JSock sfd = JSOCKDEFAULT ;
600+ struct addrinfo * ai = NULL ;
601+ struct addrinfo hints ;
602+ memset (& hints , 0 , sizeof (hints ));
603+ hints .ai_family = AF_UNSPEC ;
604+ hints .ai_socktype = socktype ;
605+ hints .ai_flags = 0 ;
606+ int status = getaddrinfo (NULL , "0" , & hints , & ai );
607+ if (status ) {
608+ janet_panicf ("could not get address info: %s" , gai_strerror (status ));
609+ }
610+
611+ struct addrinfo * rp = NULL ;
612+ for (rp = ai ; rp != NULL ; rp = rp -> ai_next ) {
613+ #ifdef JANET_WINDOWS
614+ sfd = WSASocketW (rp -> ai_family , rp -> ai_socktype | JSOCKFLAGS , rp -> ai_protocol , NULL , 0 , WSA_FLAG_OVERLAPPED );
615+ #else
616+ sfd = socket (rp -> ai_family , rp -> ai_socktype | JSOCKFLAGS , rp -> ai_protocol );
617+ #endif
618+ if (JSOCKVALID (sfd )) {
619+ break ;
620+ }
621+ }
622+ freeaddrinfo (ai );
623+
624+ if (!JSOCKVALID (sfd )) {
625+ Janet v = janet_ev_lasterr ();
626+ janet_panicf ("could not create socket: %V" , v );
627+ }
628+
629+ /* Wrap socket in abstract type JanetStream */
630+ uint32_t udp_flag = 0 ;
631+ if (socktype == SOCK_DGRAM ) udp_flag = JANET_STREAM_UDPSERVER ;
632+ JanetStream * stream = make_stream (sfd , JANET_STREAM_READABLE | JANET_STREAM_WRITABLE | udp_flag );
633+
634+ /* Set up the socket for non-blocking IO */
635+ janet_net_socknoblock (sfd );
636+
637+ return janet_wrap_abstract (stream );
638+ }
639+
590640static const char * serverify_socket (JSock sfd , int reuse_addr , int reuse_port ) {
591641 /* Set various socket options */
592642 int enable = 1 ;
@@ -1085,6 +1135,7 @@ void janet_lib_net(JanetTable *env) {
10851135 JanetRegExt net_cfuns [] = {
10861136 JANET_CORE_REG ("net/address" , cfun_net_sockaddr ),
10871137 JANET_CORE_REG ("net/listen" , cfun_net_listen ),
1138+ JANET_CORE_REG ("net/socket" , cfun_net_socket ),
10881139 JANET_CORE_REG ("net/accept" , cfun_stream_accept ),
10891140 JANET_CORE_REG ("net/accept-loop" , cfun_stream_accept_loop ),
10901141 JANET_CORE_REG ("net/read" , cfun_stream_read ),
0 commit comments