summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorRonald Oussoren <ronaldoussoren@mac.com>2010-07-24 09:46:41 (GMT)
committerRonald Oussoren <ronaldoussoren@mac.com>2010-07-24 09:46:41 (GMT)
commit9e7ffae537c72c361725ab7c6c8adede4eb9a8e0 (patch)
tree9d0c3cdad4a59457b972b2346935a385620df970 /Modules
parent8b0d84e3d56f185e70b2f862d8f5bc33d1da92b3 (diff)
downloadcpython-9e7ffae537c72c361725ab7c6c8adede4eb9a8e0.zip
cpython-9e7ffae537c72c361725ab7c6c8adede4eb9a8e0.tar.gz
cpython-9e7ffae537c72c361725ab7c6c8adede4eb9a8e0.tar.bz2
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. ........
Diffstat (limited to 'Modules')
-rw-r--r--Modules/posixmodule.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index c365bc8..d0d68c9 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -3877,17 +3877,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 = 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 @@ posix_getgroups(PyObject *self, PyObject *noargs)
}
PyList_SET_ITEM(result, i, o);
}
- }
+ }
+
+ if (alt_grouplist != grouplist) {
+ PyMem_Free(alt_grouplist);
}
return result;