diff -r 0f827775f7b7 Modules/posixmodule.c --- a/Modules/posixmodule.c Wed Feb 13 21:17:13 2013 -0500 +++ b/Modules/posixmodule.c Thu Feb 14 11:01:49 2013 +0200 @@ -391,7 +391,17 @@ { if (uid == (uid_t)-1) return PyLong_FromLong(-1); +#if !defined(SIZEOF_UID_T) || SIZEOF_UID_T <= SIZEOF_LONG + if ((uid_t)-1 <= (uid_t)0) + return PyLong_FromLong(uid); return PyLong_FromUnsignedLong(uid); +#elif defined(SIZEOF_LONG_LONG) && SIZEOF_UID_T <= SIZEOF_LONG_LONG + if ((uid_t)-1 <= (uid_t)0) + return PyLong_FromLongLong(uid); + return PyLong_FromUnsignedLong(uid); +#else +# error "sizeof(uid_t) is too large" +#endif } PyObject * @@ -399,20 +409,53 @@ { if (gid == (gid_t)-1) return PyLong_FromLong(-1); +#if !defined(SIZEOF_GID_T) || SIZEOF_GID_T <= SIZEOF_LONG + if ((gid_t)-1 <= (gid_t)0) + return PyLong_FromLong(gid); return PyLong_FromUnsignedLong(gid); +#elif defined(SIZEOF_LONG_LONG) && SIZEOF_GID_T <= SIZEOF_LONG_LONG + if ((gid_t)-1 <= (gid_t)0) + return PyLong_FromLongLong(gid); + return PyLong_FromUnsignedLong(gid); +#else +# error "sizeof(gid_t) is too large" +#endif } int _Py_Uid_Converter(PyObject *obj, void *p) { +#ifndef SIZEOF_UID_T +# define USE_LONG_LONG 0 +# define CHECK_INT_OVERFLOW (SIZEOF_INT < SIZEOF_LONG) +#elif SIZEOF_UID_T == SIZEOF_LONG +# define USE_LONG_LONG 0 +# define CHECK_INT_OVERFLOW 0 +#elif SIZEOF_UID_T == SIZEOF_INT +# define USE_LONG_LONG 0 +# define CHECK_INT_OVERFLOW 1 +#elif defined(SIZEOF_LONG_LONG) && SIZEOF_UID_T == SIZEOF_LONG_LONG +# define USE_LONG_LONG 1 +# define CHECK_INT_OVERFLOW 0 +#else +# error "sizeof(uid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)" +#endif int overflow; +#if USE_LONG_LONG + PY_LONG_LONG result; +#else long result; +#endif if (PyFloat_Check(obj)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float"); return 0; } +#if USE_LONG_LONG + result = PyLong_AsLongLongAndOverflow(obj, &overflow); +#else result = PyLong_AsLongAndOverflow(obj, &overflow); +#endif if (overflow < 0) goto OverflowDown; if (!overflow && result == -1) { @@ -421,11 +464,31 @@ return 0; *(uid_t *)p = (uid_t)-1; } + else if ((uid_t)-1 <= (uid_t)0) { + /* signed uid_t */ + if (overflow > 0) + goto OverflowUp; +#if CHECK_INT_OVERFLOW + if (result < INT_MIN) + goto OverflowDown; + if (result > INT_MAX) + goto OverflowUp; +#endif + *(uid_t *)p = (uid_t)result; + } else { /* unsigned uid_t */ +#if USE_LONG_LONG + unsigned PY_LONG_LONG uresult; +#else unsigned long uresult; +#endif if (overflow > 0) { +#if USE_LONG_LONG + uresult = PyLong_AsUnsignedLongLong(obj); +#else uresult = PyLong_AsUnsignedLong(obj); +#endif if (PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) goto OverflowUp; @@ -437,10 +500,11 @@ if (result < 0) goto OverflowDown; uresult = result; - } - if (sizeof(uid_t) < sizeof(long) && - (unsigned long)(uid_t)uresult != uresult) - goto OverflowUp; +#if CHECK_INT_OVERFLOW + if (uresult > UINT_MAX) + goto OverflowUp; +#endif + } *(uid_t *)p = (uid_t)uresult; } return 1; @@ -454,19 +518,44 @@ PyErr_SetString(PyExc_OverflowError, "user id is greater than maximum"); return 0; +#undef USE_LONG_LONG +#undef CHECK_INT_OVERFLOW } int _Py_Gid_Converter(PyObject *obj, void *p) { +#ifndef SIZEOF_GID_T +# define USE_LONG_LONG 0 +# define CHECK_INT_OVERFLOW (SIZEOF_INT < SIZEOF_LONG) +#elif SIZEOF_GID_T == SIZEOF_LONG +# define USE_LONG_LONG 0 +# define CHECK_INT_OVERFLOW 0 +#elif SIZEOF_GID_T == SIZEOF_INT +# define USE_LONG_LONG 0 +# define CHECK_INT_OVERFLOW 1 +#elif defined(SIZEOF_LONG_LONG) && SIZEOF_GID_T == SIZEOF_LONG_LONG +# define USE_LONG_LONG 1 +# define CHECK_INT_OVERFLOW 0 +#else +# error "sizeof(gid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)" +#endif int overflow; +#if USE_LONG_LONG + PY_LONG_LONG result; +#else long result; +#endif if (PyFloat_Check(obj)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float"); return 0; } +#if USE_LONG_LONG + result = PyLong_AsLongLongAndOverflow(obj, &overflow); +#else result = PyLong_AsLongAndOverflow(obj, &overflow); +#endif if (overflow < 0) goto OverflowDown; if (!overflow && result == -1) { @@ -475,11 +564,31 @@ return 0; *(gid_t *)p = (gid_t)-1; } + else if ((gid_t)-1 <= (gid_t)0) { + /* signed gid_t */ + if (overflow > 0) + goto OverflowUp; +#if CHECK_INT_OVERFLOW + if (result < INT_MIN) + goto OverflowDown; + if (result > INT_MAX) + goto OverflowUp; +#endif + *(gid_t *)p = (gid_t)result; + } else { /* unsigned gid_t */ +#if USE_LONG_LONG + unsigned PY_LONG_LONG uresult; +#else unsigned long uresult; +#endif if (overflow > 0) { +#if USE_LONG_LONG + uresult = PyLong_AsUnsignedLongLong(obj); +#else uresult = PyLong_AsUnsignedLong(obj); +#endif if (PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) goto OverflowUp; @@ -491,10 +600,11 @@ if (result < 0) goto OverflowDown; uresult = result; - } - if (sizeof(gid_t) < sizeof(long) && - (unsigned long)(gid_t)uresult != uresult) - goto OverflowUp; +#if CHECK_INT_OVERFLOW + if (uresult > UINT_MAX) + goto OverflowUp; +#endif + } *(gid_t *)p = (gid_t)uresult; } return 1; @@ -508,6 +618,8 @@ PyErr_SetString(PyExc_OverflowError, "group id is greater than maximum"); return 0; +#undef USE_LONG_LONG +#undef CHECK_INT_OVERFLOW } #endif /* MS_WINDOWS */ diff -r 0f827775f7b7 configure.ac --- a/configure.ac Wed Feb 13 21:17:13 2013 -0500 +++ b/configure.ac Thu Feb 14 11:01:49 2013 +0200 @@ -1687,6 +1687,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 diff -r 0f827775f7b7 pyconfig.h.in --- a/pyconfig.h.in Wed Feb 13 21:17:13 2013 -0500 +++ b/pyconfig.h.in Thu Feb 14 11:01:49 2013 +0200 @@ -1223,6 +1223,12 @@ /* The size of `pid_t', as computed by sizeof. */ #undef SIZEOF_PID_T +/* The size of `uid_t', as computed by sizeof. */ +#undef SIZEOF_UID_T + +/* The size of `gid_t', as computed by sizeof. */ +#undef SIZEOF_GID_T + /* The size of `pthread_t', as computed by sizeof. */ #undef SIZEOF_PTHREAD_T