Skip to content

gh-126316: Use getgrent_r() in grp.getgrall() #126506

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:mod:`grp`: :func:`grp.getgrall` now uses ``getgrent_r()``, if the function
is available, to make :func:`grp.getgrall` thread-safe. Patch by Victor
Stinner.
42 changes: 33 additions & 9 deletions Modules/grpmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,22 +281,46 @@ static PyObject *
grp_getgrall_impl(PyObject *module)
/*[clinic end generated code: output=585dad35e2e763d7 input=d7df76c825c367df]*/
{
PyObject *d;
struct group *p;

if ((d = PyList_New(0)) == NULL)
PyObject *d = PyList_New(0);
if (d == NULL) {
return NULL;
}

setgrent();
while ((p = getgrent()) != NULL) {
PyObject *v = mkgrent(module, p);
while (1) {
#ifdef HAVE_GETGRENT_R
struct group grp;
struct group *grpp;
char buf[4096];
int err = getgrent_r(&grp, buf, sizeof(buf), &grpp);
if (err) {
if (err != ENOENT) {
errno = err;
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
break;
}
#else
struct group *grpp = getgrent();
if (grpp == NULL) {
break;
}
#endif

PyObject *v = mkgrent(module, grpp);
if (v == NULL || PyList_Append(d, v) != 0) {
Py_XDECREF(v);
Py_DECREF(d);
endgrent();
return NULL;
goto error;
}
Py_DECREF(v);
}
goto done;

error:
Py_CLEAR(d);

done:
endgrent();
return d;
}
Expand Down
6 changes: 6 additions & 0 deletions configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -5181,7 +5181,7 @@ AC_CHECK_FUNCS([ \
copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid geteuid getgid getgrent getgrgid getgrgid_r \
gai_strerror getegid geteuid getgid getgrent getgrent_r getgrgid getgrgid_r \
getgrnam_r getgrouplist gethostname getitimer getloadavg getlogin \
getpeername getpgid getpid getppid getpriority _getpty \
getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \
Expand Down
3 changes: 3 additions & 0 deletions pyconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,9 @@
/* Define to 1 if you have the `getgrent' function. */
#undef HAVE_GETGRENT

/* Define to 1 if you have the `getgrent_r' function. */
#undef HAVE_GETGRENT_R

/* Define to 1 if you have the `getgrgid' function. */
#undef HAVE_GETGRGID

Expand Down
Loading