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

Reply via email to