Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit