Index: Lib/test/test_posix.py =================================================================== --- Lib/test/test_posix.py (revision 82172) +++ Lib/test/test_posix.py (working copy) @@ -12,8 +12,8 @@ import shutil import unittest import warnings +import sys - warnings.filterwarnings('ignore', '.* potential security risk .*', RuntimeWarning) @@ -356,10 +356,59 @@ finally: os.chdir(curdir) shutil.rmtree(base_path) + + def test_getgroups(self): + with os.popen('id -G') as idg: + groups = idg.read().strip() + if not groups: + raise unittest.SkipTest("need working 'id -G'") + grouplist = map(int, groups.split()) + if sys.platform == "darwin" and len(grouplist) > 16: + raise unittest.SkipTest("grouplist cannot handle more" + " than 16 groups on darwin") + self.assertListEqual(grouplist, posix.getgroups()) +class PosixGroupsTester(unittest.TestCase): + + def setUp(self): + if posix.getuid() != 0: + raise unittest.SkipTest("not enough privileges") + if not hasattr(posix, 'getgroups'): + raise unittest.SkipTest("need posix.getgroups") + self.saved_groups = posix.getgroups() + def tearDown(self): + if hasattr(posix, 'setgroups'): + posix.setgroups(self.saved_groups) + elif hasattr(posix, 'initgroups'): + name = pwd.getpwuid(posix.getuid()).pw_name + posix.initgroups(name, self.saved_groups[0]) + + @unittest.skipUnless(hasattr(posix, 'initgroups'), + "test needs posix.initgroups()") + def test_initgroups(self): + # find missing group + groups = sorted(self.saved_groups) + for g1,g2 in zip(groups[:-1], groups[1:]): + g = g1 + 1 + if g < g2: + break + else: + g = g2 + 1 + name = pwd.getpwuid(posix.getuid()).pw_name + posix.initgroups(name, g) + self.assertIn(g, posix.getgroups()) + + @unittest.skipUnless(hasattr(posix, 'setgroups'), + "test needs posix.setgroups()") + def test_setgroups(self): + for groups in [[0], range(16)]: + posix.setgroups(groups) + self.assertListEqual(groups, posix.getgroups()) + + def test_main(): - test_support.run_unittest(PosixTester) + test_support.run_unittest(PosixTester, PosixGroupsTester) if __name__ == '__main__': test_main() Index: Modules/posixmodule.c =================================================================== --- Modules/posixmodule.c (revision 82172) +++ Modules/posixmodule.c (working copy) @@ -3842,6 +3842,10 @@ #ifdef HAVE_GETGROUPS +# ifdef __APPLE__ +int _posix_getgroups(int, gid_t []) __asm("_getgroups"); +# define getgroups _posix_getgroups +# endif PyDoc_STRVAR(posix_getgroups__doc__, "getgroups() -> list of group IDs\n\n\ Return list of supplemental group IDs for the process."); @@ -3860,7 +3864,7 @@ gid_t grouplist[MAX_GROUPS]; int n; - n = getgroups(MAX_GROUPS, grouplist); + n = _posix_getgroups(MAX_GROUPS, grouplist); if (n < 0) posix_error(); else {