Author: Armin Rigo <[email protected]>
Branch:
Changeset: r90562:c979853a3b6a
Date: 2017-03-05 12:19 +0100
http://bitbucket.org/pypy/pypy/changeset/c979853a3b6a/
Log: Basics of sendfile()
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -254,6 +254,7 @@
PRIO_PGRP = rffi_platform.DefinedConstantInteger('PRIO_PGRP')
PRIO_USER = rffi_platform.DefinedConstantInteger('PRIO_USER')
O_NONBLOCK = rffi_platform.DefinedConstantInteger('O_NONBLOCK')
+ OFF_T = rffi_platform.SimpleType('off_t')
OFF_T_SIZE = rffi_platform.SizeOf('off_t')
HAVE_UTIMES = rffi_platform.Has('utimes')
@@ -2427,3 +2428,21 @@
def set_status_flags(fd, flags):
res = c_set_status_flags(fd, flags)
handle_posix_error('set_status_flags', res)
+
+if not _WIN32:
+ sendfile_eci = ExternalCompilationInfo(includes=["sys/sendfile.h"])
+ _OFF_PTR_T = rffi.CArrayPtr(OFF_T)
+ c_sendfile = rffi.llexternal('sendfile',
+ [rffi.INT, rffi.INT, _OFF_PTR_T, rffi.SIZE_T],
+ rffi.SSIZE_T, compilation_info=sendfile_eci)
+
+ def sendfile(out_fd, in_fd, offset, count):
+ with lltype.scoped_alloc(_OFF_PTR_T.TO, 1) as p_offset:
+ p_offset[0] = rffi.cast(OFF_T, offset)
+ res = c_sendfile(out_fd, in_fd, p_offset, count)
+ return handle_posix_error('sendfile', res)
+
+ def sendfile_no_offset(out_fd, in_fd, count):
+ """Passes offset==NULL; not support on all OSes"""
+ res = c_sendfile(out_fd, in_fd, lltype.nullptr(_OFF_PTR_T.TO), count)
+ return handle_posix_error('sendfile', res)
diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py
--- a/rpython/rlib/test/test_rposix.py
+++ b/rpython/rlib/test/test_rposix.py
@@ -676,3 +676,36 @@
prio = rposix.getpriority(rposix.PRIO_PROCESS, 0)
rposix.setpriority(rposix.PRIO_PROCESS, 0, prio)
py.test.raises(OSError, rposix.getpriority, rposix.PRIO_PGRP, 123456789)
+
+if sys.platform != 'win32':
+ def test_sendfile():
+ from rpython.rlib import rsocket
+ s1, s2 = rsocket.socketpair()
+ relpath = 'test_sendfile'
+ filename = str(udir.join(relpath))
+ fd = os.open(filename, os.O_RDWR|os.O_CREAT, 0777)
+ os.write(fd, 'abcdefghij')
+ res = rposix.sendfile(s1.fd, fd, 3, 5)
+ assert res == 5
+ data = os.read(s2.fd, 10)
+ assert data == 'defgh'
+ os.close(fd)
+ s2.close()
+ s1.close()
+
+if sys.platform.startswith('linux'):
+ def test_sendfile_no_offset():
+ from rpython.rlib import rsocket
+ s1, s2 = rsocket.socketpair()
+ relpath = 'test_sendfile'
+ filename = str(udir.join(relpath))
+ fd = os.open(filename, os.O_RDWR|os.O_CREAT, 0777)
+ os.write(fd, 'abcdefghij')
+ os.lseek(fd, 3, 0)
+ res = rposix.sendfile_no_offset(s1.fd, fd, 5)
+ assert res == 5
+ data = os.read(s2.fd, 10)
+ assert data == 'defgh'
+ os.close(fd)
+ s2.close()
+ s1.close()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit