@@ -481,6 +481,38 @@ int ps2ipc_ps2ip_getconfig(char *netif_name, t_ip_info *ip_info)
481481 return 1 ;
482482}
483483
484+ /* Marshal between the caller's struct fd_set (newlib, ~128 bytes on EE)
485+ * and the on-the-wire ps2ip_rpc_fd_set (MEMP_NUM_NETCONN/8 bytes, fixed
486+ * size on both sides). Bit-by-bit copy avoids any reliance on
487+ * sizeof(struct fd_set) matching across the RPC boundary. */
488+ static void ps2ipc_pack_fdset (ps2ip_rpc_fd_set * dst , struct fd_set * src , int maxfdp1 )
489+ {
490+ int i ;
491+ memset (dst , 0 , sizeof (* dst ));
492+ if (src == NULL ) return ;
493+ if (maxfdp1 > (int )(sizeof (dst -> fd_bits ) * 8 ))
494+ maxfdp1 = (int )(sizeof (dst -> fd_bits ) * 8 );
495+ for (i = 0 ; i < maxfdp1 ; i ++ ) {
496+ if (FD_ISSET (i , src )) {
497+ dst -> fd_bits [i >> 3 ] |= (unsigned char )(1U << (i & 7 ));
498+ }
499+ }
500+ }
501+
502+ static void ps2ipc_unpack_fdset (struct fd_set * dst , const ps2ip_rpc_fd_set * src , int maxfdp1 )
503+ {
504+ int i ;
505+ if (dst == NULL ) return ;
506+ FD_ZERO (dst );
507+ if (maxfdp1 > (int )(sizeof (src -> fd_bits ) * 8 ))
508+ maxfdp1 = (int )(sizeof (src -> fd_bits ) * 8 );
509+ for (i = 0 ; i < maxfdp1 ; i ++ ) {
510+ if (src -> fd_bits [i >> 3 ] & (1U << (i & 7 ))) {
511+ FD_SET (i , dst );
512+ }
513+ }
514+ }
515+
484516int ps2ipc_select (int maxfdp1 , struct fd_set * readset , struct fd_set * writeset , struct fd_set * exceptset , struct timeval * timeout )
485517{
486518 int result ;
@@ -491,21 +523,19 @@ int ps2ipc_select(int maxfdp1, struct fd_set *readset, struct fd_set *writeset,
491523 WaitSema (lock_sema );
492524
493525 pkt -> maxfdp1 = maxfdp1 ;
494- pkt -> readset_p = readset ;
495- pkt -> writeset_p = writeset ;
496- pkt -> exceptset_p = exceptset ;
526+ pkt -> readset_p = ( void * ) readset ;
527+ pkt -> writeset_p = ( void * ) writeset ;
528+ pkt -> exceptset_p = ( void * ) exceptset ;
497529 pkt -> timeout_p = timeout ;
498530 if ( timeout )
499- pkt -> timeout = * timeout ;
500-
501- if ( readset )
502- pkt -> readset = * readset ;
503-
504- if ( writeset )
505- pkt -> writeset = * writeset ;
531+ {
532+ pkt -> timeout_sec = (s32 )timeout -> tv_sec ;
533+ pkt -> timeout_usec = (s32 )timeout -> tv_usec ;
534+ }
506535
507- if ( exceptset )
508- pkt -> exceptset = * exceptset ;
536+ ps2ipc_pack_fdset (& pkt -> readset , readset , maxfdp1 );
537+ ps2ipc_pack_fdset (& pkt -> writeset , writeset , maxfdp1 );
538+ ps2ipc_pack_fdset (& pkt -> exceptset , exceptset , maxfdp1 );
509539
510540 if (sceSifCallRpc (& _ps2ip , PS2IPS_ID_SELECT , 0 , (void * )pkt , sizeof (select_pkt ), (void * )pkt , sizeof (select_pkt ), NULL , NULL ) < 0 )
511541 {
@@ -514,16 +544,14 @@ int ps2ipc_select(int maxfdp1, struct fd_set *readset, struct fd_set *writeset,
514544 }
515545
516546 if ( timeout )
517- * timeout = pkt -> timeout ;
518-
519- if ( readset )
520- * readset = pkt -> readset ;
521-
522- if ( writeset )
523- * writeset = pkt -> writeset ;
547+ {
548+ timeout -> tv_sec = pkt -> timeout_sec ;
549+ timeout -> tv_usec = pkt -> timeout_usec ;
550+ }
524551
525- if ( exceptset )
526- * exceptset = pkt -> exceptset ;
552+ ps2ipc_unpack_fdset (readset , & pkt -> readset , maxfdp1 );
553+ ps2ipc_unpack_fdset (writeset , & pkt -> writeset , maxfdp1 );
554+ ps2ipc_unpack_fdset (exceptset , & pkt -> exceptset , maxfdp1 );
527555
528556 result = pkt -> result ;
529557
0 commit comments