[Python-checkins] cpython (3.2): Issue #4591: Uid and gid values larger than 2**31 are supported now.

serhiy.storchaka python-checkins at python.org
Tue Feb 12 08:36:44 CET 2013


http://hg.python.org/cpython/rev/3893ab574c55
changeset:   82172:3893ab574c55
branch:      3.2
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Tue Feb 12 09:24:16 2013 +0200
summary:
  Issue #4591: Uid and gid values larger than 2**31 are supported now.

files:
  Lib/test/test_posix.py |   29 ++-
  Lib/test/test_pwd.py   |    9 +
  Makefile.pre.in        |    6 +
  Misc/NEWS              |    2 +
  Modules/grpmodule.c    |   17 +-
  Modules/posixmodule.c  |  327 ++++++++++++++++++----------
  Modules/posixmodule.h  |   25 ++
  Modules/pwdmodule.c    |   20 +-
  8 files changed, 301 insertions(+), 134 deletions(-)


diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -232,10 +232,20 @@
         else:
             self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
 
-    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:
@@ -255,8 +265,12 @@
                                     "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):
@@ -266,7 +280,8 @@
 
         # re-create the file
         open(support.TESTFN, 'w').close()
-        self._test_all_chown_common(posix.chown, support.TESTFN)
+        self._test_all_chown_common(posix.chown, support.TESTFN,
+                                    getattr(posix, 'stat', None))
 
     @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
     def test_fchown(self):
