diff options
author | Ronald Oussoren <ronaldoussoren@mac.com> | 2010-07-23 15:46:03 (GMT) |
---|---|---|
committer | Ronald Oussoren <ronaldoussoren@mac.com> | 2010-07-23 15:46:03 (GMT) |
commit | 47076f7897427d34a8025c1b4f330d1312facc83 (patch) | |
tree | 147962d4e226ee25121a12e5205d133d9f198117 /Modules | |
parent | 7180d4878114f8e427764b29a781b7c0a7e1f2dc (diff) | |
download | cpython-47076f7897427d34a8025c1b4f330d1312facc83.zip cpython-47076f7897427d34a8025c1b4f330d1312facc83.tar.gz cpython-47076f7897427d34a8025c1b4f330d1312facc83.tar.bz2 |
This fixes issue7900 by adding code that deals
with the fact that getgroups(2) might return
more that MAX_GROUPS on OSX.
See the issue (and python-dev archives) for the
gory details. Summarized: OSX behaves rather oddly
and Apple says this is intentional.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/posixmodule.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 65a0a5e..cb3075b 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -3995,17 +3995,49 @@ posix_getgroups(PyObject *self, PyObject *noargs) #define MAX_GROUPS 64 #endif gid_t grouplist[MAX_GROUPS]; + + /* On MacOSX getgroups(2) can return more than MAX_GROUPS results + * This is a helper variable to store the intermediate result when + * that happens. + * + * To keep the code readable the OSX behaviour is unconditional, + * according to the POSIX spec this should be safe on all unix-y + * systems. + */ + gid_t* alt_grouplist = grouplist; int n; n = getgroups(MAX_GROUPS, grouplist); - if (n < 0) - posix_error(); - else { - result = PyList_New(n); - if (result != NULL) { + if (n < 0) { + if (errno == EINVAL) { + n = getgroups(0, NULL); + if (n == -1) { + return posix_error(); + } + if (n == 0) { + /* Avoid malloc(0) */ + 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) { + PyMem_Free(alt_grouplist); + return posix_error(); + } + } + } else { + return posix_error(); + } + } + result = PyList_New(n); + if (result != NULL) { int i; for (i = 0; i < n; ++i) { - PyObject *o = PyLong_FromLong((long)grouplist[i]); + PyObject *o = PyLong_FromLong((long)alt_grouplist[i]); if (o == NULL) { Py_DECREF(result); result = NULL; @@ -4013,7 +4045,10 @@ posix_getgroups(PyObject *self, PyObject *noargs) } PyList_SET_ITEM(result, i, o); } - } + } + + if (alt_grouplist != grouplist) { + PyMem_Free(alt_grouplist); } return result; |