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

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 3 years, 11 months 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
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 /* from copy_file_range()'s man page: */
8404 static loff_t
8405 copy_file_range(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out,
8406 size_t len, unsigned int flags)
8407 {
8408 return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out,
8409 len, flags);
8410 }
8411
8412 /* TODO: use clinic? */
Martin Panter 2016/04/29 03:33:44 I admit I have only edited existing Arg Clinic fun
8413 PyDoc_STRVAR(posix_copy_file_range__doc__,
8414 "copy_file_range(in, offset_in, out, offset_out, count, flags=0) -> \
Martin Panter 2016/05/08 12:23:22 Current patch still does not have updated signatur
8415 bytes_written\n\
8416 Copy count bytes from file descriptor in, starting from offset offset_in, \
8417 to file descriptor out, starting from offset offset_out. \
8418 If offset_in is None, then in is read from the current position; \
8419 respectively for offset_out.");
8420
8421 static PyObject *
8422 posix_copy_file_range(PyObject *self, PyObject *args, PyObject *kwdict)
8423 {
8424 int in, out;
8425 off_t offset_in, *p_offset_in, offset_out, *p_offset_out, count;
8426 Py_ssize_t ret;
8427 int async_err = 0;
8428 int flags = 0;
8429 PyObject *offset_in_obj, *offset_out_obj;
8430 static char *keywords[] = {"in", "offset_in", "out", "offset_out",
8431 "count", "flags", NULL};
8432
8433 /* O types are used to handle offset_*_obj==None -> from current position */
8434 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iOiOn|i:copy_file_range",
Martin Panter 2016/04/29 03:33:44 Doesn’t the “n” format expect Py_ssize_t, not off_
StyXman 2016/05/12 12:51:46 The n is for size_t count.
Martin Panter 2016/05/13 04:52:45 Yes. In this older patch it is declared as off_t c
8435 keywords, &in, &offset_in_obj, &out, &offset_out_obj, &count, &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_in_obj == Py_None)
8444 p_offset_in = NULL;
8445 else {
8446 if (!Py_off_t_converter(offset_in_obj, &offset_in))
8447 return NULL;
8448 p_offset_in = &offset_in;
8449 }
8450 if (offset_out_obj == Py_None)
8451 p_offset_out = NULL;
8452 else {
8453 if (!Py_off_t_converter(offset_out_obj, &offset_out))
8454 return NULL;
8455 p_offset_out = &offset_out;
8456 }
8457
8458 do {
8459 Py_BEGIN_ALLOW_THREADS
8460 ret = copy_file_range(in, p_offset_in, out, p_offset_out, count, flags);
Martin Panter 2016/04/29 03:33:44 Why do you assign loff_t → Py_ssize_t here? Is thi
StyXman 2016/05/12 12:51:46 c_f_r() returns ssize_t. I don't know why the exam
8461 Py_END_ALLOW_THREADS
8462 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8463 if (ret < 0)
8464 return async_err ? NULL : posix_error();
8465 return Py_BuildValue("n", ret);
8466 }
8467 #endif /* HAVE_COPY_FILE_RANGE */
8397 8468
8398 /*[clinic input] 8469 /*[clinic input]
8399 os.fstat 8470 os.fstat
8400 8471
8401 fd : int 8472 fd : int
8402 8473
8403 Perform a stat system call on the given file descriptor. 8474 Perform a stat system call on the given file descriptor.
8404 8475
8405 Like stat(), but for an open file descriptor. 8476 Like stat(), but for an open file descriptor.
8406 Equivalent to os.stat(fd). 8477 Equivalent to os.stat(fd).
(...skipping 3992 matching lines...) Expand 10 before | Expand all | Expand 10 after
12399 OS_LSEEK_METHODDEF 12470 OS_LSEEK_METHODDEF
12400 OS_READ_METHODDEF 12471 OS_READ_METHODDEF
12401 OS_READV_METHODDEF 12472 OS_READV_METHODDEF
12402 OS_PREAD_METHODDEF 12473 OS_PREAD_METHODDEF
12403 OS_WRITE_METHODDEF 12474 OS_WRITE_METHODDEF
12404 OS_WRITEV_METHODDEF 12475 OS_WRITEV_METHODDEF
12405 OS_PWRITE_METHODDEF 12476 OS_PWRITE_METHODDEF
12406 #ifdef HAVE_SENDFILE 12477 #ifdef HAVE_SENDFILE
12407 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORD S, 12478 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORD S,
12408 posix_sendfile__doc__}, 12479 posix_sendfile__doc__},
12480 #endif
12481 #ifdef HAVE_COPY_FILE_RANGE
12482 {"copy_file_range", (PyCFunction)posix_copy_file_range, METH_VARARGS | METH_ KEYWORDS,
12483 posix_copy_file_range__doc__},
12409 #endif 12484 #endif
12410 OS_FSTAT_METHODDEF 12485 OS_FSTAT_METHODDEF
12411 OS_ISATTY_METHODDEF 12486 OS_ISATTY_METHODDEF
12412 OS_PIPE_METHODDEF 12487 OS_PIPE_METHODDEF
12413 OS_PIPE2_METHODDEF 12488 OS_PIPE2_METHODDEF
12414 OS_MKFIFO_METHODDEF 12489 OS_MKFIFO_METHODDEF
12415 OS_MKNOD_METHODDEF 12490 OS_MKNOD_METHODDEF
12416 OS_MAJOR_METHODDEF 12491 OS_MAJOR_METHODDEF
12417 OS_MINOR_METHODDEF 12492 OS_MINOR_METHODDEF
12418 OS_MAKEDEV_METHODDEF 12493 OS_MAKEDEV_METHODDEF
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after
13240 PyModule_AddObject(m, "_have_functions", list); 13315 PyModule_AddObject(m, "_have_functions", list);
13241 13316
13242 initialized = 1; 13317 initialized = 1;
13243 13318
13244 return m; 13319 return m;
13245 } 13320 }
13246 13321
13247 #ifdef __cplusplus 13322 #ifdef __cplusplus
13248 } 13323 }
13249 #endif 13324 #endif
OLDNEW
« Doc/library/os.rst ('K') | « Doc/library/os.rst ('k') | pyconfig.h.in » ('j') | no next file with comments »

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