mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
bpo-26826: Expose copy_file_range in the os module (GH-7255)
This commit is contained in:
parent
545a3b8814
commit
aac4d0342c
9 changed files with 363 additions and 19 deletions
|
@ -117,6 +117,10 @@ corresponding Unix manual entries for more information on calls.");
|
|||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_COPY_FILE_RANGE
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
|
||||
#undef HAVE_SCHED_SETAFFINITY
|
||||
#endif
|
||||
|
@ -9455,8 +9459,74 @@ os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
|
|||
}
|
||||
#endif /* HAVE_PWRITEV */
|
||||
|
||||
#ifdef HAVE_COPY_FILE_RANGE
|
||||
/*[clinic input]
|
||||
|
||||
os.copy_file_range
|
||||
src: int
|
||||
Source file descriptor.
|
||||
dst: int
|
||||
Destination file descriptor.
|
||||
count: Py_ssize_t
|
||||
Number of bytes to copy.
|
||||
offset_src: object = None
|
||||
Starting offset in src.
|
||||
offset_dst: object = None
|
||||
Starting offset in dst.
|
||||
|
||||
Copy count bytes from one file descriptor to another.
|
||||
|
||||
If offset_src is None, then src is read from the current position;
|
||||
respectively for offset_dst.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
|
||||
PyObject *offset_src, PyObject *offset_dst)
|
||||
/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
|
||||
{
|
||||
off_t offset_src_val, offset_dst_val;
|
||||
off_t *p_offset_src = NULL;
|
||||
off_t *p_offset_dst = NULL;
|
||||
Py_ssize_t ret;
|
||||
int async_err = 0;
|
||||
/* The flags argument is provided to allow
|
||||
* for future extensions and currently must be to 0. */
|
||||
int flags = 0;
|
||||
|
||||
|
||||
if (count < 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (offset_src != Py_None) {
|
||||
if (!Py_off_t_converter(offset_src, &offset_src_val)) {
|
||||
return NULL;
|
||||
}
|
||||
p_offset_src = &offset_src_val;
|
||||
}
|
||||
|
||||
if (offset_dst != Py_None) {
|
||||
if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
|
||||
return NULL;
|
||||
}
|
||||
p_offset_dst = &offset_dst_val;
|
||||
}
|
||||
|
||||
do {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
|
||||
Py_END_ALLOW_THREADS
|
||||
} while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||
|
||||
if (ret < 0) {
|
||||
return (!async_err) ? posix_error() : NULL;
|
||||
}
|
||||
|
||||
return PyLong_FromSsize_t(ret);
|
||||
}
|
||||
#endif /* HAVE_COPY_FILE_RANGE*/
|
||||
|
||||
#ifdef HAVE_MKFIFO
|
||||
/*[clinic input]
|
||||
|
@ -13432,6 +13502,7 @@ static PyMethodDef posix_methods[] = {
|
|||
OS_POSIX_SPAWN_METHODDEF
|
||||
OS_POSIX_SPAWNP_METHODDEF
|
||||
OS_READLINK_METHODDEF
|
||||
OS_COPY_FILE_RANGE_METHODDEF
|
||||
OS_RENAME_METHODDEF
|
||||
OS_REPLACE_METHODDEF
|
||||
OS_RMDIR_METHODDEF
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue