Skip to content

Commit a656c51

Browse files
committed
Add os sendfile function and python test
1 parent 00920ba commit a656c51

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

extra_tests/snippets/stdlib_os.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@
1717
assert_raises(FileNotFoundError,
1818
lambda: os.rename('DOES_NOT_EXIST', 'DOES_NOT_EXIST 2'))
1919

20+
src_fd = os.open('README.md', os.O_RDONLY)
21+
dest_fd = os.open('destination.md', os.O_RDWR | os.O_CREAT)
22+
src_len = os.stat('README.md').st_size
23+
24+
bytes_sent = os.sendfile(dest_fd, src_fd, 0, src_len)
25+
assert src_len == bytes_sent
26+
27+
os.lseek(dest_fd, 0, 0)
28+
assert os.read(src_fd, src_len) == os.read(dest_fd, bytes_sent)
29+
os.close(src_fd)
30+
os.close(dest_fd)
31+
2032
try:
2133
os.open('DOES_NOT_EXIST', 0)
2234
except OSError as err:

vm/src/stdlib/os.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,47 @@ mod _os {
337337
Err(vm.new_os_error("os.open not implemented on this platform".to_owned()))
338338
}
339339

340+
#[cfg(any(target_os = "linux"))]
341+
#[pyfunction]
342+
pub(crate) fn sendfile(
343+
out_fd: i32,
344+
in_fd: i32,
345+
offset: i64,
346+
count: u64,
347+
vm: &VirtualMachine,
348+
) -> PyResult {
349+
let mut file_offset = offset;
350+
351+
let res =
352+
nix::sys::sendfile::sendfile(out_fd, in_fd, Some(&mut file_offset), count as usize)
353+
.map_err(|err| err.into_pyexception(vm))?;
354+
Ok(vm.ctx.new_int(res as u64))
355+
}
356+
357+
#[cfg(any(target_os = "macos"))]
358+
#[pyfunction]
359+
pub(crate) fn sendfile(
360+
out_fd: i64,
361+
in_fd: i64,
362+
offset: u64,
363+
count: u64,
364+
headers: OptionalArg<PyObjectRef>,
365+
trailers: OptionalArg<PyObjectRef>,
366+
flags: OptionalArg<i64>,
367+
vm: &VirtualMachine,
368+
) -> PyResult {
369+
let res = nix::sys::sendfile::sendfile(
370+
in_fd,
371+
out_fd,
372+
offset,
373+
Some(count as usize),
374+
headers,
375+
trailers,
376+
)
377+
.map_err(|err| err.into_pyexception(vm))?;
378+
Ok(vm.ctx.new_int(res as u64))
379+
}
380+
340381
#[pyfunction]
341382
fn error(message: OptionalArg<PyStrRef>, vm: &VirtualMachine) -> PyResult {
342383
let msg = message.map_or("".to_owned(), |msg| msg.borrow_value().to_owned());

0 commit comments

Comments
 (0)