@@ -738,72 +738,6 @@ mod _socket {
738
738
. map ( |sock| sock as RawSocket )
739
739
}
740
740
741
- #[ cfg( unix) ]
742
- mod nullable_socket {
743
- use super :: * ;
744
- use std:: os:: unix:: io:: AsRawFd ;
745
-
746
- #[ derive( Debug ) ]
747
- #[ repr( transparent) ]
748
- pub struct NullableSocket ( Option < socket2:: Socket > ) ;
749
- impl From < socket2:: Socket > for NullableSocket {
750
- fn from ( sock : socket2:: Socket ) -> Self {
751
- NullableSocket ( Some ( sock) )
752
- }
753
- }
754
- impl NullableSocket {
755
- pub fn invalid ( ) -> Self {
756
- Self ( None )
757
- }
758
- pub fn get ( & self ) -> Option < & socket2:: Socket > {
759
- self . 0 . as_ref ( )
760
- }
761
- pub fn fd ( & self ) -> RawSocket {
762
- self . get ( ) . map_or ( INVALID_SOCKET , |sock| sock. as_raw_fd ( ) )
763
- }
764
- pub fn insert ( & mut self , sock : socket2:: Socket ) -> & mut socket2:: Socket {
765
- self . 0 . insert ( sock)
766
- }
767
- }
768
- }
769
- #[ cfg( windows) ]
770
- mod nullable_socket {
771
- use super :: * ;
772
- use std:: os:: windows:: io:: { AsRawSocket , FromRawSocket } ;
773
-
774
- // TODO: may change if windows changes its TcpStream repr
775
- #[ derive( Debug ) ]
776
- #[ repr( transparent) ]
777
- pub struct NullableSocket ( socket2:: Socket ) ;
778
- impl From < socket2:: Socket > for NullableSocket {
779
- fn from ( sock : socket2:: Socket ) -> Self {
780
- NullableSocket ( sock)
781
- }
782
- }
783
- impl NullableSocket {
784
- pub fn invalid ( ) -> Self {
785
- // TODO: may become UB in the future; maybe see rust-lang/rust#74699
786
- Self ( unsafe { socket2:: Socket :: from_raw_socket ( INVALID_SOCKET ) } )
787
- }
788
- pub fn get ( & self ) -> Option < & socket2:: Socket > {
789
- ( self . 0 . as_raw_socket ( ) != INVALID_SOCKET ) . then ( || & self . 0 )
790
- }
791
- pub fn fd ( & self ) -> RawSocket {
792
- self . 0 . as_raw_socket ( )
793
- }
794
- pub fn insert ( & mut self , sock : socket2:: Socket ) -> & mut socket2:: Socket {
795
- self . 0 = sock;
796
- & mut self . 0
797
- }
798
- }
799
- }
800
- use nullable_socket:: NullableSocket ;
801
- impl Default for NullableSocket {
802
- fn default ( ) -> Self {
803
- Self :: invalid ( )
804
- }
805
- }
806
-
807
741
#[ pyattr( name = "socket" ) ]
808
742
#[ pyattr( name = "SocketType" ) ]
809
743
#[ pyclass( name = "socket" ) ]
@@ -813,17 +747,19 @@ mod _socket {
813
747
family : AtomicCell < i32 > ,
814
748
proto : AtomicCell < i32 > ,
815
749
pub ( crate ) timeout : AtomicCell < f64 > ,
816
- sock : PyRwLock < NullableSocket > ,
750
+ sock : PyRwLock < Option < Socket > > ,
817
751
}
818
752
753
+ const _: ( ) = assert ! ( std:: mem:: size_of:: <Option <Socket >>( ) == std:: mem:: size_of:: <Socket >( ) ) ;
754
+
819
755
impl Default for PySocket {
820
756
fn default ( ) -> Self {
821
757
PySocket {
822
758
kind : AtomicCell :: default ( ) ,
823
759
family : AtomicCell :: default ( ) ,
824
760
proto : AtomicCell :: default ( ) ,
825
761
timeout : AtomicCell :: new ( -1.0 ) ,
826
- sock : PyRwLock :: new ( NullableSocket :: invalid ( ) ) ,
762
+ sock : PyRwLock :: new ( None ) ,
827
763
}
828
764
}
829
765
}
@@ -850,7 +786,7 @@ mod _socket {
850
786
851
787
impl PySocket {
852
788
pub fn sock_opt ( & self ) -> Option < PyMappedRwLockReadGuard < ' _ , Socket > > {
853
- PyRwLockReadGuard :: try_map ( self . sock . read ( ) , |sock| sock. get ( ) ) . ok ( )
789
+ PyRwLockReadGuard :: try_map ( self . sock . read ( ) , |sock| sock. as_ref ( ) ) . ok ( )
854
790
}
855
791
856
792
pub fn sock ( & self ) -> io:: Result < PyMappedRwLockReadGuard < ' _ , Socket > > {
@@ -1406,13 +1342,16 @@ mod _socket {
1406
1342
#[ pymethod]
1407
1343
#[ inline]
1408
1344
fn detach ( & self ) -> RawSocket {
1409
- let sock = std :: mem :: replace ( & mut * self . sock . write ( ) , NullableSocket :: invalid ( ) ) ;
1410
- std :: mem :: ManuallyDrop :: new ( sock) . fd ( )
1345
+ let sock = self . sock . write ( ) . take ( ) ;
1346
+ sock. map_or ( INVALID_SOCKET , into_sock_fileno )
1411
1347
}
1412
1348
1413
1349
#[ pymethod]
1414
1350
fn fileno ( & self ) -> RawSocket {
1415
- self . sock . read ( ) . fd ( )
1351
+ self . sock
1352
+ . read ( )
1353
+ . as_ref ( )
1354
+ . map_or ( INVALID_SOCKET , sock_fileno)
1416
1355
}
1417
1356
1418
1357
#[ pymethod]
@@ -1465,38 +1404,47 @@ mod _socket {
1465
1404
name : i32 ,
1466
1405
buflen : OptionalArg < i32 > ,
1467
1406
vm : & VirtualMachine ,
1468
- ) -> PyResult {
1469
- let fd = self . sock . read ( ) . fd ( ) as _ ;
1407
+ ) -> Result < PyObjectRef , IoOrPyException > {
1408
+ let sock = self . sock ( ) ?;
1409
+ let fd = sock_fileno ( & sock) ;
1470
1410
let buflen = buflen. unwrap_or ( 0 ) ;
1471
1411
if buflen == 0 {
1472
1412
let mut flag: libc:: c_int = 0 ;
1473
1413
let mut flagsize = std:: mem:: size_of :: < libc:: c_int > ( ) as _ ;
1474
1414
let ret = unsafe {
1475
1415
c:: getsockopt (
1476
- fd,
1416
+ fd as _ ,
1477
1417
level,
1478
1418
name,
1479
1419
& mut flag as * mut libc:: c_int as * mut _ ,
1480
1420
& mut flagsize,
1481
1421
)
1482
1422
} ;
1483
1423
if ret < 0 {
1484
- return Err ( crate :: vm :: stdlib :: os:: errno_err ( vm ) ) ;
1424
+ return Err ( crate :: common :: os:: errno ( ) . into ( ) ) ;
1485
1425
}
1486
1426
Ok ( vm. ctx . new_int ( flag) . into ( ) )
1487
1427
} else {
1488
1428
if buflen <= 0 || buflen > 1024 {
1489
- return Err ( vm. new_os_error ( "getsockopt buflen out of range" . to_owned ( ) ) ) ;
1429
+ return Err ( vm
1430
+ . new_os_error ( "getsockopt buflen out of range" . to_owned ( ) )
1431
+ . into ( ) ) ;
1490
1432
}
1491
1433
let mut buf = vec ! [ 0u8 ; buflen as usize ] ;
1492
1434
let mut buflen = buflen as _ ;
1493
1435
let ret = unsafe {
1494
- c:: getsockopt ( fd, level, name, buf. as_mut_ptr ( ) as * mut _ , & mut buflen)
1436
+ c:: getsockopt (
1437
+ fd as _ ,
1438
+ level,
1439
+ name,
1440
+ buf. as_mut_ptr ( ) as * mut _ ,
1441
+ & mut buflen,
1442
+ )
1495
1443
} ;
1496
- buf. truncate ( buflen as usize ) ;
1497
1444
if ret < 0 {
1498
- return Err ( crate :: vm :: stdlib :: os:: errno_err ( vm ) ) ;
1445
+ return Err ( crate :: common :: os:: errno ( ) . into ( ) ) ;
1499
1446
}
1447
+ buf. truncate ( buflen as usize ) ;
1500
1448
Ok ( vm. ctx . new_bytes ( buf) . into ( ) )
1501
1449
}
1502
1450
}
@@ -1509,32 +1457,33 @@ mod _socket {
1509
1457
value : Option < Either < ArgBytesLike , i32 > > ,
1510
1458
optlen : OptionalArg < u32 > ,
1511
1459
vm : & VirtualMachine ,
1512
- ) -> PyResult < ( ) > {
1513
- let fd = self . sock . read ( ) . fd ( ) as _ ;
1460
+ ) -> Result < ( ) , IoOrPyException > {
1461
+ let sock = self . sock ( ) ?;
1462
+ let fd = sock_fileno ( & sock) ;
1514
1463
let ret = match ( value, optlen) {
1515
1464
( Some ( Either :: A ( b) ) , OptionalArg :: Missing ) => b. with_ref ( |b| unsafe {
1516
- c:: setsockopt ( fd, level, name, b. as_ptr ( ) as * const _ , b. len ( ) as _ )
1465
+ c:: setsockopt ( fd as _ , level, name, b. as_ptr ( ) as * const _ , b. len ( ) as _ )
1517
1466
} ) ,
1518
1467
( Some ( Either :: B ( ref val) ) , OptionalArg :: Missing ) => unsafe {
1519
1468
c:: setsockopt (
1520
- fd,
1469
+ fd as _ ,
1521
1470
level,
1522
1471
name,
1523
1472
val as * const i32 as * const _ ,
1524
1473
std:: mem:: size_of :: < i32 > ( ) as _ ,
1525
1474
)
1526
1475
} ,
1527
1476
( None , OptionalArg :: Present ( optlen) ) => unsafe {
1528
- c:: setsockopt ( fd, level, name, std:: ptr:: null ( ) , optlen as _ )
1477
+ c:: setsockopt ( fd as _ , level, name, std:: ptr:: null ( ) , optlen as _ )
1529
1478
} ,
1530
1479
_ => {
1531
- return Err (
1532
- vm . new_type_error ( "expected the value arg xor the optlen arg" . to_owned ( ) )
1533
- ) ;
1480
+ return Err ( vm
1481
+ . new_type_error ( "expected the value arg xor the optlen arg" . to_owned ( ) )
1482
+ . into ( ) ) ;
1534
1483
}
1535
1484
} ;
1536
1485
if ret < 0 {
1537
- Err ( crate :: vm :: stdlib :: os:: errno_err ( vm ) )
1486
+ Err ( crate :: common :: os:: errno ( ) . into ( ) )
1538
1487
} else {
1539
1488
Ok ( ( ) )
1540
1489
}
@@ -1573,7 +1522,7 @@ mod _socket {
1573
1522
format ! (
1574
1523
"<socket object, fd={}, family={}, type={}, proto={}>" ,
1575
1524
// cast because INVALID_SOCKET is unsigned, so would show usize::MAX instead of -1
1576
- self . sock . read ( ) . fd ( ) as i64 ,
1525
+ self . fileno ( ) as i64 ,
1577
1526
self . family. load( ) ,
1578
1527
self . kind. load( ) ,
1579
1528
self . proto. load( ) ,
0 commit comments