Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(5)

Side by Side Diff: Modules/posixmodule.c

Issue 26826: Expose new copy_file_range() syscal in os module and use it to improve shutils.copy()
Patch Set: Created 4 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Doc/library/os.rst ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* POSIX module implementation */ 2 /* POSIX module implementation */
3 3
4 /* This file is also used for Windows NT/MS-Win. In that case the 4 /* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few 5 module actually calls itself 'nt', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source 6 functions are either unimplemented or implemented differently. The source
7 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent 7 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
8 of the compiler used. Different compilers define their own feature 8 of the compiler used. Different compilers define their own feature
9 test macro, e.g. '_MSC_VER'. */ 9 test macro, e.g. '_MSC_VER'. */
10 10
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 #ifdef HAVE_SYS_LOADAVG_H 78 #ifdef HAVE_SYS_LOADAVG_H
79 #include <sys/loadavg.h> 79 #include <sys/loadavg.h>
80 #endif 80 #endif
81 81
82 #ifdef HAVE_LANGINFO_H 82 #ifdef HAVE_LANGINFO_H
83 #include <langinfo.h> 83 #include <langinfo.h>
84 #endif 84 #endif
85 85
86 #ifdef HAVE_SYS_SENDFILE_H 86 #ifdef HAVE_SYS_SENDFILE_H
87 #include <sys/sendfile.h> 87 #include <sys/sendfile.h>
88 #endif
89
90 #ifdef HAVE_COPY_FILE_RANGE
91 #include <sys/syscall.h>
92 #include <unistd.h>
88 #endif 93 #endif
89 94
90 #ifdef HAVE_SCHED_H 95 #ifdef HAVE_SCHED_H
91 #include <sched.h> 96 #include <sched.h>
92 #endif 97 #endif
93 98
94 #if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY) 99 #if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
95 #undef HAVE_SCHED_SETAFFINITY 100 #undef HAVE_SCHED_SETAFFINITY
96 #endif 101 #endif
97 102
(...skipping 8289 matching lines...) Expand 10 before | Expand all | Expand 10 after
8387 ret = sendfile(out, in, &offset, count); 8392 ret = sendfile(out, in, &offset, count);
8388 Py_END_ALLOW_THREADS 8393 Py_END_ALLOW_THREADS
8389 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); 8394 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8390 if (ret < 0) 8395 if (ret < 0)
8391 return (!async_err) ? posix_error() : NULL; 8396 return (!async_err) ? posix_error() : NULL;
8392 return Py_BuildValue("n", ret); 8397 return Py_BuildValue("n", ret);
8393 #endif 8398 #endif
8394 } 8399 }
8395 #endif /* HAVE_SENDFILE */ 8400 #endif /* HAVE_SENDFILE */
8396 8401
8402 #ifdef HAVE_COPY_FILE_RANGE
8403 /* modified example found in copy_file_range()'s man page: */
8404 /* ssize_t so it can return -1 */
8405 static ssize_t
8406 copy_file_range(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out,
8407 size_t len, unsigned int flags)
8408 {
8409 return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out,
8410 len, flags);
8411 }
8412
8413 PyDoc_STRVAR(posix_copy_file_range__doc__,
8414 "copy_file_range(src, dst, count, offset_src=None, offset_dst=None, flags=0) -> \
8415 bytes_written\n\
8416 Copy count bytes from file descriptor src, starting from offset offset_src, \
8417 to file descriptor dst, starting from offset offset_dst. \
8418 If offset_src is None, then src is read from the current position; \
8419 respectively for offset_dst.");
8420
8421 static PyObject *
8422 posix_copy_file_range(PyObject *self, PyObject *args, PyObject *kwdict)
8423 {
8424 int src, dst;
8425 off_t offset_src, *p_offset_src, offset_dst, *p_offset_dst;
8426 Py_ssize_t count, ret;
8427 int async_err = 0;
8428 int flags = 0;
8429 PyObject *offset_src_obj, *offset_dst_obj;
8430 static char *keywords[] = {"src", "dst", "count",
8431 "offset_src", "offset_dst", "flags", NULL};
8432
8433 /* O types are used to handle offset_*_obj==None -> from current position */
8434 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iin|OOi:copy_file_range",
8435 keywords, &src, &dst, &count, &offset_src_obj, &offset_dst_obj, &flags))
8436 return NULL;
8437
8438 /* offset handling is complex. we convert the argument to a Python object.
8439 * if None, then the corresponding pointer is NULL.
8440 * otherwise, try to convert; if successful, use that
8441 * and point the pointer there.
8442 */
8443 if (offset_src_obj == Py_None)
8444 p_offset_src = NULL;
8445 else {
8446 if (!Py_off_t_converter(offset_src_obj, &offset_src))
8447 return NULL;
8448 p_offset_src = &offset_src;
8449 }
8450 if (offset_dst_obj == Py_None)
8451 p_offset_dst = NULL;
8452 else {
8453 if (!Py_off_t_converter(offset_dst_obj, &offset_dst))
8454 return NULL;
8455 p_offset_dst = &offset_dst;
8456 }
8457
8458 do {
8459 Py_BEGIN_ALLOW_THREADS
8460 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags );
8461 Py_END_ALLOW_THREADS
8462 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8463
8464 if (ret < 0)
8465 return async_err ? NULL : posix_error();
8466
8467 /* we currently ignore the changes to the offsets */
8468 return Py_BuildValue("n", ret);
8469 }
8470 #endif /* HAVE_COPY_FILE_RANGE */
8397 8471
8398 /*[clinic input] 8472 /*[clinic input]
8399 os.fstat 8473 os.fstat
8400 8474
8401 fd : int 8475 fd : int
8402 8476
8403 Perform a stat system call on the given file descriptor. 8477 Perform a stat system call on the given file descriptor.
8404 8478
8405 Like stat(), but for an open file descriptor. 8479 Like stat(), but for an open file descriptor.
8406 Equivalent to os.stat(fd). 8480 Equivalent to os.stat(fd).
(...skipping 3992 matching lines...) Expand 10 before | Expand all | Expand 10 after
12399 OS_LSEEK_METHODDEF 12473 OS_LSEEK_METHODDEF
12400 OS_READ_METHODDEF 12474 OS_READ_METHODDEF
12401 OS_READV_METHODDEF 12475 OS_READV_METHODDEF
12402 OS_PREAD_METHODDEF 12476 OS_PREAD_METHODDEF
12403 OS_WRITE_METHODDEF 12477 OS_WRITE_METHODDEF
12404 OS_WRITEV_METHODDEF 12478 OS_WRITEV_METHODDEF
12405 OS_PWRITE_METHODDEF 12479 OS_PWRITE_METHODDEF
12406 #ifdef HAVE_SENDFILE 12480 #ifdef HAVE_SENDFILE
12407 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORD S, 12481 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORD S,
12408 posix_sendfile__doc__}, 12482 posix_sendfile__doc__},
12483 #endif
12484 #ifdef HAVE_COPY_FILE_RANGE
12485 {"copy_file_range", (PyCFunction)posix_copy_file_range, METH_VARARGS | METH_ KEYWORDS,
12486 posix_copy_file_range__doc__},
12409 #endif 12487 #endif
12410 OS_FSTAT_METHODDEF 12488 OS_FSTAT_METHODDEF
12411 OS_ISATTY_METHODDEF 12489 OS_ISATTY_METHODDEF
12412 OS_PIPE_METHODDEF 12490 OS_PIPE_METHODDEF
12413 OS_PIPE2_METHODDEF 12491 OS_PIPE2_METHODDEF
12414 OS_MKFIFO_METHODDEF 12492 OS_MKFIFO_METHODDEF
12415 OS_MKNOD_METHODDEF 12493 OS_MKNOD_METHODDEF
12416 OS_MAJOR_METHODDEF 12494 OS_MAJOR_METHODDEF
12417 OS_MINOR_METHODDEF 12495 OS_MINOR_METHODDEF
12418 OS_MAKEDEV_METHODDEF 12496 OS_MAKEDEV_METHODDEF
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after
13240 PyModule_AddObject(m, "_have_functions", list); 13318 PyModule_AddObject(m, "_have_functions", list);
13241 13319
13242 initialized = 1; 13320 initialized = 1;
13243 13321
13244 return m; 13322 return m;
13245 } 13323 }
13246 13324
13247 #ifdef __cplusplus 13325 #ifdef __cplusplus
13248 } 13326 }
13249 #endif 13327 #endif
OLDNEW
« no previous file with comments | « Doc/library/os.rst ('k') | no next file » | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+