bpo-40178: Convert the remaining os functions to Argument Clinic. (GH-19360)

Convert os.getgrouplist(), os.initgroups(), os.sendfile() and
os.get_terminal_size().
This commit is contained in:
Serhiy Storchaka 2020-04-18 19:14:10 +03:00 committed by GitHub
parent 12446e6a60
commit 2b5603140c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 719 additions and 129 deletions

View file

@ -6947,23 +6947,46 @@ os_getpid_impl(PyObject *module)
#ifdef HAVE_GETGROUPLIST
/* AC 3.5: funny apple logic below */
PyDoc_STRVAR(posix_getgrouplist__doc__,
"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
Returns a list of groups to which a user belongs.\n\n\
user: username to lookup\n\
group: base group id of the user");
#ifdef __APPLE__
/*[clinic input]
os.getgrouplist
user: str
username to lookup
group as basegid: int
base group id of the user
/
Returns a list of groups to which a user belongs.
[clinic start generated code]*/
static PyObject *
posix_getgrouplist(PyObject *self, PyObject *args)
os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
#else
/*[clinic input]
os.getgrouplist
user: str
username to lookup
group as basegid: gid_t
base group id of the user
/
Returns a list of groups to which a user belongs.
[clinic start generated code]*/
static PyObject *
os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
#endif
{
const char *user;
int i, ngroups;
PyObject *list;
#ifdef __APPLE__
int *groups, basegid;
int *groups;
#else
gid_t *groups, basegid;
gid_t *groups;
#endif
/*
@ -6976,15 +6999,6 @@ posix_getgrouplist(PyObject *self, PyObject *args)
*/
ngroups = 1 + MAX_GROUPS;
#ifdef __APPLE__
if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
return NULL;
#else
if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
_Py_Gid_Converter, &basegid))
return NULL;
#endif
while (1) {
#ifdef __APPLE__
groups = PyMem_New(int, ngroups);
@ -7155,40 +7169,47 @@ os_getgroups_impl(PyObject *module)
#endif /* HAVE_GETGROUPS */
#ifdef HAVE_INITGROUPS
PyDoc_STRVAR(posix_initgroups__doc__,
"initgroups(username, gid) -> None\n\n\
Call the system initgroups() to initialize the group access list with all of\n\
the groups of which the specified username is a member, plus the specified\n\
group id.");
#ifdef __APPLE__
/*[clinic input]
os.initgroups
username as oname: FSConverter
gid: int
/
Initialize the group access list.
Call the system initgroups() to initialize the group access list with all of
the groups of which the specified username is a member, plus the specified
group id.
[clinic start generated code]*/
/* AC 3.5: funny apple logic */
static PyObject *
posix_initgroups(PyObject *self, PyObject *args)
os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
#else
/*[clinic input]
os.initgroups
username as oname: FSConverter
gid: gid_t
/
Initialize the group access list.
Call the system initgroups() to initialize the group access list with all of
the groups of which the specified username is a member, plus the specified
group id.
[clinic start generated code]*/
static PyObject *
os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
#endif
{
PyObject *oname;
const char *username;
int res;
#ifdef __APPLE__
int gid;
#else
gid_t gid;
#endif
const char *username = PyBytes_AS_STRING(oname);
#ifdef __APPLE__
if (!PyArg_ParseTuple(args, "O&i:initgroups",
PyUnicode_FSConverter, &oname,
&gid))
#else
if (!PyArg_ParseTuple(args, "O&O&:initgroups",
PyUnicode_FSConverter, &oname,
_Py_Gid_Converter, &gid))
#endif
return NULL;
username = PyBytes_AS_STRING(oname);
res = initgroups(username, gid);
Py_DECREF(oname);
if (res == -1)
if (initgroups(username, gid) == -1)
return PyErr_SetFromErrno(PyExc_OSError);
Py_RETURN_NONE;
@ -9220,46 +9241,77 @@ os_write_impl(PyObject *module, int fd, Py_buffer *data)
}
#ifdef HAVE_SENDFILE
PyDoc_STRVAR(posix_sendfile__doc__,
"sendfile(out_fd, in_fd, offset, count) -> byteswritten\n\
sendfile(out_fd, in_fd, offset, count[, headers][, trailers], flags=0)\n\
-> byteswritten\n\
Copy count bytes from file descriptor in_fd to file descriptor out_fd.");
#ifdef __APPLE__
/*[clinic input]
os.sendfile
out_fd: int
in_fd: int
offset: Py_off_t
count as sbytes: Py_off_t
headers: object(c_default="NULL") = ()
trailers: object(c_default="NULL") = ()
flags: int = 0
Copy count bytes from file descriptor in_fd to file descriptor out_fd.
[clinic start generated code]*/
/* AC 3.5: don't bother converting, has optional group*/
static PyObject *
posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
Py_off_t sbytes, PyObject *headers, PyObject *trailers,
int flags)
/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
#elif defined(__FreeBSD__) || defined(__DragonFly__)
/*[clinic input]
os.sendfile
out_fd: int
in_fd: int
offset: Py_off_t
count: Py_ssize_t
headers: object(c_default="NULL") = ()
trailers: object(c_default="NULL") = ()
flags: int = 0
Copy count bytes from file descriptor in_fd to file descriptor out_fd.
[clinic start generated code]*/
static PyObject *
os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
Py_ssize_t count, PyObject *headers, PyObject *trailers,
int flags)
/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
#else
/*[clinic input]
os.sendfile
out_fd: int
in_fd: int
offset as offobj: object
count: Py_ssize_t
Copy count bytes from file descriptor in_fd to file descriptor out_fd.
[clinic start generated code]*/
static PyObject *
os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
Py_ssize_t count)
/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
#endif
{
int in, out;
Py_ssize_t ret;
int async_err = 0;
off_t offset;
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
#ifndef __APPLE__
Py_ssize_t len;
#endif
PyObject *headers = NULL, *trailers = NULL;
Py_buffer *hbuf, *tbuf;
off_t sbytes;
#endif
Py_buffer *hbuf, *tbuf;
struct sf_hdtr sf;
int flags = 0;
static char *keywords[] = {"out_fd", "in_fd",
"offset", "count",
"headers", "trailers", "flags", NULL};
sf.headers = NULL;
sf.trailers = NULL;
#ifdef __APPLE__
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
#else
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
keywords, &out, &in, Py_off_t_converter, &offset, &len,
#endif
&headers, &trailers, &flags))
return NULL;
if (headers != NULL) {
if (!PySequence_Check(headers)) {
PyErr_SetString(PyExc_TypeError,
@ -9321,9 +9373,9 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
do {
Py_BEGIN_ALLOW_THREADS
#ifdef __APPLE__
ret = sendfile(in, out, offset, &sbytes, &sf, flags);
ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
#else
ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
#endif
Py_END_ALLOW_THREADS
} while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
@ -9358,18 +9410,11 @@ done:
#endif
#else
Py_ssize_t count;
PyObject *offobj;
static char *keywords[] = {"out_fd", "in_fd",
"offset", "count", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
keywords, &out, &in, &offobj, &count))
return NULL;
#ifdef __linux__
if (offobj == Py_None) {
do {
Py_BEGIN_ALLOW_THREADS
ret = sendfile(out, in, NULL, count);
ret = sendfile(out_fd, in_fd, NULL, count);
Py_END_ALLOW_THREADS
} while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
if (ret < 0)
@ -9377,12 +9422,13 @@ done:
return Py_BuildValue("n", ret);
}
#endif
off_t offset;
if (!Py_off_t_converter(offobj, &offset))
return NULL;
do {
Py_BEGIN_ALLOW_THREADS
ret = sendfile(out, in, &offset, count);
ret = sendfile(out_fd, in_fd, &offset, count);
Py_END_ALLOW_THREADS
} while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
if (ret < 0)
@ -12360,29 +12406,34 @@ static PyStructSequence_Desc TerminalSize_desc = {
};
#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
/* AC 3.5: fd should accept None */
PyDoc_STRVAR(termsize__doc__,
"Return the size of the terminal window as (columns, lines).\n" \
"\n" \
"The optional argument fd (default standard output) specifies\n" \
"which file descriptor should be queried.\n" \
"\n" \
"If the file descriptor is not connected to a terminal, an OSError\n" \
"is thrown.\n" \
"\n" \
"This function will only be defined if an implementation is\n" \
"available for this system.\n" \
"\n" \
"shutil.get_terminal_size is the high-level function which should\n" \
"normally be used, os.get_terminal_size is the low-level implementation.");
/*[clinic input]
os.get_terminal_size
static PyObject*
get_terminal_size(PyObject *self, PyObject *args)
fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
/
Return the size of the terminal window as (columns, lines).
The optional argument fd (default standard output) specifies
which file descriptor should be queried.
If the file descriptor is not connected to a terminal, an OSError
is thrown.
This function will only be defined if an implementation is
available for this system.
shutil.get_terminal_size is the high-level function which should
normally be used, os.get_terminal_size is the low-level implementation.
[clinic start generated code]*/
static PyObject *
os_get_terminal_size_impl(PyObject *module, int fd)
/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
{
int columns, lines;
PyObject *termsize;
int fd = fileno(stdout);
/* Under some conditions stdout may not be connected and
* fileno(stdout) may point to an invalid file descriptor. For example
* GUI apps don't have valid standard streams by default.
@ -12391,9 +12442,6 @@ get_terminal_size(PyObject *self, PyObject *args)
* the ioctl below will fail returning EBADF. This is what we want.
*/
if (!PyArg_ParseTuple(args, "|i", &fd))
return NULL;
#ifdef TERMSIZE_USE_IOCTL
{
struct winsize w;
@ -12433,7 +12481,7 @@ get_terminal_size(PyObject *self, PyObject *args)
}
#endif /* TERMSIZE_USE_CONIO */
PyObject *TerminalSizeType = get_posix_state(self)->TerminalSizeType;
PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
if (termsize == NULL)
return NULL;
@ -13912,9 +13960,7 @@ static PyMethodDef posix_methods[] = {
OS_GETEGID_METHODDEF
OS_GETEUID_METHODDEF
OS_GETGID_METHODDEF
#ifdef HAVE_GETGROUPLIST
{"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
#endif
OS_GETGROUPLIST_METHODDEF
OS_GETGROUPS_METHODDEF
OS_GETPID_METHODDEF
OS_GETPGRP_METHODDEF
@ -13924,9 +13970,7 @@ static PyMethodDef posix_methods[] = {
OS_KILL_METHODDEF
OS_KILLPG_METHODDEF
OS_PLOCK_METHODDEF
#ifdef MS_WINDOWS
OS_STARTFILE_METHODDEF
#endif
OS_SETUID_METHODDEF
OS_SETEUID_METHODDEF
OS_SETREUID_METHODDEF
@ -13934,9 +13978,7 @@ static PyMethodDef posix_methods[] = {
OS_SETEGID_METHODDEF
OS_SETREGID_METHODDEF
OS_SETGROUPS_METHODDEF
#ifdef HAVE_INITGROUPS
{"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
#endif /* HAVE_INITGROUPS */
OS_INITGROUPS_METHODDEF
OS_GETPGID_METHODDEF
OS_SETPGRP_METHODDEF
OS_WAIT_METHODDEF
@ -13966,10 +14008,7 @@ static PyMethodDef posix_methods[] = {
OS_WRITEV_METHODDEF
OS_PWRITE_METHODDEF
OS_PWRITEV_METHODDEF
#ifdef HAVE_SENDFILE
{"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
posix_sendfile__doc__},
#endif
OS_SENDFILE_METHODDEF
OS_FSTAT_METHODDEF
OS_ISATTY_METHODDEF
OS_PIPE_METHODDEF
@ -14021,26 +14060,20 @@ static PyMethodDef posix_methods[] = {
OS_REMOVEXATTR_METHODDEF
OS_LISTXATTR_METHODDEF
#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
{"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
#endif
OS_GET_TERMINAL_SIZE_METHODDEF
OS_CPU_COUNT_METHODDEF
OS_GET_INHERITABLE_METHODDEF
OS_SET_INHERITABLE_METHODDEF
OS_GET_HANDLE_INHERITABLE_METHODDEF
OS_SET_HANDLE_INHERITABLE_METHODDEF
#ifndef MS_WINDOWS
OS_GET_BLOCKING_METHODDEF
OS_SET_BLOCKING_METHODDEF
#endif
OS_SCANDIR_METHODDEF
OS_FSPATH_METHODDEF
OS_GETRANDOM_METHODDEF
OS_MEMFD_CREATE_METHODDEF
#ifdef MS_WINDOWS
OS__ADD_DLL_DIRECTORY_METHODDEF
OS__REMOVE_DLL_DIRECTORY_METHODDEF
#endif
OS_WAITSTATUS_TO_EXITCODE_METHODDEF
{NULL, NULL} /* Sentinel */
};