From 2e3e593e3490202757e25a82a8b3420418597cab Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Thu, 1 Aug 2013 19:34:46 -0700 Subject: [PATCH 1/2] Issue #17899: Fix rare file descriptor leak in os.listdir(). (Done as separate patch from trunk as the code has diverged quite a bit.) --- Misc/NEWS | 2 ++ Modules/posixmodule.c | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/Misc/NEWS b/Misc/NEWS index 82b1081fda7..825f6b3a133 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,8 @@ What's New in Python 3.3.3 release candidate 1? Core and Builtins ----------------- +- Issue #17899: Fix rare file descriptor leak in os.listdir(). + - Issue #18552: Check return value of PyArena_AddPyObject() in obj2ast_object(). diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 1ca12f3c70e..56903c42f10 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -3443,7 +3443,9 @@ posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) path_t path; PyObject *list = NULL; static char *keywords[] = {"path", NULL}; +#ifdef HAVE_FDOPENDIR int fd = -1; +#endif /* HAVE_FDOPENDIR */ #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) PyObject *v; @@ -3732,6 +3734,13 @@ exit: if (dirp == NULL) { list = path_error("listdir", &path); +#ifdef HAVE_FDOPENDIR + if (fd != -1) { + Py_BEGIN_ALLOW_THREADS + close(fd); + Py_END_ALLOW_THREADS + } +#endif /* HAVE_FDOPENDIR */ goto exit; } if ((list = PyList_New(0)) == NULL) { @@ -3774,8 +3783,10 @@ exit: exit: if (dirp != NULL) { Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_FDOPENDIR if (fd > -1) rewinddir(dirp); +#endif /* HAVE_FDOPENDIR */ closedir(dirp); Py_END_ALLOW_THREADS } From b5dd6d228777a12801ccc48aa1b9050b6a614576 Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Thu, 1 Aug 2013 21:21:15 -0700 Subject: [PATCH 2/2] Issue #17557: Fix os.getgroups() to work with the modified behavior of getgroups(2) on OS X 10.8. Original patch by Mateusz Lenik. --- Misc/ACKS | 1 + Misc/NEWS | 3 +++ Modules/posixmodule.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/Misc/ACKS b/Misc/ACKS index aaa8dd4433f..54fa661fbe9 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -721,6 +721,7 @@ Petri Lehtinen Luke Kenneth Casson Leighton Tshepang Lekhonkhobe Marc-André Lemburg +Mateusz Lenik John Lenton Kostyantyn Leschenko Christopher Tur Lesniewski-Laas diff --git a/Misc/NEWS b/Misc/NEWS index 825f6b3a133..f0cbca20e7b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -59,6 +59,9 @@ Core and Builtins Library ------- +- Issue #17557: Fix os.getgroups() to work with the modified behavior of + getgroups(2) on OS X 10.8. Original patch by Mateusz Lenik. + - Issue #18599: Fix name attribute of _sha1.sha1() object. It now returns 'SHA1' instead of 'SHA'. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 56903c42f10..32c85b8be91 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6331,6 +6331,34 @@ posix_getgroups(PyObject *self, PyObject *noargs) gid_t* alt_grouplist = grouplist; int n; +#ifdef __APPLE__ + /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if + * there are more groups than can fit in grouplist. Therefore, on OS X + * always first call getgroups with length 0 to get the actual number + * of groups. + */ + n = getgroups(0, NULL); + if (n < 0) { + return posix_error(); + } else if (n <= MAX_GROUPS) { + /* groups will fit in existing array */ + alt_grouplist = grouplist; + } else { + alt_grouplist = PyMem_Malloc(n * sizeof(gid_t)); + if (alt_grouplist == NULL) { + errno = EINVAL; + return posix_error(); + } + } + + n = getgroups(n, alt_grouplist); + if (n == -1) { + if (alt_grouplist != grouplist) { + PyMem_Free(alt_grouplist); + } + return posix_error(); + } +#else n = getgroups(MAX_GROUPS, grouplist); if (n < 0) { if (errno == EINVAL) { @@ -6357,6 +6385,8 @@ posix_getgroups(PyObject *self, PyObject *noargs) return posix_error(); } } +#endif + result = PyList_New(n); if (result != NULL) { int i;