Repository navigation
bpo-31368: Expose preadv (preadv2) and pwritev (pwritev2) in the os module #5239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
ea21128
4570976
21a3004
8a2a2a3
c0c53dc
4ddbca9
cac62ac
c7b7285
58910d0
f7cdf22
47f65b5
87c6970
cb74d38
5563b8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8163,6 +8163,64 @@ os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset) | |
| } | ||
| #endif /* HAVE_PREAD */ | ||
|
|
||
| #ifdef HAVE_PREAD | ||
| /*[clinic input] | ||
| os.preadv2 -> Py_ssize_t | ||
|
|
||
| fd: int | ||
| buffers: object | ||
| offset: Py_off_t | ||
| flags: int | ||
| / | ||
|
|
||
| Read a number of bytes from a file descriptor starting at a particular offset. | ||
|
|
||
| Read length bytes from file descriptor fd, starting at offset bytes from | ||
| the beginning of the file. The file offset remains unchanged. | ||
| [clinic start generated code]*/ | ||
|
|
||
| static Py_ssize_t | ||
| os_preadv2_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, | ||
| int flags) | ||
| /*[clinic end generated code: output=fd040c20cf504631 input=f4a633d90005eb65]*/ | ||
| { | ||
| 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) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please always add { ... } to if blocks: see PEP 7. Same comment for the whole PR. |
||
| return -1; | ||
|
|
||
| if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) | ||
| return -1; | ||
|
|
||
| do { | ||
| Py_BEGIN_ALLOW_THREADS | ||
| n = preadv2(fd, iov, cnt, offset, flags); | ||
| Py_END_ALLOW_THREADS | ||
| } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); | ||
|
|
||
| iov_cleanup(iov, buf, cnt); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we exit early (e.g. due to
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have corrected it in 4ddbca9. I could not use easily a goto label to have a clean exit section due to the check for async error in the signal handler so I just clean before exiting if |
||
| if (n < 0) { | ||
| if (!async_err) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PEP 7 coding style: add { ... } |
||
| posix_error(); | ||
| return -1; | ||
| } | ||
|
|
||
| return n; | ||
| } | ||
|
|
||
|
|
||
| #endif /* HAVE PREADV2 */ | ||
|
|
||
|
|
||
| /*[clinic input] | ||
| os.write -> Py_ssize_t | ||
|
|
@@ -12506,6 +12564,7 @@ static PyMethodDef posix_methods[] = { | |
| OS_READ_METHODDEF | ||
| OS_READV_METHODDEF | ||
| OS_PREAD_METHODDEF | ||
| OS_PREADV2_METHODDEF | ||
| OS_WRITE_METHODDEF | ||
| OS_WRITEV_METHODDEF | ||
| OS_PWRITE_METHODDEF | ||
|
|
@@ -12953,6 +13012,13 @@ all_ins(PyObject *m) | |
| if (PyModule_AddIntMacro(m, F_TEST)) return -1; | ||
| #endif | ||
|
|
||
| #ifdef HAVE_READV | ||
| if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1; | ||
| if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1; | ||
| if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1; | ||
| if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1; | ||
| #endif | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These constants were added at different times, so they should be checked for individually, like: #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
...
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also EOPNOTSUPP flag might be important to add?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's already available as |
||
|
|
||
| #ifdef HAVE_SPAWNV | ||
| if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1; | ||
| if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait... is this description correct? it seems to be copied from two other functions?