Mercurial > cpython-lru_cache-weakref
diff Modules/posixmodule.c @ 63196:ff6449643142 2.7
Merged revisions 83088 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k
........
r83088 | ronald.oussoren | 2010-07-23 14:53:51 +0100 (Fri, 23 Jul 2010) | 8 lines
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.
........
| author | Ronald Oussoren <ronaldoussoren@mac.com> |
|---|---|
| date | Sat, 24 Jul 2010 09:46:41 +0000 |
| parents | 98a4e96f1f67 |
| children | fa485dcea613 |
line wrap: on
line diff
--- a/Modules/posixmodule.c Sat Jul 24 02:51:49 2010 +0000 +++ b/Modules/posixmodule.c Sat Jul 24 09:46:41 2010 +0000 @@ -3877,17 +3877,49 @@ #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 = PyInt_FromLong((long)grouplist[i]); + PyObject *o = PyInt_FromLong((long)alt_grouplist[i]); if (o == NULL) { Py_DECREF(result); result = NULL; @@ -3895,7 +3927,10 @@ } PyList_SET_ITEM(result, i, o); } - } + } + + if (alt_grouplist != grouplist) { + PyMem_Free(alt_grouplist); } return result;
