@@ -498,34 +498,73 @@ mod _os {
498
498
fd. map ( |fd| fd. 0 ) . map_err ( |e| e. into_pyexception ( vm) )
499
499
}
500
500
501
+ #[ cfg( any( target_os = "linux" , target_os = "macos" ) ) ]
502
+ #[ derive( FromArgs ) ]
503
+ struct SendFileArgs {
504
+ #[ pyarg( any) ]
505
+ out_fd : i32 ,
506
+ #[ pyarg( any) ]
507
+ in_fd : i32 ,
508
+ #[ pyarg( any) ]
509
+ offset : i64 ,
510
+ #[ pyarg( any) ]
511
+ count : i64 ,
512
+ #[ cfg( target_os = "macos" ) ]
513
+ #[ pyarg( any, optional) ]
514
+ headers : OptionalArg < PyObjectRef > ,
515
+ #[ cfg( target_os = "macos" ) ]
516
+ #[ pyarg( any, optional) ]
517
+ trailers : OptionalArg < PyObjectRef > ,
518
+ #[ cfg( target_os = "macos" ) ]
519
+ #[ allow( dead_code) ]
520
+ #[ pyarg( any, default ) ]
521
+ // TODO: not implemented
522
+ flags : OptionalArg < i32 > ,
523
+ }
524
+
501
525
#[ cfg( target_os = "linux" ) ]
502
526
#[ pyfunction]
503
- fn sendfile ( out_fd : i32 , in_fd : i32 , offset : i64 , count : u64 , vm : & VirtualMachine ) -> PyResult {
504
- let mut file_offset = offset;
527
+ fn sendfile ( args : SendFileArgs , vm : & VirtualMachine ) -> PyResult {
528
+ let mut file_offset = args . offset ;
505
529
506
- let res =
507
- nix:: sys:: sendfile:: sendfile ( out_fd, in_fd, Some ( & mut file_offset) , count as usize )
508
- . map_err ( |err| err. into_pyexception ( vm) ) ?;
530
+ let res = nix:: sys:: sendfile:: sendfile (
531
+ args. out_fd ,
532
+ args. in_fd ,
533
+ Some ( & mut file_offset) ,
534
+ args. count as usize ,
535
+ )
536
+ . map_err ( |err| err. into_pyexception ( vm) ) ?;
509
537
Ok ( vm. ctx . new_int ( res as u64 ) )
510
538
}
511
539
512
540
#[ cfg( target_os = "macos" ) ]
513
- #[ pyfunction]
514
- #[ allow( clippy:: too_many_arguments) ]
515
- fn sendfile (
516
- out_fd : i32 ,
517
- in_fd : i32 ,
518
- offset : i64 ,
519
- count : i64 ,
520
- headers : OptionalArg < PyObjectRef > ,
521
- trailers : OptionalArg < PyObjectRef > ,
522
- _flags : OptionalArg < i32 > ,
541
+ fn _extract_vec_bytes (
542
+ x : OptionalArg ,
523
543
vm : & VirtualMachine ,
524
- ) -> PyResult {
525
- let headers = match headers. into_option ( ) {
526
- Some ( x) => Some ( vm. extract_elements :: < PyBytesLike > ( & x) ?) ,
544
+ ) -> PyResult < Option < Vec < PyBytesLike > > > {
545
+ let inner = match x. into_option ( ) {
546
+ Some ( v) => {
547
+ let v = vm. extract_elements :: < PyBytesLike > ( & v) ?;
548
+ if v. is_empty ( ) {
549
+ None
550
+ } else {
551
+ Some ( v)
552
+ }
553
+ }
527
554
None => None ,
528
555
} ;
556
+ Ok ( inner)
557
+ }
558
+
559
+ #[ cfg( target_os = "macos" ) ]
560
+ #[ pyfunction]
561
+ fn sendfile ( args : SendFileArgs , vm : & VirtualMachine ) -> PyResult {
562
+ let headers = _extract_vec_bytes ( args. headers , vm) ?;
563
+ let count = headers
564
+ . as_ref ( )
565
+ . map ( |v| v. iter ( ) . map ( |s| s. len ( ) ) . sum ( ) )
566
+ . unwrap_or ( 0 ) as i64
567
+ + args. count ;
529
568
530
569
let headers = headers
531
570
. as_ref ( )
@@ -535,10 +574,7 @@ mod _os {
535
574
. map ( |v| v. iter ( ) . map ( |borrowed| & * * borrowed) . collect :: < Vec < _ > > ( ) ) ;
536
575
let headers = headers. as_deref ( ) ;
537
576
538
- let trailers = match trailers. into_option ( ) {
539
- Some ( x) => Some ( vm. extract_elements :: < PyBytesLike > ( & x) ?) ,
540
- None => None ,
541
- } ;
577
+ let trailers = _extract_vec_bytes ( args. trailers , vm) ?;
542
578
543
579
let trailers = trailers
544
580
. as_ref ( )
@@ -548,8 +584,14 @@ mod _os {
548
584
. map ( |v| v. iter ( ) . map ( |borrowed| & * * borrowed) . collect :: < Vec < _ > > ( ) ) ;
549
585
let trailers = trailers. as_deref ( ) ;
550
586
551
- let ( res, written) =
552
- nix:: sys:: sendfile:: sendfile ( in_fd, out_fd, offset, Some ( count) , headers, trailers) ;
587
+ let ( res, written) = nix:: sys:: sendfile:: sendfile (
588
+ args. in_fd ,
589
+ args. out_fd ,
590
+ args. offset ,
591
+ Some ( count) ,
592
+ headers,
593
+ trailers,
594
+ ) ;
553
595
res. map_err ( |err| err. into_pyexception ( vm) ) ?;
554
596
Ok ( vm. ctx . new_int ( written as u64 ) )
555
597
}
0 commit comments