Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b0ae53d

Browse files
committed
Issue #9344: Add os.getgrouplist().
1 parent 10c30d6 commit b0ae53d

6 files changed

Lines changed: 368 additions & 252 deletions

File tree

Doc/library/os.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,17 @@ process and user.
219219
Availability: Unix.
220220

221221

222+
.. function:: getgrouplist(user, group)
223+
224+
Return list of group ids that *user* belongs to. If *group* is not in the
225+
list, it is included; typically, *group* is specified as the group ID
226+
field from the password record for *user*.
227+
228+
Availability: Unix.
229+
230+
.. versionadded:: 3.3
231+
232+
222233
.. function:: getgroups()
223234

224235
Return list of supplemental group ids associated with the current process.

Lib/test/test_posix.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,21 @@ def _create_and_do_getcwd(dirname, current_path_length = 0):
569569
os.chdir(curdir)
570570
support.rmtree(base_path)
571571

572+
@unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
573+
@unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
574+
@unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
575+
def test_getgrouplist(self):
576+
with os.popen('id -G') as idg:
577+
groups = idg.read().strip()
578+
579+
if not groups:
580+
raise unittest.SkipTest("need working 'id -G'")
581+
582+
self.assertEqual(
583+
set([int(x) for x in groups.split()]),
584+
set(posix.getgrouplist(pwd.getpwuid(os.getuid())[0],
585+
pwd.getpwuid(os.getuid())[3])))
586+
572587
@unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
573588
def test_getgroups(self):
574589
with os.popen('id -G') as idg:

Modules/posixmodule.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4672,6 +4672,70 @@ posix_getpid(PyObject *self, PyObject *noargs)
46724672
return PyLong_FromPid(getpid());
46734673
}
46744674

4675+
#ifdef HAVE_GETGROUPLIST
4676+
PyDoc_STRVAR(posix_getgrouplist__doc__,
4677+
"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
4678+
Returns a list of groups to which a user belongs.\n\n\
4679+
user: username to lookup\n\
4680+
group: base group id of the user");
4681+
4682+
static PyObject *
4683+
posix_getgrouplist(PyObject *self, PyObject *args)
4684+
{
4685+
#ifdef NGROUPS_MAX
4686+
#define MAX_GROUPS NGROUPS_MAX
4687+
#else
4688+
/* defined to be 16 on Solaris7, so this should be a small number */
4689+
#define MAX_GROUPS 64
4690+
#endif
4691+
4692+
const char *user;
4693+
int i, ngroups;
4694+
PyObject *list;
4695+
#ifdef __APPLE__
4696+
int *groups, basegid;
4697+
#else
4698+
gid_t *groups, basegid;
4699+
#endif
4700+
ngroups = MAX_GROUPS;
4701+
4702+
if (!PyArg_ParseTuple(args, "si", &user, &basegid))
4703+
return NULL;
4704+
4705+
#ifdef __APPLE__
4706+
groups = PyMem_Malloc(ngroups * sizeof(int));
4707+
#else
4708+
groups = PyMem_Malloc(ngroups * sizeof(gid_t));
4709+
#endif
4710+
if (groups == NULL)
4711+
return PyErr_NoMemory();
4712+
4713+
if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
4714+
PyMem_Del(groups);
4715+
return posix_error();
4716+
}
4717+
4718+
list = PyList_New(ngroups);
4719+
if (list == NULL) {
4720+
PyMem_Del(groups);
4721+
return NULL;
4722+
}
4723+
4724+
for (i = 0; i < ngroups; i++) {
4725+
PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
4726+
if (o == NULL) {
4727+
Py_DECREF(list);
4728+
PyMem_Del(groups);
4729+
return NULL;
4730+
}
4731+
PyList_SET_ITEM(list, i, o);
4732+
}
4733+
4734+
PyMem_Del(groups);
4735+
4736+
return list;
4737+
}
4738+
#endif
46754739

46764740
#ifdef HAVE_GETGROUPS
46774741
PyDoc_STRVAR(posix_getgroups__doc__,
@@ -9383,6 +9447,9 @@ static PyMethodDef posix_methods[] = {
93839447
#ifdef HAVE_GETGID
93849448
{"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
93859449
#endif /* HAVE_GETGID */
9450+
#ifdef HAVE_GETGROUPLIST
9451+
{"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
9452+
#endif
93869453
#ifdef HAVE_GETGROUPS
93879454
{"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
93889455
#endif

0 commit comments

Comments
 (0)