diff --git a/Include/longobject.h b/Include/longobject.h index d741f1b..9e154d1 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -49,6 +49,40 @@ PyAPI_FUNC(PyObject *) PyLong_GetInfo(void); #error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)" #endif /* SIZEOF_PID_T */ +/* Issue #2005: uid_t can be longer than a C long on some systems */ +#if !defined(SIZEOF_UID_T) || SIZEOF_UID_T == SIZEOF_INT +#define _Py_PARSE_UID "i" +#define PyLong_FromUid PyLong_FromLong +#define PyLong_AsUid PyLong_AsLong +#elif SIZEOF_UID_T == SIZEOF_LONG +#define _Py_PARSE_UID "l" +#define PyLong_FromUid PyLong_FromLong +#define PyLong_AsUid PyLong_AsLong +#elif defined(SIZEOF_LONG_LONG) && SIZEOF_UID_T == SIZEOF_LONG_LONG +#define _Py_PARSE_UID "L" +#define PyLong_FromUid PyLong_FromLongLong +#define PyLong_AsUid PyLong_AsLongLong +#else +#error "sizeof(uid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)" +#endif /* SIZEOF_UID_T */ + +/* Issue #2005: gid_t can be longer than a C long on some systems */ +#if !defined(SIZEOF_GID_T) || SIZEOF_GID_T == SIZEOF_INT +#define _Py_PARSE_GID "i" +#define PyLong_FromGid PyLong_FromLong +#define PyLong_AsGid PyLong_AsLong +#elif SIZEOF_GID_T == SIZEOF_LONG +#define _Py_PARSE_GID "l" +#define PyLong_FromGid PyLong_FromLong +#define PyLong_AsGid PyLong_AsLong +#elif defined(SIZEOF_LONG_LONG) && SIZEOF_GID_T == SIZEOF_LONG_LONG +#define _Py_PARSE_GID "L" +#define PyLong_FromGid PyLong_FromLongLong +#define PyLong_AsGid PyLong_AsLongLong +#else +#error "sizeof(gid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)" +#endif /* SIZEOF_GID_T */ + /* Used by Python/mystrtoul.c. */ #ifndef Py_LIMITED_API PyAPI_DATA(unsigned char) _PyLong_DigitValue[256]; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 0fe3963..626ba7b 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2035,8 +2035,8 @@ _pystat_fromstructstat(STRUCT_STAT *st) 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)); + PyStructSequence_SET_ITEM(v, 4, PyLong_FromUid((long)st->st_uid)); + PyStructSequence_SET_ITEM(v, 5, PyLong_FromGid((long)st->st_gid)); #ifdef HAVE_LARGEFILE_SUPPORT PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong((PY_LONG_LONG)st->st_size)); @@ -2839,7 +2839,6 @@ static PyObject * posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) { path_t path; - long uid_l, gid_l; uid_t uid; gid_t gid; int dir_fd = DEFAULT_DIR_FD; @@ -2853,9 +2852,11 @@ posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) #ifdef HAVE_FCHOWN path.allow_fd = 1; #endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords, - path_converter, &path, - &uid_l, &gid_l, + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&" _Py_PARSE_UID _Py_PARSE_GID + "|$O&p:chown", + keywords, path_converter, &path, + &uid, &gid, #ifdef HAVE_FCHOWNAT dir_fd_converter, &dir_fd, #else @@ -2886,8 +2887,6 @@ posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) #endif Py_BEGIN_ALLOW_THREADS - uid = (uid_t)uid_l; - gid = (uid_t)gid_l; #ifdef HAVE_FCHOWN if (path.fd != -1) result = fchown(path.fd, uid, gid); @@ -2931,12 +2930,14 @@ 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:fchown", &fd, &uid, &gid)) + if (!PyArg_ParseTuple(args, "i" _Py_PARSE_UID _Py_PARSE_GID ":fchown", + &fd, &uid, &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(); @@ -2956,15 +2957,16 @@ posix_lchown(PyObject *self, PyObject *args) { 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&" _Py_PARSE_UID _Py_PARSE_GID ":lchown", PyUnicode_FSConverter, &opath, &uid, &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); @@ -5624,7 +5626,7 @@ Return the current process's effective group id."); static PyObject * posix_getegid(PyObject *self, PyObject *noargs) { - return PyLong_FromLong((long)getegid()); + return PyLong_FromGid(getegid()); } #endif @@ -5637,7 +5639,7 @@ Return the current process's effective user id."); static PyObject * posix_geteuid(PyObject *self, PyObject *noargs) { - return PyLong_FromLong((long)geteuid()); + return PyLong_FromUid(geteuid()); } #endif @@ -5650,7 +5652,7 @@ Return the current process's group id."); static PyObject * posix_getgid(PyObject *self, PyObject *noargs) { - return PyLong_FromLong((long)getgid()); + return PyLong_FromGid(getgid()); } #endif @@ -5820,14 +5822,14 @@ posix_initgroups(PyObject *self, PyObject *args) PyObject *oname; char *username; int res; - long gid; + gid_t gid; - if (!PyArg_ParseTuple(args, "O&l:initgroups", + if (!PyArg_ParseTuple(args, "O&" _Py_PARSE_GID ":initgroups", PyUnicode_FSConverter, &oname, &gid)) 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); @@ -6002,7 +6004,7 @@ Return the current process's user id."); static PyObject * posix_getuid(PyObject *self, PyObject *noargs) { - return PyLong_FromLong((long)getuid()); + return PyLong_FromUid(getuid()); } #endif @@ -6127,15 +6129,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, _Py_PARSE_UID ":setuid", &uid)) return NULL; - } if (setuid(uid) < 0) return posix_error(); Py_INCREF(Py_None); @@ -6152,15 +6148,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)) - return NULL; - euid = euid_arg; - if (euid != euid_arg) { - PyErr_SetString(PyExc_OverflowError, "user id too big"); + if (!PyArg_ParseTuple(args, _Py_PARSE_UID, &euid)) return NULL; - } if (seteuid(euid) < 0) { return posix_error(); } else { @@ -6178,15 +6168,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)) - return NULL; - egid = egid_arg; - if (egid != egid_arg) { - PyErr_SetString(PyExc_OverflowError, "group id too big"); + if (!PyArg_ParseTuple(args, _Py_PARSE_GID, &egid)) return NULL; - } if (setegid(egid) < 0) { return posix_error(); } else { @@ -6204,23 +6188,9 @@ 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, _Py_PARSE_UID _Py_PARSE_UID, &ruid, &euid)) return NULL; - } if (setreuid(ruid, euid) < 0) { return posix_error(); } else { @@ -6238,23 +6208,9 @@ 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)) - 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"); + if (!PyArg_ParseTuple(args, _Py_PARSE_GID _Py_PARSE_GID, &rgid, &egid)) return NULL; - } if (setregid(rgid, egid) < 0) { return posix_error(); } else { @@ -6272,15 +6228,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)) + if (!PyArg_ParseTuple(args, _Py_PARSE_GID ":setgid", &gid)) return NULL; - gid = gid_arg; - if (gid != gid_arg) { - PyErr_SetString(PyExc_OverflowError, "group id too big"); - return NULL; - } if (setgid(gid) < 0) return posix_error(); Py_INCREF(Py_None); @@ -6319,21 +6269,14 @@ posix_setgroups(PyObject *self, PyObject *groups) Py_DECREF(elem); return NULL; } else { - unsigned long x = PyLong_AsUnsignedLong(elem); + gid_t gid = PyLong_AsGid(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"); - Py_DECREF(elem); - return NULL; - } + grouplist[i] = gid; } Py_DECREF(elem); } @@ -6492,7 +6435,7 @@ posix_waitid(PyObject *self, PyObject *args) return NULL; PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid)); - PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid)); + PyStructSequence_SET_ITEM(result, 1, PyLong_FromUid(si.si_uid)); PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo))); PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status))); PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code))); @@ -7007,8 +6950,9 @@ static PyObject * posix_setpgid(PyObject *self, PyObject *args) { pid_t pid; - int pgrp; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp)) + pid_t pgrp; + if (!PyArg_ParseTuple(args, _Py_PARSE_PID _Py_PARSE_PID ":setpgid", + &pid, &pgrp)) return NULL; if (setpgid(pid, pgrp) < 0) return posix_error(); @@ -9740,9 +9684,9 @@ 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, _Py_PARSE_UID _Py_PARSE_UID _Py_PARSE_UID, + &ruid, &euid, &suid)) return NULL; if (setresuid(ruid, euid, suid) < 0) return posix_error(); @@ -9759,8 +9703,9 @@ 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, _Py_PARSE_GID _Py_PARSE_GID _Py_PARSE_GID, + &rgid, &egid, &sgid)) return NULL; if (setresgid(rgid, egid, sgid) < 0) return posix_error(); @@ -9777,14 +9722,10 @@ 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)", PyLong_FromUid(ruid), PyLong_FromUid(euid), + PyLong_FromUid(suid)); } #endif @@ -9797,14 +9738,10 @@ 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)", PyLong_FromGid(rgid), PyLong_FromGid(egid), + PyLong_FromGid(sgid)); } #endif diff --git a/configure.ac b/configure.ac index 94d5b80..5d699a0 100644 --- a/configure.ac +++ b/configure.ac @@ -1654,6 +1654,8 @@ AC_CHECK_SIZEOF(double, 8) AC_CHECK_SIZEOF(fpos_t, 4) AC_CHECK_SIZEOF(size_t, 4) AC_CHECK_SIZEOF(pid_t, 4) +AC_CHECK_SIZEOF(uid_t, 4) +AC_CHECK_SIZEOF(gid_t, 4) AC_MSG_CHECKING(for long long support) have_long_long=no