@@ -276,7 +291,8 @@
         test_file = open(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()
 
@@ -285,7 +301,8 @@
         os.unlink(support.TESTFN)
         # create a symlink
         os.symlink(_DUMMY_SYMLINK, support.TESTFN)
-        self._test_all_chown_common(posix.lchown, support.TESTFN)
+        self._test_all_chown_common(posix.lchown, 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
--- a/Lib/test/test_pwd.py
+++ b/Lib/test/test_pwd.py
@@ -49,7 +49,9 @@
 
     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 @@
         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():
     support.run_unittest(PwdTest)
 
diff --git a/Makefile.pre.in b/Makefile.pre.in
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -587,6 +587,12 @@
 Modules/python.o: $(srcdir)/Modules/python.c
 	$(MAINCC) -c $(PY_CORE_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
+
 Python/dynload_shlib.o: $(srcdir)/Python/dynload_shlib.c Makefile
 	$(CC) -c $(PY_CORE_CFLAGS) \
 		-DSOABI='"$(SOABI)"' \
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -226,6 +226,8 @@
 
 - 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
--- a/Modules/grpmodule.c
+++ b/Modules/grpmodule.c
@@ -2,8 +2,8 @@
 /* UNIX group file access module */
 
 #include "Python.h"
+#include "posixmodule.h"
 
-#include <sys/types.h>
 #include <grp.h>
 
 static PyStructSequence_Field struct_group_type_fields[] = {
@@ -69,7 +69,7 @@
             Py_INCREF(Py_None);
     }
 #endif
-    SET(setIndex++, PyLong_FromLong((long) p->gr_gid));
+    SET(setIndex++, _PyLong_FromGid(p->gr_gid));
     SET(setIndex++, w);
 #undef SET
 
@@ -85,17 +85,24 @@
 grp_getgrgid(PyObject *self, PyObject *pyo_id)
 {
     PyObject *py_int_id;
-    unsigned int gid;
+    gid_t gid;
     struct group *p;
 
     py_int_id = PyNumber_Long(pyo_id);
     if (!py_int_id)
             return NULL;
-    gid = PyLong_AS_LONG(py_int_id);
+    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);
+        PyObject *gid_obj = _PyLong_FromGid(gid);
+        if (gid_obj == NULL)
+            return NULL;
+        PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj);
+        Py_DECREF(gid_obj);
         return NULL;
     }
     return mkgrent(p);
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -26,6 +26,9 @@
 #define PY_SSIZE_T_CLEAN
 
 #include "Python.h"
+#ifndef MS_WINDOWS
+#include "posixmodule.h"
+#endif
 
 #if defined(__VMS)
 #    include <unixio.h>
@@ -347,6 +350,134 @@
 #endif
 #endif
 
+
+#ifndef MS_WINDOWS
+PyObject *
+_PyLong_FromUid(uid_t uid)
+{
+    if (uid == (uid_t)-1)
+        return PyLong_FromLong(-1);
+    return PyLong_FromUnsignedLong(uid);
+}
+
+PyObject *
+_PyLong_FromGid(gid_t gid)
+{
+    if (gid == (gid_t)-1)
+        return PyLong_FromLong(-1);
+    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.
@@ -1643,8 +1774,13 @@
     PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
 #endif
     PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
-    PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
-    PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
+#if defined(MS_WINDOWS)
+    PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
+    PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
+#else
+    PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
+    PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
+#endif
 #ifdef HAVE_LARGEFILE_SUPPORT
     PyStructSequence_SET_ITEM(v, 6,
                               PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
@@ -2173,15 +2309,17 @@
 {
     PyObject *opath;
     char *path;
-    long uid, gid;
+    uid_t uid;
+    gid_t gid;
     int res;
-    if (!PyArg_ParseTuple(args, "O&ll:chown",
+    if (!PyArg_ParseTuple(args, "O&O&O&:chown",
                           PyUnicode_FSConverter, &opath,
-                          &uid, &gid))
+                          _Py_Uid_Converter, &uid,
+                          _Py_Gid_Converter, &gid))
         return NULL;
     path = PyBytes_AsString(opath);
     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(opath);
@@ -2201,12 +2339,15 @@
 posix_fchown(PyObject *self, PyObject *args)
 {
     int fd;
-    long uid, gid;
+    uid_t uid;
+    gid_t gid;
     int res;
-    if (!PyArg_ParseTuple(args, "ill:fchown", &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();
@@ -2225,15 +2366,17 @@
 {
     PyObject *opath;
     char *path;
-    long uid, gid;
+    uid_t uid;
+    gid_t gid;
     int res;
-    if (!PyArg_ParseTuple(args, "O&ll:lchown",
+    if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
                           PyUnicode_FSConverter, &opath,
-                          &uid, &gid))
+                          _Py_Uid_Converter, &uid,
+                          _Py_Gid_Converter, &gid))
         return NULL;
     path = PyBytes_AsString(opath);
     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(opath);
@@ -4288,7 +4431,7 @@
 static PyObject *
 posix_getegid(PyObject *self, PyObject *noargs)
 {
-    return PyLong_FromLong((long)getegid());
+    return _PyLong_FromGid(getegid());
 }
 #endif
 
@@ -4301,7 +4444,7 @@
 static PyObject *
 posix_geteuid(PyObject *self, PyObject *noargs)
 {
-    return PyLong_FromLong((long)geteuid());
+    return _PyLong_FromUid(geteuid());
 }
 #endif
 
@@ -4314,7 +4457,7 @@
 static PyObject *
 posix_getgid(PyObject *self, PyObject *noargs)
 {
-    return PyLong_FromLong((long)getgid());
+    return _PyLong_FromGid(getgid());
 }
 #endif
 
@@ -4389,7 +4532,7 @@
     if (result != NULL) {
         int i;
         for (i = 0; i < n; ++i) {
-            PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
+            PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
             if (o == NULL) {
                 Py_DECREF(result);
                 result = NULL;
@@ -4420,14 +4563,25 @@
     PyObject *oname;
     char *username;
     int res;
-    long gid;
-
-    if (!PyArg_ParseTuple(args, "O&l:initgroups",
-                          PyUnicode_FSConverter, &oname, &gid))
+#ifdef __APPLE__
+    int gid;
+#else
+    gid_t gid;
+#endif
+
+#ifdef __APPLE__
+    if (!PyArg_ParseTuple(args, "O&i:initgroups",
+                          PyUnicode_FSConverter, &oname,
+                          &gid))
+#else
+    if (!PyArg_ParseTuple(args, "O&O&:initgroups",
+                          PyUnicode_FSConverter, &oname,
+                          _Py_Gid_Converter, &gid))
+#endif
         return NULL;
     username = PyBytes_AS_STRING(oname);
 
-    res = initgroups(username, (gid_t) gid);
+    res = initgroups(username, gid);
     Py_DECREF(oname);
     if (res == -1)
         return PyErr_SetFromErrno(PyExc_OSError);
@@ -4602,7 +4756,7 @@
 static PyObject *
 posix_getuid(PyObject *self, PyObject *noargs)
 {
-    return PyLong_FromLong((long)getuid());
+    return _PyLong_FromUid(getuid());
 }
 #endif
 
@@ -4742,15 +4896,9 @@
 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");
-        return NULL;
-    }
+    if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
+        return NULL;
     if (setuid(uid) < 0)
         return posix_error();
     Py_INCREF(Py_None);
@@ -4767,15 +4915,9 @@
 static PyObject *
 posix_seteuid (PyObject *self, PyObject *args)
 {
-    long euid_arg;
     uid_t euid;
-    if (!PyArg_ParseTuple(args, "l", &euid_arg))
-        return NULL;
-    euid = euid_arg;
-    if (euid != euid_arg) {
-        PyErr_SetString(PyExc_OverflowError, "user id too big");
-        return NULL;
-    }
+    if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
+        return NULL;
     if (seteuid(euid) < 0) {
         return posix_error();
     } else {
@@ -4793,15 +4935,9 @@
 static PyObject *
 posix_setegid (PyObject *self, PyObject *args)
 {
-    long egid_arg;
     gid_t egid;
-    if (!PyArg_ParseTuple(args, "l", &egid_arg))
-        return NULL;
-    egid = egid_arg;
-    if (egid != egid_arg) {
-        PyErr_SetString(PyExc_OverflowError, "group id too big");
-        return NULL;
-    }
+    if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
+        return NULL;
     if (setegid(egid) < 0) {
         return posix_error();
     } else {
@@ -4819,23 +4955,11 @@
 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");
-        return NULL;
-    }
+    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 {
@@ -4853,23 +4977,11 @@
 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))
-        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 (!PyArg_ParseTuple(args, "O&O&:setregid",
+                          _Py_Gid_Converter, &rgid,
+                          _Py_Gid_Converter, &egid))
+        return NULL;
     if (setregid(rgid, egid) < 0) {
         return posix_error();
     } else {
@@ -4887,15 +4999,9 @@
 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");
-        return NULL;
-    }
+    if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
+        return NULL;
     if (setgid(gid) < 0)
         return posix_error();
     Py_INCREF(Py_None);
@@ -4934,18 +5040,7 @@
             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 the value to see if it fitted in gid_t */
-            if (grouplist[i] != x) {
-                PyErr_SetString(PyExc_TypeError,
-                                "group id too big");
+            if (!_Py_Gid_Converter(elem, &grouplist[i])) {
                 Py_DECREF(elem);
                 return NULL;
             }
@@ -7694,9 +7789,11 @@
 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();
@@ -7712,9 +7809,11 @@
 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();
@@ -7731,14 +7830,11 @@
 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)", _PyLong_FromUid(ruid),
+                                  _PyLong_FromUid(euid),
+                                  _PyLong_FromUid(suid));
 }
 #endif
 
@@ -7751,14 +7847,11 @@
 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)", _PyLong_FromGid(rgid),
+                                  _PyLong_FromGid(egid),
+                                  _PyLong_FromGid(sgid));
 }
 #endif
 
diff --git a/Modules/posixmodule.h b/Modules/posixmodule.h
new file mode 100644
--- /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 *) _PyLong_FromUid(uid_t);
+PyAPI_FUNC(PyObject *) _PyLong_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
--- a/Modules/pwdmodule.c
+++ b/Modules/pwdmodule.c
@@ -2,8 +2,8 @@
 /* UNIX password file access module */
 
 #include "Python.h"
+#include "posixmodule.h"
 
-#include <sys/types.h>
 #include <pwd.h>
 
 static PyStructSequence_Field struct_pwd_type_fields[] = {
@@ -74,8 +74,8 @@
 #else
     SETS(setIndex++, p->pw_passwd);
 #endif
-    SETI(setIndex++, p->pw_uid);
-    SETI(setIndex++, p->pw_gid);
+    PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid));
+    PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid));
 #ifdef __VMS
     SETS(setIndex++, "");
 #else
@@ -104,13 +104,21 @@
 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) {
+        PyObject *uid_obj = _PyLong_FromUid(uid);
+        if (uid_obj == NULL)
+            return NULL;
         PyErr_Format(PyExc_KeyError,
-                     "getpwuid(): uid not found: %d", uid);
+                     "getpwuid(): uid not found: %S", uid_obj);
+        Py_DECREF(uid_obj);
         return NULL;
     }
     return mkpwent(p);

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list