Skip to content

Commit

Permalink
Fix splice binding (ygrek#51)
Browse files Browse the repository at this point in the history
Missing Int_val on the offset argument.
  • Loading branch information
chambart authored Nov 24, 2023
1 parent 9b84a56 commit 1996691
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 8 deletions.
3 changes: 3 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## v0.4.2 - ???
* fix splice

## v0.4.1 - 20 Jun 2022
* Support OCaml 5 new Unix primitive names

Expand Down
17 changes: 9 additions & 8 deletions src/splice.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#define EXTUNIX_WANT_SPLICE
#define EXTUNIX_WANT_TEE
#include "config.h"
#include "common.h"

#if defined(EXTUNIX_HAVE_SPLICE) | defined(EXTUNIX_HAVE_TEE) | defined(EXTUNIX_HAVE_VMSPLICE)
static int splice_flags[] =
Expand All @@ -15,11 +16,6 @@ static int splice_flags[] =
#endif

#if defined(EXTUNIX_HAVE_SPLICE)
static loff_t* get_offset(value v_off)
{
return (Is_long(v_off) ? NULL : &(Field(v_off, 0)));
}

CAMLprim value caml_extunix_splice(value v_fd_in, value v_off_in, value v_fd_out, value v_off_out, value v_len, value v_flags)
{
CAMLparam5(v_fd_in, v_off_in, v_fd_out, v_off_out, v_len);
Expand All @@ -28,13 +24,18 @@ CAMLprim value caml_extunix_splice(value v_fd_in, value v_off_in, value v_fd_out
unsigned int flags = caml_convert_flag_list(v_flags, splice_flags);
int fd_in = Int_val(v_fd_in);
int fd_out = Int_val(v_fd_out);
loff_t* off_in = get_offset(v_off_in);
loff_t* off_out = get_offset(v_off_out);
loff_t off_in;
loff_t off_out;
loff_t* off_in_p = NULL;
loff_t* off_out_p = NULL;
size_t len = Int_val(v_len);
ssize_t ret;

if(Is_some(v_off_in)) { off_in = Int_val(Some_val(v_off_in)); off_in_p = &off_in; }
if(Is_some(v_off_out)) { off_out = Int_val(Some_val(v_off_out)); off_out_p = &off_out; }

caml_enter_blocking_section();
ret = splice(fd_in, off_in, fd_out, off_out, len, flags);
ret = splice(fd_in, off_in_p, fd_out, off_out_p, len, flags);
caml_leave_blocking_section();

if (ret == -1)
Expand Down
23 changes: 23 additions & 0 deletions test/test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,28 @@ let test_sysinfo () =
let (_:int) = t.uptime in
()

let test_splice () =
require "splice";
let pipe_out, pipe_in = Unix.pipe ~cloexec:true () in
let name = Filename.temp_file "extunix" "test" in
let fd = Unix.openfile name [O_RDWR; O_CREAT; O_CLOEXEC] 0o666 in
Unix.ftruncate fd (4096 * 2);
assert_equal (Unix.write_substring fd "test0123456789" 0 14) 14;
let n = splice fd (Some 4) pipe_in None 10 [] in
assert(n = 10);
let n = splice pipe_out None fd (Some 4096) 10 [] in
assert(n = 10);
let b = Bytes.create 13 in
let _ = Unix.lseek fd 4096 SEEK_SET in
let n = Unix.read fd b 0 13 in
assert(n = 13);
assert_equal(Bytes.to_string b) "0123456789\000\000\000";
Unix.close fd;
Unix.unlink name;
Unix.close pipe_out;
Unix.close pipe_in;
()

let () =
let wrap test =
with_unix_error (fun () -> test (); Gc.compact ())
Expand Down Expand Up @@ -610,5 +632,6 @@ let () =
"sockopt" >:: test_sockopt;
"sendmsg_bin" >:: test_sendmsg_bin;
"sysinfo" >:: test_sysinfo;
"splice" >:: test_splice;
]) in
ignore (run_test_tt_main (test_decorate wrap tests))

0 comments on commit 1996691

Please sign in to comment.