diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2013-02-12 07:27:53 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2013-02-12 07:27:53 (GMT) |
commit | da5c2a064699c657b69e11aaab0eca8d743dd7ed (patch) | |
tree | 03091e586fad8bdfeb0fd966379e9bb7d30416b0 | |
parent | 083c0aac32b5edaf84f2a37232238d80ddfc00e7 (diff) | |
download | cpython-da5c2a064699c657b69e11aaab0eca8d743dd7ed.zip cpython-da5c2a064699c657b69e11aaab0eca8d743dd7ed.tar.gz cpython-da5c2a064699c657b69e11aaab0eca8d743dd7ed.tar.bz2 |
Issue #4591: Uid and gid values larger than 2**31 are supported now.
-rw-r--r-- | Lib/test/test_posix.py | 29 | ||||
-rw-r--r-- | Lib/test/test_pwd.py | 9 | ||||
-rw-r--r-- | Makefile.pre.in | 5 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Modules/grpmodule.c | 20 | ||||
-rw-r--r-- | Modules/posixmodule.c | 331 | ||||
-rw-r--r-- | Modules/posixmodule.h | 25 | ||||
-rw-r--r-- | Modules/pwdmodule.c | 22 |
8 files changed, 299 insertions, 144 deletions
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 2fba330..f995a9c 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -222,10 +222,20 @@ class PosixTester(unittest.TestCase): if hasattr(posix, 'stat'): self.assertTrue(posix.stat(test_support.TESTFN)) - def _test_all_chown_common(self, chown_func, first_param): + def _test_all_chown_common(self, chown_func, first_param, stat_func): """Common code for chown, fchown and lchown tests.""" + def check_stat(): + if stat_func is not None: + stat = stat_func(first_param) + self.assertEqual(stat.st_uid, os.getuid()) + self.assertEqual(stat.st_gid, os.getgid()) # test a successful chown call chown_func(first_param, os.getuid(), os.getgid()) + check_stat() + chown_func(first_param, -1, os.getgid()) + check_stat() + chown_func(first_param, os.getuid(), -1) + check_stat() if os.getuid() == 0: try: @@ -245,8 +255,12 @@ class PosixTester(unittest.TestCase): "behavior") else: # non-root cannot chown to root, raises OSError - self.assertRaises(OSError, chown_func, - first_param, 0, 0) + self.assertRaises(OSError, chown_func, first_param, 0, 0) + check_stat() + self.assertRaises(OSError, chown_func, first_param, -1, 0) + check_stat() + self.assertRaises(OSError, chown_func, first_param, 0, -1) + check_stat() @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()") def test_chown(self): @@ -256,7 +270,8 @@ class PosixTester(unittest.TestCase): # re-create the file open(test_support.TESTFN, 'w').close() - self._test_all_chown_common(posix.chown, test_support.TESTFN) + self._test_all_chown_common(posix.chown, test_support.TESTFN, + getattr(posix, 'stat', None)) @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()") def test_fchown(self): @@ -266,7 +281,8 @@ class PosixTester(unittest.TestCase): test_file = open(test_support.TESTFN, 'w') try: fd = test_file.fileno() - self._test_all_chown_common(posix.fchown, fd) + self._test_all_chown_common(posix.fchown, fd, + getattr(posix, 'fstat', None)) finally: test_file.close() @@ -275,7 +291,8 @@ class PosixTester(unittest.TestCase): os.unlink(test_support.TESTFN) # create a symlink os.symlink(_DUMMY_SYMLINK, test_support.TESTFN) - self._test_all_chown_common(posix.lchown, test_support.TESTFN) + self._test_all_chown_common(posix.lchown, test_support.TESTFN, + getattr(posix, 'lstat', None)) def test_chdir(self): if hasattr(posix, 'chdir'): diff --git a/Lib/test/test_pwd.py b/Lib/test/test_pwd.py index 67e11b6..ce8b8b3 100644 --- a/Lib/test/test_pwd.py +++ b/Lib/test/test_pwd.py @@ -49,7 +49,9 @@ class PwdTest(unittest.TestCase): def test_errors(self): self.assertRaises(TypeError, pwd.getpwuid) + self.assertRaises(TypeError, pwd.getpwuid, 3.14) self.assertRaises(TypeError, pwd.getpwnam) + self.assertRaises(TypeError, pwd.getpwnam, 42) self.assertRaises(TypeError, pwd.getpwall, 42) # try to get some errors @@ -93,6 +95,13 @@ class PwdTest(unittest.TestCase): self.assertNotIn(fakeuid, byuids) self.assertRaises(KeyError, pwd.getpwuid, fakeuid) + # -1 shouldn't be a valid uid because it has a special meaning in many + # uid-related functions + self.assertRaises(KeyError, pwd.getpwuid, -1) + # should be out of uid_t range + self.assertRaises(KeyError, pwd.getpwuid, 2**128) + self.assertRaises(KeyError, pwd.getpwuid, -2**128) + def test_main(): test_support.run_unittest(PwdTest) diff --git a/Makefile.pre.in b/Makefile.pre.in index 0f8f823..01f4699 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -579,6 +579,11 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile Modules/python.o: $(srcdir)/Modules/python.c $(MAINCC) -c $(PY_CFLAGS) -o $@ $(srcdir)/Modules/python.c +Modules/posixmodule.o: $(srcdir)/Modules/posixmodule.c $(srcdir)/Modules/posixmodule.h + +Modules/grpmodule.o: $(srcdir)/Modules/grpmodule.c $(srcdir)/Modules/posixmodule.h + +Modules/pwdmodule.o: $(srcdir)/Modules/pwdmodule.c $(srcdir)/Modules/posixmodule.h $(GRAMMAR_H): $(GRAMMAR_INPUT) $(PGENSRCS) @$(MKDIR_P) Include @@ -204,6 +204,8 @@ Library - Issue #17052: unittest discovery should use self.testLoader. +- Issue #4591: Uid and gid values larger than 2**31 are supported now. + - Issue #17141: random.vonmisesvariate() no more hangs for large kappas. - Issue #17149: Fix random.vonmisesvariate to always return results in diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index ebc38cc..55da9b8 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -3,8 +3,8 @@ #include "Python.h" #include "structseq.h" +#include "posixmodule.h" -#include <sys/types.h> #include <grp.h> static PyStructSequence_Field struct_group_type_fields[] = { @@ -70,7 +70,7 @@ mkgrent(struct group *p) Py_INCREF(Py_None); } #endif - SET(setIndex++, PyInt_FromLong((long) p->gr_gid)); + SET(setIndex++, _PyInt_FromGid(p->gr_gid)); SET(setIndex++, w); #undef SET @@ -86,17 +86,25 @@ static PyObject * grp_getgrgid(PyObject *self, PyObject *pyo_id) { PyObject *py_int_id; - unsigned int gid; + gid_t gid; struct group *p; py_int_id = PyNumber_Int(pyo_id); if (!py_int_id) - return NULL; - gid = PyInt_AS_LONG(py_int_id); + return NULL; + if (!_Py_Gid_Converter(py_int_id, &gid)) { + Py_DECREF(py_int_id); + return NULL; + } Py_DECREF(py_int_id); if ((p = getgrgid(gid)) == NULL) { - PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid); + if (gid < 0) + PyErr_Format(PyExc_KeyError, + "getgrgid(): gid not found: %ld", (long)gid); + else + PyErr_Format(PyExc_KeyError, + "getgrgid(): gid not found: %lu", (unsigned long)gid); return NULL; } return mkgrent(p); diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 776c7c6..a06ebd1 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -27,6 +27,9 @@ #include "Python.h" #include "structseq.h" +#ifndef MS_WINDOWS +#include "posixmodule.h" +#endif #if defined(__VMS) # include <unixio.h> @@ -347,6 +350,134 @@ extern int lstat(const char *, struct stat *); #endif #endif + +#ifndef MS_WINDOWS +PyObject * +_PyInt_FromUid(uid_t uid) +{ + if (uid <= LONG_MAX) + return PyInt_FromLong(uid); + return PyLong_FromUnsignedLong(uid); +} + +PyObject * +_PyInt_FromGid(gid_t gid) +{ + if (gid <= LONG_MAX) + return PyInt_FromLong(gid); + return PyLong_FromUnsignedLong(gid); +} + +int +_Py_Uid_Converter(PyObject *obj, void *p) +{ + int overflow; + long result; + if (PyFloat_Check(obj)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float"); + return 0; + } + result = PyLong_AsLongAndOverflow(obj, &overflow); + if (overflow < 0) + goto OverflowDown; + if (!overflow && result == -1) { + /* error or -1 */ + if (PyErr_Occurred()) + return 0; + *(uid_t *)p = (uid_t)-1; + } + else { + /* unsigned uid_t */ + unsigned long uresult; + if (overflow > 0) { + uresult = PyLong_AsUnsignedLong(obj); + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + goto OverflowUp; + return 0; + } + if ((uid_t)uresult == (uid_t)-1) + goto OverflowUp; + } else { + if (result < 0) + goto OverflowDown; + uresult = result; + } + if (sizeof(uid_t) < sizeof(long) && + (unsigned long)(uid_t)uresult != uresult) + goto OverflowUp; + *(uid_t *)p = (uid_t)uresult; + } + return 1; + +OverflowDown: + PyErr_SetString(PyExc_OverflowError, + "user id is less than minimum"); + return 0; + +OverflowUp: + PyErr_SetString(PyExc_OverflowError, + "user id is greater than maximum"); + return 0; +} + +int +_Py_Gid_Converter(PyObject *obj, void *p) +{ + int overflow; + long result; + if (PyFloat_Check(obj)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float"); + return 0; + } + result = PyLong_AsLongAndOverflow(obj, &overflow); + if (overflow < 0) + goto OverflowDown; + if (!overflow && result == -1) { + /* error or -1 */ + if (PyErr_Occurred()) + return 0; + *(gid_t *)p = (gid_t)-1; + } + else { + /* unsigned gid_t */ + unsigned long uresult; + if (overflow > 0) { + uresult = PyLong_AsUnsignedLong(obj); + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + goto OverflowUp; + return 0; + } + if ((gid_t)uresult == (gid_t)-1) + goto OverflowUp; + } else { + if (result < 0) + goto OverflowDown; + uresult = result; + } + if (sizeof(gid_t) < sizeof(long) && + (unsigned long)(gid_t)uresult != uresult) + goto OverflowUp; + *(gid_t *)p = (gid_t)uresult; + } + return 1; + +OverflowDown: + PyErr_SetString(PyExc_OverflowError, + "group id is less than minimum"); + return 0; + +OverflowUp: + PyErr_SetString(PyExc_OverflowError, + "group id is greater than maximum"); + return 0; +} +#endif /* MS_WINDOWS */ + + #if defined _MSC_VER && _MSC_VER >= 1400 /* Microsoft CRT in VS2005 and higher will verify that a filehandle is * valid and raise an assertion if it isn't. @@ -1306,8 +1437,13 @@ _pystat_fromstructstat(STRUCT_STAT *st) PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev)); #endif PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink)); - PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid)); - PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid)); +#if defined(MS_WINDOWS) + PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong(0)); + PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong(0)); +#else + PyStructSequence_SET_ITEM(v, 4, _PyInt_FromUid(st->st_uid)); + PyStructSequence_SET_ITEM(v, 5, _PyInt_FromGid(st->st_gid)); +#endif #ifdef HAVE_LARGEFILE_SUPPORT PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong((PY_LONG_LONG)st->st_size)); @@ -1884,14 +2020,16 @@ static PyObject * posix_chown(PyObject *self, PyObject *args) { char *path = NULL; - long uid, gid; + uid_t uid; + gid_t gid; int res; - if (!PyArg_ParseTuple(args, "etll:chown", + if (!PyArg_ParseTuple(args, "etO&O&:chown", Py_FileSystemDefaultEncoding, &path, - &uid, &gid)) + _Py_Uid_Converter, &uid, + _Py_Gid_Converter, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS - res = chown(path, (uid_t) uid, (gid_t) gid); + res = chown(path, uid, gid); Py_END_ALLOW_THREADS if (res < 0) return posix_error_with_allocated_filename(path); @@ -1911,12 +2049,15 @@ static PyObject * posix_fchown(PyObject *self, PyObject *args) { int fd; - long uid, gid; + uid_t uid; + gid_t gid; int res; - if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid)) + if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd, + _Py_Uid_Converter, &uid, + _Py_Gid_Converter, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS - res = fchown(fd, (uid_t) uid, (gid_t) gid); + res = fchown(fd, uid, gid); Py_END_ALLOW_THREADS if (res < 0) return posix_error(); @@ -1934,14 +2075,16 @@ static PyObject * posix_lchown(PyObject *self, PyObject *args) { char *path = NULL; - long uid, gid; + uid_t uid; + gid_t gid; int res; - if (!PyArg_ParseTuple(args, "etll:lchown", + if (!PyArg_ParseTuple(args, "etO&O&:lchown", Py_FileSystemDefaultEncoding, &path, - &uid, &gid)) + _Py_Uid_Converter, &uid, + _Py_Gid_Converter, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS - res = lchown(path, (uid_t) uid, (gid_t) gid); + res = lchown(path, uid, gid); Py_END_ALLOW_THREADS if (res < 0) return posix_error_with_allocated_filename(path); @@ -3844,7 +3987,7 @@ Return the current process's effective group id."); static PyObject * posix_getegid(PyObject *self, PyObject *noargs) { - return PyInt_FromLong((long)getegid()); + return _PyInt_FromGid(getegid()); } #endif @@ -3857,7 +4000,7 @@ Return the current process's effective user id."); static PyObject * posix_geteuid(PyObject *self, PyObject *noargs) { - return PyInt_FromLong((long)geteuid()); + return _PyInt_FromUid(geteuid()); } #endif @@ -3870,7 +4013,7 @@ Return the current process's group id."); static PyObject * posix_getgid(PyObject *self, PyObject *noargs) { - return PyInt_FromLong((long)getgid()); + return _PyInt_FromGid(getgid()); } #endif @@ -3945,7 +4088,7 @@ posix_getgroups(PyObject *self, PyObject *noargs) if (result != NULL) { int i; for (i = 0; i < n; ++i) { - PyObject *o = PyInt_FromLong((long)alt_grouplist[i]); + PyObject *o = _PyInt_FromGid(alt_grouplist[i]); if (o == NULL) { Py_DECREF(result); result = NULL; @@ -3974,12 +4117,22 @@ static PyObject * posix_initgroups(PyObject *self, PyObject *args) { char *username; - long gid; +#ifdef __APPLE__ + int gid; +#else + gid_t gid; +#endif - if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid)) +#ifdef __APPLE__ + if (!PyArg_ParseTuple(args, "si:initgroups", &username, + &gid)) +#else + if (!PyArg_ParseTuple(args, "sO&:initgroups", &username, + _Py_Gid_Converter, &gid)) +#endif return NULL; - if (initgroups(username, (gid_t) gid) == -1) + if (initgroups(username, gid) == -1) return PyErr_SetFromErrno(PyExc_OSError); Py_INCREF(Py_None); @@ -4093,7 +4246,7 @@ Return the current process's user id."); static PyObject * posix_getuid(PyObject *self, PyObject *noargs) { - return PyInt_FromLong((long)getuid()); + return _PyInt_FromUid(getuid()); } #endif @@ -5740,15 +5893,9 @@ Set the current process's user id."); static PyObject * posix_setuid(PyObject *self, PyObject *args) { - long uid_arg; uid_t uid; - if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg)) - return NULL; - uid = uid_arg; - if (uid != uid_arg) { - PyErr_SetString(PyExc_OverflowError, "user id too big"); + if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid)) return NULL; - } if (setuid(uid) < 0) return posix_error(); Py_INCREF(Py_None); @@ -5765,15 +5912,9 @@ Set the current process's effective user id."); static PyObject * posix_seteuid (PyObject *self, PyObject *args) { - long euid_arg; uid_t euid; - if (!PyArg_ParseTuple(args, "l", &euid_arg)) + if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid)) return NULL; - euid = euid_arg; - if (euid != euid_arg) { - PyErr_SetString(PyExc_OverflowError, "user id too big"); - return NULL; - } if (seteuid(euid) < 0) { return posix_error(); } else { @@ -5791,15 +5932,9 @@ Set the current process's effective group id."); static PyObject * posix_setegid (PyObject *self, PyObject *args) { - long egid_arg; gid_t egid; - if (!PyArg_ParseTuple(args, "l", &egid_arg)) + if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid)) return NULL; - egid = egid_arg; - if (egid != egid_arg) { - PyErr_SetString(PyExc_OverflowError, "group id too big"); - return NULL; - } if (setegid(egid) < 0) { return posix_error(); } else { @@ -5817,23 +5952,11 @@ Set the current process's real and effective user ids."); static PyObject * posix_setreuid (PyObject *self, PyObject *args) { - long ruid_arg, euid_arg; uid_t ruid, euid; - if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg)) - return NULL; - if (ruid_arg == -1) - ruid = (uid_t)-1; /* let the compiler choose how -1 fits */ - else - ruid = ruid_arg; /* otherwise, assign from our long */ - if (euid_arg == -1) - euid = (uid_t)-1; - else - euid = euid_arg; - if ((euid_arg != -1 && euid != euid_arg) || - (ruid_arg != -1 && ruid != ruid_arg)) { - PyErr_SetString(PyExc_OverflowError, "user id too big"); + if (!PyArg_ParseTuple(args, "O&O&:setreuid", + _Py_Uid_Converter, &ruid, + _Py_Uid_Converter, &euid)) return NULL; - } if (setreuid(ruid, euid) < 0) { return posix_error(); } else { @@ -5851,23 +5974,11 @@ Set the current process's real and effective group ids."); static PyObject * posix_setregid (PyObject *self, PyObject *args) { - long rgid_arg, egid_arg; gid_t rgid, egid; - if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg)) + if (!PyArg_ParseTuple(args, "O&O&:setregid", + _Py_Gid_Converter, &rgid, + _Py_Gid_Converter, &egid)) return NULL; - if (rgid_arg == -1) - rgid = (gid_t)-1; /* let the compiler choose how -1 fits */ - else - rgid = rgid_arg; /* otherwise, assign from our long */ - if (egid_arg == -1) - egid = (gid_t)-1; - else - egid = egid_arg; - if ((egid_arg != -1 && egid != egid_arg) || - (rgid_arg != -1 && rgid != rgid_arg)) { - PyErr_SetString(PyExc_OverflowError, "group id too big"); - return NULL; - } if (setregid(rgid, egid) < 0) { return posix_error(); } else { @@ -5885,15 +5996,9 @@ Set the current process's group id."); static PyObject * posix_setgid(PyObject *self, PyObject *args) { - long gid_arg; gid_t gid; - if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg)) - return NULL; - gid = gid_arg; - if (gid != gid_arg) { - PyErr_SetString(PyExc_OverflowError, "group id too big"); + if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid)) return NULL; - } if (setgid(gid) < 0) return posix_error(); Py_INCREF(Py_None); @@ -5926,35 +6031,13 @@ posix_setgroups(PyObject *self, PyObject *groups) elem = PySequence_GetItem(groups, i); if (!elem) return NULL; - if (!PyInt_Check(elem)) { - if (!PyLong_Check(elem)) { - PyErr_SetString(PyExc_TypeError, - "groups must be integers"); - Py_DECREF(elem); - return NULL; - } else { - unsigned long x = PyLong_AsUnsignedLong(elem); - if (PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "group id too big"); - Py_DECREF(elem); - return NULL; - } - grouplist[i] = x; - /* read back to see if it fits in gid_t */ - if (grouplist[i] != x) { - PyErr_SetString(PyExc_TypeError, - "group id too big"); - Py_DECREF(elem); - return NULL; - } - } + if (!PyInt_Check(elem) && !PyLong_Check(elem)) { + PyErr_SetString(PyExc_TypeError, + "groups must be integers"); + Py_DECREF(elem); + return NULL; } else { - long x = PyInt_AsLong(elem); - grouplist[i] = x; - if (grouplist[i] != x) { - PyErr_SetString(PyExc_TypeError, - "group id too big"); + if (!_Py_Gid_Converter(elem, &grouplist[i])) { Py_DECREF(elem); return NULL; } @@ -8580,9 +8663,11 @@ Set the current process's real, effective, and saved user ids."); static PyObject* posix_setresuid (PyObject *self, PyObject *args) { - /* We assume uid_t is no larger than a long. */ - long ruid, euid, suid; - if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid)) + uid_t ruid, euid, suid; + if (!PyArg_ParseTuple(args, "O&O&O&:setresuid", + _Py_Uid_Converter, &ruid, + _Py_Uid_Converter, &euid, + _Py_Uid_Converter, &suid)) return NULL; if (setresuid(ruid, euid, suid) < 0) return posix_error(); @@ -8598,9 +8683,11 @@ Set the current process's real, effective, and saved group ids."); static PyObject* posix_setresgid (PyObject *self, PyObject *args) { - /* We assume uid_t is no larger than a long. */ - long rgid, egid, sgid; - if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid)) + gid_t rgid, egid, sgid; + if (!PyArg_ParseTuple(args, "O&O&O&:setresgid", + _Py_Gid_Converter, &rgid, + _Py_Gid_Converter, &egid, + _Py_Gid_Converter, &sgid)) return NULL; if (setresgid(rgid, egid, sgid) < 0) return posix_error(); @@ -8617,14 +8704,11 @@ static PyObject* posix_getresuid (PyObject *self, PyObject *noargs) { uid_t ruid, euid, suid; - long l_ruid, l_euid, l_suid; if (getresuid(&ruid, &euid, &suid) < 0) return posix_error(); - /* Force the values into long's as we don't know the size of uid_t. */ - l_ruid = ruid; - l_euid = euid; - l_suid = suid; - return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid); + return Py_BuildValue("(NNN)", _PyInt_FromUid(ruid), + _PyInt_FromUid(euid), + _PyInt_FromUid(suid)); } #endif @@ -8637,14 +8721,11 @@ static PyObject* posix_getresgid (PyObject *self, PyObject *noargs) { uid_t rgid, egid, sgid; - long l_rgid, l_egid, l_sgid; if (getresgid(&rgid, &egid, &sgid) < 0) return posix_error(); - /* Force the values into long's as we don't know the size of uid_t. */ - l_rgid = rgid; - l_egid = egid; - l_sgid = sgid; - return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid); + return Py_BuildValue("(NNN)", _PyInt_FromGid(rgid), + _PyInt_FromGid(egid), + _PyInt_FromGid(sgid)); } #endif diff --git a/Modules/posixmodule.h b/Modules/posixmodule.h new file mode 100644 index 0000000..084e063 --- /dev/null +++ b/Modules/posixmodule.h @@ -0,0 +1,25 @@ +/* Declarations shared between the different POSIX-related modules */ + +#ifndef Py_POSIXMODULE_H +#define Py_POSIXMODULE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifndef Py_LIMITED_API +#ifndef MS_WINDOWS +PyAPI_FUNC(PyObject *) _PyInt_FromUid(uid_t); +PyAPI_FUNC(PyObject *) _PyInt_FromGid(gid_t); +PyAPI_FUNC(int) _Py_Uid_Converter(PyObject *, void *); +PyAPI_FUNC(int) _Py_Gid_Converter(PyObject *, void *); +#endif /* MS_WINDOWS */ +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_POSIXMODULE_H */ diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index 6729c84..c2907f6 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -3,8 +3,8 @@ #include "Python.h" #include "structseq.h" +#include "posixmodule.h" -#include <sys/types.h> #include <pwd.h> static PyStructSequence_Field struct_pwd_type_fields[] = { @@ -73,8 +73,8 @@ mkpwent(struct passwd *p) #else SETS(setIndex++, p->pw_passwd); #endif - SETI(setIndex++, p->pw_uid); - SETI(setIndex++, p->pw_gid); + PyStructSequence_SET_ITEM(v, setIndex++, _PyInt_FromUid(p->pw_uid)); + PyStructSequence_SET_ITEM(v, setIndex++, _PyInt_FromGid(p->pw_gid)); #ifdef __VMS SETS(setIndex++, ""); #else @@ -103,13 +103,21 @@ See help(pwd) for more on password database entries."); static PyObject * pwd_getpwuid(PyObject *self, PyObject *args) { - unsigned int uid; + uid_t uid; struct passwd *p; - if (!PyArg_ParseTuple(args, "I:getpwuid", &uid)) + if (!PyArg_ParseTuple(args, "O&:getpwuid", _Py_Uid_Converter, &uid)) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + PyErr_Format(PyExc_KeyError, + "getpwuid(): uid not found"); return NULL; + } if ((p = getpwuid(uid)) == NULL) { - PyErr_Format(PyExc_KeyError, - "getpwuid(): uid not found: %d", uid); + if (uid < 0) + PyErr_Format(PyExc_KeyError, + "getpwuid(): uid not found: %ld", (long)uid); + else + PyErr_Format(PyExc_KeyError, + "getpwuid(): uid not found: %lu", (unsigned long)uid); return NULL; } return mkpwent(p); |