2020#include <unistd.h>
2121#include <dirent.h>
2222#include <fcntl.h>
23- #include <pthread.h>
2423#include <arpa/inet.h>
2524#include <netinet/in.h>
2625#include <sys/socket.h>
2928#include <sys/stat.h>
3029#include <sys/time.h>
3130#include <utime.h>
32- #include <signal.h>
33- #include <stdio.h>
3431#include <poll.h>
3532#include <netdb.h>
3633#include <malloc.h>
4138#include <coreinit/systeminfo.h>
4239#include <coreinit/time.h>
4340#include <whb/proc.h>
41+ #include <nn/ac.h>
42+ #include <nsysnet/_socket.h>
43+ #include <nsysnet/_netdb.h>
44+ #include <nsysnet/misc.h>
45+
46+ #define SOCK_ERR_WOULDBLOCK 6
47+ #define SOCK_ERR_PIPE 13
48+ #define SOCK_ERR_INPROGRESS 22
4449
4550const cc_result ReturnCode_FileShareViolation = 1000000000 ; /* TODO: not used apparently */
4651const cc_result ReturnCode_FileNotFound = ENOENT ;
4752const cc_result ReturnCode_PathNotFound = 99999 ;
4853const cc_result ReturnCode_DirectoryExists = EEXIST ;
49- const cc_result ReturnCode_SocketInProgess = EINPROGRESS ;
50- const cc_result ReturnCode_SocketWouldBlock = EWOULDBLOCK ;
51- const cc_result ReturnCode_SocketDropped = EPIPE ;
54+ const cc_result ReturnCode_SocketInProgess = SOCK_ERR_INPROGRESS ;
55+ const cc_result ReturnCode_SocketWouldBlock = SOCK_ERR_WOULDBLOCK ;
56+ const cc_result ReturnCode_SocketDropped = SOCK_ERR_PIPE ;
5257
5358const char * Platform_AppNameSuffix = " Wii U" ;
5459cc_bool Platform_ReadonlyFilesystem ;
@@ -382,7 +387,7 @@ static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int*
382387 String_AppendInt (& portStr , port );
383388 portRaw [portStr .length ] = '\0' ;
384389
385- res = getaddrinfo (host , portRaw , & hints , & result );
390+ res = RPLWRAP ( getaddrinfo ) (host , portRaw , & hints , & result );
386391 if (res == EAI_AGAIN ) return SOCK_ERR_UNKNOWN_HOST ;
387392 if (res ) return res ;
388393
@@ -400,60 +405,71 @@ static cc_result ParseHost(const char* host, int port, cc_sockaddr* addrs, int*
400405 SocketAddr_Set (& addrs [i ], cur -> ai_addr , cur -> ai_addrlen ); i ++ ;
401406 }
402407
403- freeaddrinfo (result );
408+ RPLWRAP ( freeaddrinfo ) (result );
404409 * numValidAddrs = i ;
405410 return i == 0 ? ERR_INVALID_ARGUMENT : 0 ;
406411}
407412
413+ static CC_INLINE int Socket_LastError (void ) {
414+ return RPLWRAP (socketlasterr )();
415+ }
416+
408417cc_result Socket_Create (cc_socket * s , cc_sockaddr * addr , cc_bool nonblocking ) {
409418 struct sockaddr * raw = (struct sockaddr * )addr -> data ;
410419
411- * s = socket (raw -> sa_family , SOCK_STREAM , IPPROTO_TCP );
412- if (* s == -1 ) return errno ;
420+ * s = RPLWRAP ( socket ) (raw -> sa_family , SOCK_STREAM , IPPROTO_TCP );
421+ if (* s < 0 ) return Socket_LastError () ;
413422
414423 if (nonblocking ) {
415- int blocking_raw = - 1 ; /* non-blocking mode */
416- ioctl ( * s , FIONBIO , & blocking_raw );
424+ int nonblock = 1 ; /* non-blocking mode */
425+ RPLWRAP ( setsockopt )( * s , SOL_SOCKET , SO_NONBLOCK , & nonblock , sizeof ( int ) );
417426 }
418427 return 0 ;
419428}
420429
421430cc_result Socket_Connect (cc_socket s , cc_sockaddr * addr ) {
422431 struct sockaddr * raw = (struct sockaddr * )addr -> data ;
423432
424- int res = connect (s , raw , addr -> size );
425- return res == -1 ? errno : 0 ;
433+ int res = RPLWRAP ( connect ) (s , raw , addr -> size );
434+ return res < 0 ? Socket_LastError () : 0 ;
426435}
427436
428437cc_result Socket_Read (cc_socket s , cc_uint8 * data , cc_uint32 count , cc_uint32 * modified ) {
429- int recvCount = recv (s , data , count , 0 );
430- if (recvCount != -1 ) { * modified = recvCount ; return 0 ; }
431- * modified = 0 ; return errno ;
438+ int recvCount = RPLWRAP (recv )(s , data , count , 0 );
439+
440+ * modified = recvCount >= 0 ? recvCount : 0 ;
441+ return recvCount < 0 ? Socket_LastError () : 0 ;
432442}
433443
434444cc_result Socket_Write (cc_socket s , const cc_uint8 * data , cc_uint32 count , cc_uint32 * modified ) {
435- int sentCount = send (s , data , count , 0 );
436- if (sentCount != -1 ) { * modified = sentCount ; return 0 ; }
437- * modified = 0 ; return errno ;
445+ int sentCount = RPLWRAP (send )(s , data , count , 0 );
446+
447+ * modified = sentCount >= 0 ? sentCount : 0 ;
448+ return sentCount < 0 ? Socket_LastError () : 0 ;
438449}
439450
440451void Socket_Close (cc_socket s ) {
441- shutdown (s , SHUT_RDWR );
442- close (s );
452+ RPLWRAP ( shutdown ) (s , SHUT_RDWR );
453+ RPLWRAP ( socketclose ) (s );
443454}
444455
445456static cc_result Socket_Poll (cc_socket s , int mode , cc_bool * success ) {
446- struct pollfd pfd ;
447- int flags ;
457+ nsysnet_fd_set rd_set , wr_set , ex_set ;
458+ struct nsysnet_timeval timeout = { 0 , 0 } ;
448459
449- pfd .fd = s ;
450- pfd .events = mode == SOCKET_POLL_READ ? POLLIN : POLLOUT ;
451- if (poll (& pfd , 1 , 0 ) == -1 ) { * success = false; return errno ; }
452-
453- /* to match select, closed socket still counts as readable */
454- flags = mode == SOCKET_POLL_READ ? (POLLIN | POLLHUP ) : POLLOUT ;
455- * success = (pfd .revents & flags ) != 0 ;
456- return 0 ;
460+ NSYSNET_FD_ZERO (& rd_set );
461+ NSYSNET_FD_ZERO (& wr_set );
462+ NSYSNET_FD_ZERO (& ex_set );
463+
464+ nsysnet_fd_set * set = (mode == SOCKET_POLL_READ ) ? & rd_set : & wr_set ;
465+ NSYSNET_FD_SET (s , set );
466+ int res = RPLWRAP (select )(s + 1 , & rd_set , & wr_set , & ex_set , & timeout );
467+
468+ if (res < 0 ) {
469+ * success = false; return Socket_LastError ();
470+ } else {
471+ * success = NSYSNET_FD_ISSET (s , set ) != 0 ; return 0 ;
472+ }
457473}
458474
459475cc_result Socket_CheckReadable (cc_socket s , cc_bool * readable ) {
@@ -469,17 +485,27 @@ cc_result Socket_GetLastError(cc_socket s) {
469485 socklen_t errSize = sizeof (error );
470486
471487 /* https://stackoverflow.com/questions/29479953/so-error-value-after-successful-socket-operation */
472- getsockopt (s , SOL_SOCKET , SO_ERROR , & error , & errSize );
488+ RPLWRAP ( getsockopt ) (s , SOL_SOCKET , SO_ERROR , & error , & errSize );
473489
474490 // Apparently, actual Wii U hardware returns INPROGRESS error code if connect is still in progress
475- if (error == 22 ) error = 0 ;
491+ if (error == SOCK_ERR_INPROGRESS ) error = 0 ;
476492 return error ;
477493}
478494
479495
480496/*########################################################################################################################*
481497*--------------------------------------------------------Platform---------------------------------------------------------*
482498*#########################################################################################################################*/
499+ void __init_wut_socket ()
500+ {
501+ socket_lib_init ();
502+ set_multicast_state (TRUE);
503+ ACInitialize ();
504+ ACConnectAsync (); // TODO not Async
505+ }
506+
507+ void __fini_wut_socket () { }
508+
483509cc_bool Platform_DescribeError (cc_result res , cc_string * dst ) {
484510 char chars [NATIVE_STR_LEN ];
485511 int len ;
0 commit comments