bpo-31368: Expose preadv and pwritev in the os module (#5239)
This commit is contained in:
parent
60da99b8e2
commit
4defba3b95
|
@ -1102,6 +1102,45 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
|
||||||
.. versionadded:: 3.3
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: pwritev(fd, buffers, offset, flags=0)
|
||||||
|
|
||||||
|
Combines the functionality of :func:`os.writev` and :func:`os.pwrite`. It
|
||||||
|
writes the contents of *buffers* to file descriptor *fd* at offset *offset*.
|
||||||
|
*buffers* must be a sequence of :term:`bytes-like objects <bytes-like object>`.
|
||||||
|
Buffers are processed in array order. Entire contents of first buffer is written
|
||||||
|
before proceeding to second, and so on. The operating system may set a limit
|
||||||
|
(sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
|
||||||
|
:func:`~os.pwritev` writes the contents of each object to the file descriptor
|
||||||
|
and returns the total number of bytes written.
|
||||||
|
|
||||||
|
The *flags* argument contains a bitwise OR of zero or more of the following
|
||||||
|
flags:
|
||||||
|
|
||||||
|
- RWF_DSYNC
|
||||||
|
- RWF_SYNC
|
||||||
|
|
||||||
|
Using non-zero flags requires Linux 4.7 or newer.
|
||||||
|
|
||||||
|
Availability: Linux (version 2.6.30), FreeBSD 6.0 and newer,
|
||||||
|
OpenBSD (version 2.7 and newer).
|
||||||
|
|
||||||
|
.. versionadded:: 3.7
|
||||||
|
|
||||||
|
.. data:: RWF_DSYNC (since Linux 4.7)
|
||||||
|
Provide a per-write equivalent of the O_DSYNC open(2) flag. This flag
|
||||||
|
is meaningful only for pwritev2(), and its effect applies only to the
|
||||||
|
data range written by the system call.
|
||||||
|
|
||||||
|
.. versionadded:: 3.7
|
||||||
|
|
||||||
|
.. data:: RWF_SYNC (since Linux 4.7)
|
||||||
|
Provide a per-write equivalent of the O_SYNC open(2) flag. This flag is
|
||||||
|
meaningful only for pwritev2(), and its effect applies only to the data
|
||||||
|
range written by the system call.
|
||||||
|
|
||||||
|
.. versionadded:: 3.7
|
||||||
|
|
||||||
|
|
||||||
.. function:: read(fd, n)
|
.. function:: read(fd, n)
|
||||||
|
|
||||||
Read at most *n* bytes from file descriptor *fd*. Return a bytestring containing the
|
Read at most *n* bytes from file descriptor *fd*. Return a bytestring containing the
|
||||||
|
@ -1196,6 +1235,51 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
|
||||||
.. versionadded:: 3.3
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: preadv(fd, buffers, offset, flags=0)
|
||||||
|
|
||||||
|
Combines the functionality of :func:`os.readv` and :func:`os.pread`. It
|
||||||
|
reads from a file descriptor *fd* into a number of mutable :term:`bytes-like
|
||||||
|
objects <bytes-like object>` *buffers*. As :func:`os.readv`, it will transfer
|
||||||
|
data into each buffer until it is full and then move on to the next buffer in
|
||||||
|
the sequence to hold the rest of the data. Its fourth argument, *offset*,
|
||||||
|
specifies the file offset at which the input operation is to be performed.
|
||||||
|
:func:`~os.preadv` return the total number of bytes read (which can be less than
|
||||||
|
the total capacity of all the objects).
|
||||||
|
|
||||||
|
The flags argument contains a bitwise OR of zero or more of the following
|
||||||
|
flags:
|
||||||
|
|
||||||
|
- RWF_HIPRI
|
||||||
|
- RWF_NOWAIT
|
||||||
|
|
||||||
|
Using non-zero flags requires Linux 4.6 or newer.
|
||||||
|
|
||||||
|
Availability: Linux (version 2.6.30), FreeBSD 6.0 and newer,
|
||||||
|
OpenBSD (version 2.7 and newer).
|
||||||
|
|
||||||
|
.. versionadded:: 3.7
|
||||||
|
|
||||||
|
|
||||||
|
.. data:: RWF_HIPRI (since Linux 4.6)
|
||||||
|
High priority read/write. Allows block-based filesystems to use polling
|
||||||
|
of the device, which provides lower latency, but may use additional
|
||||||
|
resources. (Currently, this feature is usable only on a file descriptor
|
||||||
|
opened using the O_DIRECT flag.)
|
||||||
|
|
||||||
|
.. versionadded:: 3.7
|
||||||
|
|
||||||
|
|
||||||
|
.. data:: RWF_NOWAIT (since Linux 4.14)
|
||||||
|
Do not wait for data which is not immediately available. If this flag
|
||||||
|
is specified, the preadv2() system call will return instantly
|
||||||
|
if it would have to read data from the backing storage or wait for a lock.
|
||||||
|
If some data was successfully read, it will return the number of bytes
|
||||||
|
read. If no bytes were read, it will return -1 and set errno to EAGAIN.
|
||||||
|
Currently, this flag is meaningful only for preadv2().
|
||||||
|
|
||||||
|
.. versionadded:: 3.7
|
||||||
|
|
||||||
|
|
||||||
.. function:: tcgetpgrp(fd)
|
.. function:: tcgetpgrp(fd)
|
||||||
|
|
||||||
Return the process group associated with the terminal given by *fd* (an open
|
Return the process group associated with the terminal given by *fd* (an open
|
||||||
|
|
|
@ -272,6 +272,28 @@ class PosixTester(unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
|
||||||
|
def test_preadv(self):
|
||||||
|
fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
|
||||||
|
try:
|
||||||
|
os.write(fd, b'test1tt2t3t5t6t6t8')
|
||||||
|
buf = [bytearray(i) for i in [5, 3, 2]]
|
||||||
|
self.assertEqual(posix.preadv(fd, buf, 3), 10)
|
||||||
|
self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
|
||||||
|
finally:
|
||||||
|
os.close(fd)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'RWF_HIPRI'), "test needs posix.RWF_HIPRI")
|
||||||
|
def test_preadv_flags(self):
|
||||||
|
fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
|
||||||
|
try:
|
||||||
|
os.write(fd, b'test1tt2t3t5t6t6t8')
|
||||||
|
buf = [bytearray(i) for i in [5, 3, 2]]
|
||||||
|
self.assertEqual(posix.preadv(fd, buf, 3, os.RWF_HIPRI), 10)
|
||||||
|
self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
|
||||||
|
finally:
|
||||||
|
os.close(fd)
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
|
@unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
|
||||||
def test_pwrite(self):
|
def test_pwrite(self):
|
||||||
fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
|
fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
|
||||||
|
@ -283,6 +305,34 @@ class PosixTester(unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
|
||||||
|
def test_pwritev(self):
|
||||||
|
fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
|
||||||
|
try:
|
||||||
|
os.write(fd, b"xx")
|
||||||
|
os.lseek(fd, 0, os.SEEK_SET)
|
||||||
|
n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2)
|
||||||
|
self.assertEqual(n, 10)
|
||||||
|
|
||||||
|
os.lseek(fd, 0, os.SEEK_SET)
|
||||||
|
self.assertEqual(b'xxtest1tt2t3', posix.read(fd, 100))
|
||||||
|
finally:
|
||||||
|
os.close(fd)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'os.RWF_SYNC'), "test needs os.RWF_SYNC")
|
||||||
|
def test_pwritev_flags(self):
|
||||||
|
fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
|
||||||
|
try:
|
||||||
|
os.write(fd,b"xx")
|
||||||
|
os.lseek(fd, 0, os.SEEK_SET)
|
||||||
|
n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2, os.RWF_SYNC)
|
||||||
|
self.assertEqual(n, 10)
|
||||||
|
|
||||||
|
os.lseek(fd, 0, os.SEEK_SET)
|
||||||
|
self.assertEqual(b'xxtest1tt2', posix.read(fd, 100))
|
||||||
|
finally:
|
||||||
|
os.close(fd)
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
|
@unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
|
||||||
"test needs posix.posix_fallocate()")
|
"test needs posix.posix_fallocate()")
|
||||||
def test_posix_fallocate(self):
|
def test_posix_fallocate(self):
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Expose preadv and pwritev system calls in the os module. Patch by Pablo Galindo
|
|
@ -3705,6 +3705,61 @@ exit:
|
||||||
|
|
||||||
#endif /* defined(HAVE_PREAD) */
|
#endif /* defined(HAVE_PREAD) */
|
||||||
|
|
||||||
|
#if (defined(HAVE_PREADV) || defined (HAVE_PREADV2))
|
||||||
|
|
||||||
|
PyDoc_STRVAR(os_preadv__doc__,
|
||||||
|
"preadv($module, fd, buffers, offset, flags=0, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Reads from a file descriptor into a number of mutable bytes-like objects.\n"
|
||||||
|
"\n"
|
||||||
|
"Combines the functionality of readv() and pread(). As readv(), it will\n"
|
||||||
|
"transfer data into each buffer until it is full and then move on to the next\n"
|
||||||
|
"buffer in the sequence to hold the rest of the data. Its fourth argument,\n"
|
||||||
|
"specifies the file offset at which the input operation is to be performed. It\n"
|
||||||
|
"will return the total number of bytes read (which can be less than the total\n"
|
||||||
|
"capacity of all the objects).\n"
|
||||||
|
"\n"
|
||||||
|
"The flags argument contains a bitwise OR of zero or more of the following flags:\n"
|
||||||
|
"\n"
|
||||||
|
"- RWF_HIPRI\n"
|
||||||
|
"- RWF_NOWAIT\n"
|
||||||
|
"\n"
|
||||||
|
"Using non-zero flags requires Linux 4.6 or newer.");
|
||||||
|
|
||||||
|
#define OS_PREADV_METHODDEF \
|
||||||
|
{"preadv", (PyCFunction)os_preadv, METH_FASTCALL, os_preadv__doc__},
|
||||||
|
|
||||||
|
static Py_ssize_t
|
||||||
|
os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
|
||||||
|
int flags);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
os_preadv(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
int fd;
|
||||||
|
PyObject *buffers;
|
||||||
|
Py_off_t offset;
|
||||||
|
int flags = 0;
|
||||||
|
Py_ssize_t _return_value;
|
||||||
|
|
||||||
|
if (!_PyArg_ParseStack(args, nargs, "iOO&|i:preadv",
|
||||||
|
&fd, &buffers, Py_off_t_converter, &offset, &flags)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
_return_value = os_preadv_impl(module, fd, buffers, offset, flags);
|
||||||
|
if ((_return_value == -1) && PyErr_Occurred()) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = PyLong_FromSsize_t(_return_value);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (defined(HAVE_PREADV) || defined (HAVE_PREADV2)) */
|
||||||
|
|
||||||
PyDoc_STRVAR(os_write__doc__,
|
PyDoc_STRVAR(os_write__doc__,
|
||||||
"write($module, fd, data, /)\n"
|
"write($module, fd, data, /)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
|
@ -3963,6 +4018,61 @@ exit:
|
||||||
|
|
||||||
#endif /* defined(HAVE_PWRITE) */
|
#endif /* defined(HAVE_PWRITE) */
|
||||||
|
|
||||||
|
#if (defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2))
|
||||||
|
|
||||||
|
PyDoc_STRVAR(os_pwritev__doc__,
|
||||||
|
"pwritev($module, fd, buffers, offset, flags=0, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Writes the contents of bytes-like objects to a file descriptor at a given offset.\n"
|
||||||
|
"\n"
|
||||||
|
"Combines the functionality of writev() and pwrite(). All buffers must be a sequence\n"
|
||||||
|
"of bytes-like objects. Buffers are processed in array order. Entire contents of first\n"
|
||||||
|
"buffer is written before proceeding to second, and so on. The operating system may\n"
|
||||||
|
"set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.\n"
|
||||||
|
"This function writes the contents of each object to the file descriptor and returns\n"
|
||||||
|
"the total number of bytes written.\n"
|
||||||
|
"\n"
|
||||||
|
"The flags argument contains a bitwise OR of zero or more of the following flags:\n"
|
||||||
|
"\n"
|
||||||
|
"- RWF_DSYNC\n"
|
||||||
|
"- RWF_SYNC\n"
|
||||||
|
"\n"
|
||||||
|
"Using non-zero flags requires Linux 4.7 or newer.");
|
||||||
|
|
||||||
|
#define OS_PWRITEV_METHODDEF \
|
||||||
|
{"pwritev", (PyCFunction)os_pwritev, METH_FASTCALL, os_pwritev__doc__},
|
||||||
|
|
||||||
|
static Py_ssize_t
|
||||||
|
os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
|
||||||
|
int flags);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
os_pwritev(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
int fd;
|
||||||
|
PyObject *buffers;
|
||||||
|
Py_off_t offset;
|
||||||
|
int flags = 0;
|
||||||
|
Py_ssize_t _return_value;
|
||||||
|
|
||||||
|
if (!_PyArg_ParseStack(args, nargs, "iOO&|i:pwritev",
|
||||||
|
&fd, &buffers, Py_off_t_converter, &offset, &flags)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
_return_value = os_pwritev_impl(module, fd, buffers, offset, flags);
|
||||||
|
if ((_return_value == -1) && PyErr_Occurred()) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = PyLong_FromSsize_t(_return_value);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)) */
|
||||||
|
|
||||||
#if defined(HAVE_MKFIFO)
|
#if defined(HAVE_MKFIFO)
|
||||||
|
|
||||||
PyDoc_STRVAR(os_mkfifo__doc__,
|
PyDoc_STRVAR(os_mkfifo__doc__,
|
||||||
|
@ -6239,6 +6349,10 @@ exit:
|
||||||
#define OS_PREAD_METHODDEF
|
#define OS_PREAD_METHODDEF
|
||||||
#endif /* !defined(OS_PREAD_METHODDEF) */
|
#endif /* !defined(OS_PREAD_METHODDEF) */
|
||||||
|
|
||||||
|
#ifndef OS_PREADV_METHODDEF
|
||||||
|
#define OS_PREADV_METHODDEF
|
||||||
|
#endif /* !defined(OS_PREADV_METHODDEF) */
|
||||||
|
|
||||||
#ifndef OS_PIPE_METHODDEF
|
#ifndef OS_PIPE_METHODDEF
|
||||||
#define OS_PIPE_METHODDEF
|
#define OS_PIPE_METHODDEF
|
||||||
#endif /* !defined(OS_PIPE_METHODDEF) */
|
#endif /* !defined(OS_PIPE_METHODDEF) */
|
||||||
|
@ -6255,6 +6369,10 @@ exit:
|
||||||
#define OS_PWRITE_METHODDEF
|
#define OS_PWRITE_METHODDEF
|
||||||
#endif /* !defined(OS_PWRITE_METHODDEF) */
|
#endif /* !defined(OS_PWRITE_METHODDEF) */
|
||||||
|
|
||||||
|
#ifndef OS_PWRITEV_METHODDEF
|
||||||
|
#define OS_PWRITEV_METHODDEF
|
||||||
|
#endif /* !defined(OS_PWRITEV_METHODDEF) */
|
||||||
|
|
||||||
#ifndef OS_MKFIFO_METHODDEF
|
#ifndef OS_MKFIFO_METHODDEF
|
||||||
#define OS_MKFIFO_METHODDEF
|
#define OS_MKFIFO_METHODDEF
|
||||||
#endif /* !defined(OS_MKFIFO_METHODDEF) */
|
#endif /* !defined(OS_MKFIFO_METHODDEF) */
|
||||||
|
@ -6410,4 +6528,4 @@ exit:
|
||||||
#ifndef OS_GETRANDOM_METHODDEF
|
#ifndef OS_GETRANDOM_METHODDEF
|
||||||
#define OS_GETRANDOM_METHODDEF
|
#define OS_GETRANDOM_METHODDEF
|
||||||
#endif /* !defined(OS_GETRANDOM_METHODDEF) */
|
#endif /* !defined(OS_GETRANDOM_METHODDEF) */
|
||||||
/*[clinic end generated code: output=6345053cd5992caf input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=06ace805893aa10c input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -8163,6 +8163,94 @@ os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
|
||||||
}
|
}
|
||||||
#endif /* HAVE_PREAD */
|
#endif /* HAVE_PREAD */
|
||||||
|
|
||||||
|
#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
|
||||||
|
/*[clinic input]
|
||||||
|
os.preadv -> Py_ssize_t
|
||||||
|
|
||||||
|
fd: int
|
||||||
|
buffers: object
|
||||||
|
offset: Py_off_t
|
||||||
|
flags: int = 0
|
||||||
|
/
|
||||||
|
|
||||||
|
Reads from a file descriptor into a number of mutable bytes-like objects.
|
||||||
|
|
||||||
|
Combines the functionality of readv() and pread(). As readv(), it will
|
||||||
|
transfer data into each buffer until it is full and then move on to the next
|
||||||
|
buffer in the sequence to hold the rest of the data. Its fourth argument,
|
||||||
|
specifies the file offset at which the input operation is to be performed. It
|
||||||
|
will return the total number of bytes read (which can be less than the total
|
||||||
|
capacity of all the objects).
|
||||||
|
|
||||||
|
The flags argument contains a bitwise OR of zero or more of the following flags:
|
||||||
|
|
||||||
|
- RWF_HIPRI
|
||||||
|
- RWF_NOWAIT
|
||||||
|
|
||||||
|
Using non-zero flags requires Linux 4.6 or newer.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
static Py_ssize_t
|
||||||
|
os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
|
||||||
|
int flags)
|
||||||
|
/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
|
||||||
|
{
|
||||||
|
Py_ssize_t cnt, n;
|
||||||
|
int async_err = 0;
|
||||||
|
struct iovec *iov;
|
||||||
|
Py_buffer *buf;
|
||||||
|
|
||||||
|
if (!PySequence_Check(buffers)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"preadv2() arg 2 must be a sequence");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cnt = PySequence_Size(buffers);
|
||||||
|
if (cnt < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_PREADV2
|
||||||
|
if(flags != 0) {
|
||||||
|
argument_unavailable_error("preadv2", "flags");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_PREADV2
|
||||||
|
do {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
_Py_BEGIN_SUPPRESS_IPH
|
||||||
|
n = preadv2(fd, iov, cnt, offset, flags);
|
||||||
|
_Py_END_SUPPRESS_IPH
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
} while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||||
|
#else
|
||||||
|
do {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
_Py_BEGIN_SUPPRESS_IPH
|
||||||
|
n = preadv(fd, iov, cnt, offset);
|
||||||
|
_Py_END_SUPPRESS_IPH
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
} while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
iov_cleanup(iov, buf, cnt);
|
||||||
|
if (n < 0) {
|
||||||
|
if (!async_err) {
|
||||||
|
posix_error();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_PREADV */
|
||||||
|
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
os.write -> Py_ssize_t
|
os.write -> Py_ssize_t
|
||||||
|
@ -8613,6 +8701,97 @@ os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
|
||||||
}
|
}
|
||||||
#endif /* HAVE_PWRITE */
|
#endif /* HAVE_PWRITE */
|
||||||
|
|
||||||
|
#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
|
||||||
|
/*[clinic input]
|
||||||
|
os.pwritev -> Py_ssize_t
|
||||||
|
|
||||||
|
fd: int
|
||||||
|
buffers: object
|
||||||
|
offset: Py_off_t
|
||||||
|
flags: int = 0
|
||||||
|
/
|
||||||
|
|
||||||
|
Writes the contents of bytes-like objects to a file descriptor at a given offset.
|
||||||
|
|
||||||
|
Combines the functionality of writev() and pwrite(). All buffers must be a sequence
|
||||||
|
of bytes-like objects. Buffers are processed in array order. Entire contents of first
|
||||||
|
buffer is written before proceeding to second, and so on. The operating system may
|
||||||
|
set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
|
||||||
|
This function writes the contents of each object to the file descriptor and returns
|
||||||
|
the total number of bytes written.
|
||||||
|
|
||||||
|
The flags argument contains a bitwise OR of zero or more of the following flags:
|
||||||
|
|
||||||
|
- RWF_DSYNC
|
||||||
|
- RWF_SYNC
|
||||||
|
|
||||||
|
Using non-zero flags requires Linux 4.7 or newer.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
static Py_ssize_t
|
||||||
|
os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
|
||||||
|
int flags)
|
||||||
|
/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
|
||||||
|
{
|
||||||
|
Py_ssize_t cnt;
|
||||||
|
Py_ssize_t result;
|
||||||
|
int async_err = 0;
|
||||||
|
struct iovec *iov;
|
||||||
|
Py_buffer *buf;
|
||||||
|
|
||||||
|
if (!PySequence_Check(buffers)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"pwritev() arg 2 must be a sequence");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cnt = PySequence_Size(buffers);
|
||||||
|
if (cnt < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_PWRITEV2
|
||||||
|
if(flags != 0) {
|
||||||
|
argument_unavailable_error("pwritev2", "flags");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_PWRITEV2
|
||||||
|
do {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
_Py_BEGIN_SUPPRESS_IPH
|
||||||
|
result = pwritev2(fd, iov, cnt, offset, flags);
|
||||||
|
_Py_END_SUPPRESS_IPH
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
} while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||||
|
#else
|
||||||
|
do {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
_Py_BEGIN_SUPPRESS_IPH
|
||||||
|
result = pwritev(fd, iov, cnt, offset);
|
||||||
|
_Py_END_SUPPRESS_IPH
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
} while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
iov_cleanup(iov, buf, cnt);
|
||||||
|
if (result < 0) {
|
||||||
|
if (!async_err) {
|
||||||
|
posix_error();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_PWRITEV */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_MKFIFO
|
#ifdef HAVE_MKFIFO
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
@ -12506,9 +12685,11 @@ static PyMethodDef posix_methods[] = {
|
||||||
OS_READ_METHODDEF
|
OS_READ_METHODDEF
|
||||||
OS_READV_METHODDEF
|
OS_READV_METHODDEF
|
||||||
OS_PREAD_METHODDEF
|
OS_PREAD_METHODDEF
|
||||||
|
OS_PREADV_METHODDEF
|
||||||
OS_WRITE_METHODDEF
|
OS_WRITE_METHODDEF
|
||||||
OS_WRITEV_METHODDEF
|
OS_WRITEV_METHODDEF
|
||||||
OS_PWRITE_METHODDEF
|
OS_PWRITE_METHODDEF
|
||||||
|
OS_PWRITEV_METHODDEF
|
||||||
#ifdef HAVE_SENDFILE
|
#ifdef HAVE_SENDFILE
|
||||||
{"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
|
{"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
|
||||||
posix_sendfile__doc__},
|
posix_sendfile__doc__},
|
||||||
|
@ -12953,6 +13134,19 @@ all_ins(PyObject *m)
|
||||||
if (PyModule_AddIntMacro(m, F_TEST)) return -1;
|
if (PyModule_AddIntMacro(m, F_TEST)) return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RWF_DSYNC
|
||||||
|
if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
|
||||||
|
#endif
|
||||||
|
#ifdef RWF_HIPRI
|
||||||
|
if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
|
||||||
|
#endif
|
||||||
|
#ifdef RWF_SYNC
|
||||||
|
if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
|
||||||
|
#endif
|
||||||
|
#ifdef RWF_NOWAIT
|
||||||
|
if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SPAWNV
|
#ifdef HAVE_SPAWNV
|
||||||
if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
|
if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
|
||||||
if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
|
if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
||||||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||||
# serial 11 (pkg-config-0.29.1)
|
# serial 12 (pkg-config-0.29.2)
|
||||||
|
|
||||||
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||||
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
|
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
|
||||||
|
@ -55,7 +55,7 @@ dnl
|
||||||
dnl See the "Since" comment for each macro you use to see what version
|
dnl See the "Since" comment for each macro you use to see what version
|
||||||
dnl of the macros you require.
|
dnl of the macros you require.
|
||||||
m4_defun([PKG_PREREQ],
|
m4_defun([PKG_PREREQ],
|
||||||
[m4_define([PKG_MACROS_VERSION], [0.29.1])
|
[m4_define([PKG_MACROS_VERSION], [0.29.2])
|
||||||
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
|
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
|
||||||
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
|
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
|
||||||
])dnl PKG_PREREQ
|
])dnl PKG_PREREQ
|
||||||
|
@ -156,7 +156,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
|
||||||
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
|
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
|
||||||
|
|
||||||
pkg_failed=no
|
pkg_failed=no
|
||||||
AC_MSG_CHECKING([for $1])
|
AC_MSG_CHECKING([for $2])
|
||||||
|
|
||||||
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
|
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
|
||||||
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
|
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
|
||||||
|
@ -166,11 +166,11 @@ and $1[]_LIBS to avoid the need to call pkg-config.
|
||||||
See the pkg-config man page for more details.])
|
See the pkg-config man page for more details.])
|
||||||
|
|
||||||
if test $pkg_failed = yes; then
|
if test $pkg_failed = yes; then
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
_PKG_SHORT_ERRORS_SUPPORTED
|
_PKG_SHORT_ERRORS_SUPPORTED
|
||||||
if test $_pkg_short_errors_supported = yes; then
|
if test $_pkg_short_errors_supported = yes; then
|
||||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
||||||
else
|
else
|
||||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
||||||
fi
|
fi
|
||||||
# Put the nasty error message in config.log where it belongs
|
# Put the nasty error message in config.log where it belongs
|
||||||
|
@ -187,7 +187,7 @@ installed software in a non-standard prefix.
|
||||||
_PKG_TEXT])[]dnl
|
_PKG_TEXT])[]dnl
|
||||||
])
|
])
|
||||||
elif test $pkg_failed = untried; then
|
elif test $pkg_failed = untried; then
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
m4_default([$4], [AC_MSG_FAILURE(
|
m4_default([$4], [AC_MSG_FAILURE(
|
||||||
[The pkg-config script could not be found or is too old. Make sure it
|
[The pkg-config script could not be found or is too old. Make sure it
|
||||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||||
|
@ -288,72 +288,4 @@ AS_VAR_COPY([$1], [pkg_cv_][$1])
|
||||||
AS_VAR_IF([$1], [""], [$5], [$4])dnl
|
AS_VAR_IF([$1], [""], [$5], [$4])dnl
|
||||||
])dnl PKG_CHECK_VAR
|
])dnl PKG_CHECK_VAR
|
||||||
|
|
||||||
dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
|
|
||||||
dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
|
|
||||||
dnl [DESCRIPTION], [DEFAULT])
|
|
||||||
dnl ------------------------------------------
|
|
||||||
dnl
|
|
||||||
dnl Prepare a "--with-" configure option using the lowercase
|
|
||||||
dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and
|
|
||||||
dnl PKG_CHECK_MODULES in a single macro.
|
|
||||||
AC_DEFUN([PKG_WITH_MODULES],
|
|
||||||
[
|
|
||||||
m4_pushdef([with_arg], m4_tolower([$1]))
|
|
||||||
|
|
||||||
m4_pushdef([description],
|
|
||||||
[m4_default([$5], [build with ]with_arg[ support])])
|
|
||||||
|
|
||||||
m4_pushdef([def_arg], [m4_default([$6], [auto])])
|
|
||||||
m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes])
|
|
||||||
m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no])
|
|
||||||
|
|
||||||
m4_case(def_arg,
|
|
||||||
[yes],[m4_pushdef([with_without], [--without-]with_arg)],
|
|
||||||
[m4_pushdef([with_without],[--with-]with_arg)])
|
|
||||||
|
|
||||||
AC_ARG_WITH(with_arg,
|
|
||||||
AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),,
|
|
||||||
[AS_TR_SH([with_]with_arg)=def_arg])
|
|
||||||
|
|
||||||
AS_CASE([$AS_TR_SH([with_]with_arg)],
|
|
||||||
[yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],
|
|
||||||
[auto],[PKG_CHECK_MODULES([$1],[$2],
|
|
||||||
[m4_n([def_action_if_found]) $3],
|
|
||||||
[m4_n([def_action_if_not_found]) $4])])
|
|
||||||
|
|
||||||
m4_popdef([with_arg])
|
|
||||||
m4_popdef([description])
|
|
||||||
m4_popdef([def_arg])
|
|
||||||
|
|
||||||
])dnl PKG_WITH_MODULES
|
|
||||||
|
|
||||||
dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
|
|
||||||
dnl [DESCRIPTION], [DEFAULT])
|
|
||||||
dnl -----------------------------------------------
|
|
||||||
dnl
|
|
||||||
dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES
|
|
||||||
dnl check._[VARIABLE-PREFIX] is exported as make variable.
|
|
||||||
AC_DEFUN([PKG_HAVE_WITH_MODULES],
|
|
||||||
[
|
|
||||||
PKG_WITH_MODULES([$1],[$2],,,[$3],[$4])
|
|
||||||
|
|
||||||
AM_CONDITIONAL([HAVE_][$1],
|
|
||||||
[test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"])
|
|
||||||
])dnl PKG_HAVE_WITH_MODULES
|
|
||||||
|
|
||||||
dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
|
|
||||||
dnl [DESCRIPTION], [DEFAULT])
|
|
||||||
dnl ------------------------------------------------------
|
|
||||||
dnl
|
|
||||||
dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
|
|
||||||
dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make
|
|
||||||
dnl and preprocessor variable.
|
|
||||||
AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],
|
|
||||||
[
|
|
||||||
PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])
|
|
||||||
|
|
||||||
AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
|
|
||||||
[AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
|
|
||||||
])dnl PKG_HAVE_DEFINE_WITH_MODULES
|
|
||||||
|
|
||||||
m4_include([m4/ax_check_openssl.m4])
|
m4_include([m4/ax_check_openssl.m4])
|
||||||
|
|
|
@ -11197,8 +11197,8 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
||||||
initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \
|
initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \
|
||||||
memrchr mbrtowc mkdirat mkfifo \
|
memrchr mbrtowc mkdirat mkfifo \
|
||||||
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
|
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
|
||||||
posix_fallocate posix_fadvise pread \
|
posix_fallocate posix_fadvise pread preadv preadv2 \
|
||||||
pthread_init pthread_kill putenv pwrite readlink readlinkat readv realpath renameat \
|
pthread_init pthread_kill putenv pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
|
||||||
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
|
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
|
||||||
setgid sethostname \
|
setgid sethostname \
|
||||||
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
|
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
|
||||||
|
|
|
@ -3431,8 +3431,8 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
||||||
initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \
|
initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \
|
||||||
memrchr mbrtowc mkdirat mkfifo \
|
memrchr mbrtowc mkdirat mkfifo \
|
||||||
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
|
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
|
||||||
posix_fallocate posix_fadvise pread \
|
posix_fallocate posix_fadvise pread preadv preadv2 \
|
||||||
pthread_init pthread_kill putenv pwrite readlink readlinkat readv realpath renameat \
|
pthread_init pthread_kill putenv pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
|
||||||
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
|
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
|
||||||
setgid sethostname \
|
setgid sethostname \
|
||||||
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
|
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
|
||||||
|
|
|
@ -710,6 +710,12 @@
|
||||||
/* Define to 1 if you have the `pread' function. */
|
/* Define to 1 if you have the `pread' function. */
|
||||||
#undef HAVE_PREAD
|
#undef HAVE_PREAD
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `preadv' function. */
|
||||||
|
#undef HAVE_PREADV
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `preadv2' function. */
|
||||||
|
#undef HAVE_PREADV2
|
||||||
|
|
||||||
/* Define if you have the 'prlimit' functions. */
|
/* Define if you have the 'prlimit' functions. */
|
||||||
#undef HAVE_PRLIMIT
|
#undef HAVE_PRLIMIT
|
||||||
|
|
||||||
|
@ -746,6 +752,12 @@
|
||||||
/* Define to 1 if you have the `pwrite' function. */
|
/* Define to 1 if you have the `pwrite' function. */
|
||||||
#undef HAVE_PWRITE
|
#undef HAVE_PWRITE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `pwritev' function. */
|
||||||
|
#undef HAVE_PWRITEV
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `pwritev2' function. */
|
||||||
|
#undef HAVE_PWRITEV2
|
||||||
|
|
||||||
/* Define to 1 if you have the `readlink' function. */
|
/* Define to 1 if you have the `readlink' function. */
|
||||||
#undef HAVE_READLINK
|
#undef HAVE_READLINK
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue