Issue #4591: Uid and gid values larger than 2**31 are supported now.

This commit is contained in:
Serhiy Storchaka 2013-02-10 21:56:49 +02:00
parent ac99576a8e
commit 7cf5599346
8 changed files with 283 additions and 130 deletions

View File

@ -404,10 +404,20 @@ class PosixTester(unittest.TestCase):
else: else:
self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode)) 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.""" """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 # test a successful chown call
chown_func(first_param, os.getuid(), os.getgid()) 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: if os.getuid() == 0:
try: try:
@ -427,8 +437,12 @@ class PosixTester(unittest.TestCase):
"behavior") "behavior")
else: else:
# non-root cannot chown to root, raises OSError # non-root cannot chown to root, raises OSError
self.assertRaises(OSError, chown_func, self.assertRaises(OSError, chown_func, first_param, 0, 0)
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()") @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
def test_chown(self): def test_chown(self):
@ -438,7 +452,8 @@ class PosixTester(unittest.TestCase):
# re-create the file # re-create the file
support.create_empty_file(support.TESTFN) support.create_empty_file(support.TESTFN)
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()") @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
def test_fchown(self): def test_fchown(self):
@ -448,7 +463,8 @@ class PosixTester(unittest.TestCase):
test_file = open(support.TESTFN, 'w') test_file = open(support.TESTFN, 'w')
try: try:
fd = test_file.fileno() 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: finally:
test_file.close() test_file.close()
@ -457,7 +473,8 @@ class PosixTester(unittest.TestCase):
os.unlink(support.TESTFN) os.unlink(support.TESTFN)
# create a symlink # create a symlink
os.symlink(_DUMMY_SYMLINK, support.TESTFN) 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): def test_chdir(self):
if hasattr(posix, 'chdir'): if hasattr(posix, 'chdir'):

View File

@ -639,6 +639,14 @@ Modules/python.o: $(srcdir)/Modules/python.c
Modules/_testembed.o: $(srcdir)/Modules/_testembed.c Modules/_testembed.o: $(srcdir)/Modules/_testembed.c
$(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Modules/_testembed.c $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Modules/_testembed.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
Modules/signalmodule.o: $(srcdir)/Modules/signalmodule.c $(srcdir)/Modules/posixmodule.h
Python/dynload_shlib.o: $(srcdir)/Python/dynload_shlib.c Makefile Python/dynload_shlib.o: $(srcdir)/Python/dynload_shlib.c Makefile
$(CC) -c $(PY_CORE_CFLAGS) \ $(CC) -c $(PY_CORE_CFLAGS) \
-DSOABI='"$(SOABI)"' \ -DSOABI='"$(SOABI)"' \

View File

@ -175,6 +175,8 @@ Core and Builtins
Library Library
------- -------
- Issue #4591: Uid and gid values larger than 2**31 are supported now.
- Issue #17141: random.vonmisesvariate() no more hangs for large kappas. - Issue #17141: random.vonmisesvariate() no more hangs for large kappas.
- Issue #17149: Fix random.vonmisesvariate to always return results in - Issue #17149: Fix random.vonmisesvariate to always return results in

View File

@ -2,8 +2,8 @@
/* UNIX group file access module */ /* UNIX group file access module */
#include "Python.h" #include "Python.h"
#include "posixmodule.h"
#include <sys/types.h>
#include <grp.h> #include <grp.h>
static PyStructSequence_Field struct_group_type_fields[] = { static PyStructSequence_Field struct_group_type_fields[] = {
@ -69,7 +69,7 @@ mkgrent(struct group *p)
Py_INCREF(Py_None); Py_INCREF(Py_None);
} }
#endif #endif
SET(setIndex++, PyLong_FromLong((long) p->gr_gid)); SET(setIndex++, _PyLong_FromGid(p->gr_gid));
SET(setIndex++, w); SET(setIndex++, w);
#undef SET #undef SET
@ -85,17 +85,24 @@ static PyObject *
grp_getgrgid(PyObject *self, PyObject *pyo_id) grp_getgrgid(PyObject *self, PyObject *pyo_id)
{ {
PyObject *py_int_id; PyObject *py_int_id;
unsigned int gid; gid_t gid;
struct group *p; struct group *p;
py_int_id = PyNumber_Long(pyo_id); py_int_id = PyNumber_Long(pyo_id);
if (!py_int_id) if (!py_int_id)
return NULL; 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); Py_DECREF(py_int_id);
if ((p = getgrgid(gid)) == NULL) { 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 NULL;
} }
return mkgrent(p); return mkgrent(p);

View File

@ -26,6 +26,9 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include "Python.h" #include "Python.h"
#ifndef MS_WINDOWS
#include "posixmodule.h"
#endif
#if defined(__VMS) #if defined(__VMS)
# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4" # error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
@ -413,6 +416,121 @@ win32_warn_bytes_api()
#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 = 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 = 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 */
#ifdef AT_FDCWD #ifdef AT_FDCWD
/* /*
* Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965); * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
@ -2166,8 +2284,13 @@ _pystat_fromstructstat(STRUCT_STAT *st)
PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev)); PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
#endif #endif
PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink)); PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid)); #if defined(MS_WINDOWS)
PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid)); 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 #ifdef HAVE_LARGEFILE_SUPPORT
PyStructSequence_SET_ITEM(v, 6, PyStructSequence_SET_ITEM(v, 6,
PyLong_FromLongLong((PY_LONG_LONG)st->st_size)); PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
@ -2972,7 +3095,6 @@ static PyObject *
posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
{ {
path_t path; path_t path;
long uid_l, gid_l;
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
int dir_fd = DEFAULT_DIR_FD; int dir_fd = DEFAULT_DIR_FD;
@ -2986,9 +3108,10 @@ posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
#ifdef HAVE_FCHOWN #ifdef HAVE_FCHOWN
path.allow_fd = 1; path.allow_fd = 1;
#endif #endif
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
path_converter, &path, path_converter, &path,
&uid_l, &gid_l, _Py_Uid_Converter, &uid,
_Py_Gid_Converter, &gid,
#ifdef HAVE_FCHOWNAT #ifdef HAVE_FCHOWNAT
dir_fd_converter, &dir_fd, dir_fd_converter, &dir_fd,
#else #else
@ -3019,8 +3142,6 @@ posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
#endif #endif
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
uid = (uid_t)uid_l;
gid = (uid_t)gid_l;
#ifdef HAVE_FCHOWN #ifdef HAVE_FCHOWN
if (path.fd != -1) if (path.fd != -1)
result = fchown(path.fd, uid, gid); result = fchown(path.fd, uid, gid);
@ -3064,12 +3185,15 @@ static PyObject *
posix_fchown(PyObject *self, PyObject *args) posix_fchown(PyObject *self, PyObject *args)
{ {
int fd; int fd;
long uid, gid; uid_t uid;
gid_t gid;
int res; 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; return NULL;
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
res = fchown(fd, (uid_t) uid, (gid_t) gid); res = fchown(fd, uid, gid);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (res < 0) if (res < 0)
return posix_error(); return posix_error();
@ -3089,15 +3213,17 @@ posix_lchown(PyObject *self, PyObject *args)
{ {
PyObject *opath; PyObject *opath;
char *path; char *path;
long uid, gid; uid_t uid;
gid_t gid;
int res; int res;
if (!PyArg_ParseTuple(args, "O&ll:lchown", if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
PyUnicode_FSConverter, &opath, PyUnicode_FSConverter, &opath,
&uid, &gid)) _Py_Uid_Converter, &uid,
_Py_Gid_Converter, &gid))
return NULL; return NULL;
path = PyBytes_AsString(opath); path = PyBytes_AsString(opath);
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
res = lchown(path, (uid_t) uid, (gid_t) gid); res = lchown(path, uid, gid);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (res < 0) if (res < 0)
return posix_error_with_allocated_filename(opath); return posix_error_with_allocated_filename(opath);
@ -6030,7 +6156,7 @@ Return the current process's effective group id.");
static PyObject * static PyObject *
posix_getegid(PyObject *self, PyObject *noargs) posix_getegid(PyObject *self, PyObject *noargs)
{ {
return PyLong_FromLong((long)getegid()); return _PyLong_FromGid(getegid());
} }
#endif #endif
@ -6043,7 +6169,7 @@ Return the current process's effective user id.");
static PyObject * static PyObject *
posix_geteuid(PyObject *self, PyObject *noargs) posix_geteuid(PyObject *self, PyObject *noargs)
{ {
return PyLong_FromLong((long)geteuid()); return _PyLong_FromUid(geteuid());
} }
#endif #endif
@ -6056,7 +6182,7 @@ Return the current process's group id.");
static PyObject * static PyObject *
posix_getgid(PyObject *self, PyObject *noargs) posix_getgid(PyObject *self, PyObject *noargs)
{ {
return PyLong_FromLong((long)getgid()); return _PyLong_FromGid(getgid());
} }
#endif #endif
@ -6098,8 +6224,14 @@ posix_getgrouplist(PyObject *self, PyObject *args)
#endif #endif
ngroups = MAX_GROUPS; ngroups = MAX_GROUPS;
if (!PyArg_ParseTuple(args, "si", &user, &basegid)) #ifdef __APPLE__
if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
return NULL; return NULL;
#else
if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
_Py_Gid_Converter, &basegid))
return NULL;
#endif
#ifdef __APPLE__ #ifdef __APPLE__
groups = PyMem_Malloc(ngroups * sizeof(int)); groups = PyMem_Malloc(ngroups * sizeof(int));
@ -6121,7 +6253,11 @@ posix_getgrouplist(PyObject *self, PyObject *args)
} }
for (i = 0; i < ngroups; i++) { for (i = 0; i < ngroups; i++) {
#ifdef __APPLE__
PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]); PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
#else
PyObject *o = _PyLong_FromGid(groups[i]);
#endif
if (o == NULL) { if (o == NULL) {
Py_DECREF(list); Py_DECREF(list);
PyMem_Del(groups); PyMem_Del(groups);
@ -6195,7 +6331,7 @@ posix_getgroups(PyObject *self, PyObject *noargs)
if (result != NULL) { if (result != NULL) {
int i; int i;
for (i = 0; i < n; ++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) { if (o == NULL) {
Py_DECREF(result); Py_DECREF(result);
result = NULL; result = NULL;
@ -6226,14 +6362,25 @@ posix_initgroups(PyObject *self, PyObject *args)
PyObject *oname; PyObject *oname;
char *username; char *username;
int res; int res;
long gid; #ifdef __APPLE__
int gid;
#else
gid_t gid;
#endif
if (!PyArg_ParseTuple(args, "O&l:initgroups", #ifdef __APPLE__
PyUnicode_FSConverter, &oname, &gid)) 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; return NULL;
username = PyBytes_AS_STRING(oname); username = PyBytes_AS_STRING(oname);
res = initgroups(username, (gid_t) gid); res = initgroups(username, gid);
Py_DECREF(oname); Py_DECREF(oname);
if (res == -1) if (res == -1)
return PyErr_SetFromErrno(PyExc_OSError); return PyErr_SetFromErrno(PyExc_OSError);
@ -6408,7 +6555,7 @@ Return the current process's user id.");
static PyObject * static PyObject *
posix_getuid(PyObject *self, PyObject *noargs) posix_getuid(PyObject *self, PyObject *noargs)
{ {
return PyLong_FromLong((long)getuid()); return _PyLong_FromUid(getuid());
} }
#endif #endif
@ -6548,15 +6695,9 @@ Set the current process's user id.");
static PyObject * static PyObject *
posix_setuid(PyObject *self, PyObject *args) posix_setuid(PyObject *self, PyObject *args)
{ {
long uid_arg;
uid_t uid; uid_t uid;
if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg)) if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
return NULL; return NULL;
uid = uid_arg;
if (uid != uid_arg) {
PyErr_SetString(PyExc_OverflowError, "user id too big");
return NULL;
}
if (setuid(uid) < 0) if (setuid(uid) < 0)
return posix_error(); return posix_error();
Py_INCREF(Py_None); Py_INCREF(Py_None);
@ -6573,15 +6714,9 @@ Set the current process's effective user id.");
static PyObject * static PyObject *
posix_seteuid (PyObject *self, PyObject *args) posix_seteuid (PyObject *self, PyObject *args)
{ {
long euid_arg;
uid_t euid; uid_t euid;
if (!PyArg_ParseTuple(args, "l", &euid_arg)) if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
return NULL; return NULL;
euid = euid_arg;
if (euid != euid_arg) {
PyErr_SetString(PyExc_OverflowError, "user id too big");
return NULL;
}
if (seteuid(euid) < 0) { if (seteuid(euid) < 0) {
return posix_error(); return posix_error();
} else { } else {
@ -6599,15 +6734,9 @@ Set the current process's effective group id.");
static PyObject * static PyObject *
posix_setegid (PyObject *self, PyObject *args) posix_setegid (PyObject *self, PyObject *args)
{ {
long egid_arg;
gid_t egid; gid_t egid;
if (!PyArg_ParseTuple(args, "l", &egid_arg)) if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
return NULL; return NULL;
egid = egid_arg;
if (egid != egid_arg) {
PyErr_SetString(PyExc_OverflowError, "group id too big");
return NULL;
}
if (setegid(egid) < 0) { if (setegid(egid) < 0) {
return posix_error(); return posix_error();
} else { } else {
@ -6625,23 +6754,11 @@ Set the current process's real and effective user ids.");
static PyObject * static PyObject *
posix_setreuid (PyObject *self, PyObject *args) posix_setreuid (PyObject *self, PyObject *args)
{ {
long ruid_arg, euid_arg;
uid_t ruid, euid; uid_t ruid, euid;
if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg)) if (!PyArg_ParseTuple(args, "O&O&:setreuid",
_Py_Uid_Converter, &ruid,
_Py_Uid_Converter, &euid))
return NULL; 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 (setreuid(ruid, euid) < 0) { if (setreuid(ruid, euid) < 0) {
return posix_error(); return posix_error();
} else { } else {
@ -6659,23 +6776,11 @@ Set the current process's real and effective group ids.");
static PyObject * static PyObject *
posix_setregid (PyObject *self, PyObject *args) posix_setregid (PyObject *self, PyObject *args)
{ {
long rgid_arg, egid_arg;
gid_t rgid, egid; 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; 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) { if (setregid(rgid, egid) < 0) {
return posix_error(); return posix_error();
} else { } else {
@ -6693,15 +6798,9 @@ Set the current process's group id.");
static PyObject * static PyObject *
posix_setgid(PyObject *self, PyObject *args) posix_setgid(PyObject *self, PyObject *args)
{ {
long gid_arg;
gid_t gid; gid_t gid;
if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg)) if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
return NULL; return NULL;
gid = gid_arg;
if (gid != gid_arg) {
PyErr_SetString(PyExc_OverflowError, "group id too big");
return NULL;
}
if (setgid(gid) < 0) if (setgid(gid) < 0)
return posix_error(); return posix_error();
Py_INCREF(Py_None); Py_INCREF(Py_None);
@ -6740,18 +6839,7 @@ posix_setgroups(PyObject *self, PyObject *groups)
Py_DECREF(elem); Py_DECREF(elem);
return NULL; return NULL;
} else { } else {
unsigned long x = PyLong_AsUnsignedLong(elem); if (!_Py_Gid_Converter(elem, &grouplist[i])) {
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); Py_DECREF(elem);
return NULL; return NULL;
} }
@ -6913,7 +7001,7 @@ posix_waitid(PyObject *self, PyObject *args)
return NULL; return NULL;
PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid)); 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, 2, PyLong_FromLong((long)(si.si_signo)));
PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status))); PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code))); PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
@ -10197,8 +10285,11 @@ static PyObject*
posix_setresuid (PyObject *self, PyObject *args) posix_setresuid (PyObject *self, PyObject *args)
{ {
/* We assume uid_t is no larger than a long. */ /* We assume uid_t is no larger than a long. */
long ruid, euid, suid; uid_t ruid, euid, suid;
if (!PyArg_ParseTuple(args, "lll", &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; return NULL;
if (setresuid(ruid, euid, suid) < 0) if (setresuid(ruid, euid, suid) < 0)
return posix_error(); return posix_error();
@ -10214,9 +10305,11 @@ Set the current process's real, effective, and saved group ids.");
static PyObject* static PyObject*
posix_setresgid (PyObject *self, PyObject *args) posix_setresgid (PyObject *self, PyObject *args)
{ {
/* We assume uid_t is no larger than a long. */ gid_t rgid, egid, sgid;
long rgid, egid, sgid; if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid)) _Py_Gid_Converter, &rgid,
_Py_Gid_Converter, &egid,
_Py_Gid_Converter, &sgid))
return NULL; return NULL;
if (setresgid(rgid, egid, sgid) < 0) if (setresgid(rgid, egid, sgid) < 0)
return posix_error(); return posix_error();
@ -10233,14 +10326,11 @@ static PyObject*
posix_getresuid (PyObject *self, PyObject *noargs) posix_getresuid (PyObject *self, PyObject *noargs)
{ {
uid_t ruid, euid, suid; uid_t ruid, euid, suid;
long l_ruid, l_euid, l_suid;
if (getresuid(&ruid, &euid, &suid) < 0) if (getresuid(&ruid, &euid, &suid) < 0)
return posix_error(); return posix_error();
/* Force the values into long's as we don't know the size of uid_t. */ return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
l_ruid = ruid; _PyLong_FromUid(euid),
l_euid = euid; _PyLong_FromUid(suid));
l_suid = suid;
return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
} }
#endif #endif
@ -10253,14 +10343,11 @@ static PyObject*
posix_getresgid (PyObject *self, PyObject *noargs) posix_getresgid (PyObject *self, PyObject *noargs)
{ {
uid_t rgid, egid, sgid; uid_t rgid, egid, sgid;
long l_rgid, l_egid, l_sgid;
if (getresgid(&rgid, &egid, &sgid) < 0) if (getresgid(&rgid, &egid, &sgid) < 0)
return posix_error(); return posix_error();
/* Force the values into long's as we don't know the size of uid_t. */ return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
l_rgid = rgid; _PyLong_FromGid(egid),
l_egid = egid; _PyLong_FromGid(sgid));
l_sgid = sgid;
return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
} }
#endif #endif

25
Modules/posixmodule.h Normal file
View File

@ -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 */

View File

@ -2,8 +2,8 @@
/* UNIX password file access module */ /* UNIX password file access module */
#include "Python.h" #include "Python.h"
#include "posixmodule.h"
#include <sys/types.h>
#include <pwd.h> #include <pwd.h>
static PyStructSequence_Field struct_pwd_type_fields[] = { static PyStructSequence_Field struct_pwd_type_fields[] = {
@ -74,8 +74,8 @@ mkpwent(struct passwd *p)
#else #else
SETS(setIndex++, p->pw_passwd); SETS(setIndex++, p->pw_passwd);
#endif #endif
SETI(setIndex++, p->pw_uid); PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid));
SETI(setIndex++, p->pw_gid); PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid));
#ifdef __VMS #ifdef __VMS
SETS(setIndex++, ""); SETS(setIndex++, "");
#else #else
@ -104,13 +104,17 @@ See help(pwd) for more on password database entries.");
static PyObject * static PyObject *
pwd_getpwuid(PyObject *self, PyObject *args) pwd_getpwuid(PyObject *self, PyObject *args)
{ {
unsigned int uid; uid_t uid;
struct passwd *p; struct passwd *p;
if (!PyArg_ParseTuple(args, "I:getpwuid", &uid)) if (!PyArg_ParseTuple(args, "O&:getpwuid", _Py_Uid_Converter, &uid))
return NULL; return NULL;
if ((p = getpwuid(uid)) == NULL) { if ((p = getpwuid(uid)) == NULL) {
PyObject *uid_obj = _PyLong_FromUid(uid);
if (uid_obj == NULL)
return NULL;
PyErr_Format(PyExc_KeyError, PyErr_Format(PyExc_KeyError,
"getpwuid(): uid not found: %d", uid); "getpwuid(): uid not found: %S", uid_obj);
Py_DECREF(uid_obj);
return NULL; return NULL;
} }
return mkpwent(p); return mkpwent(p);

View File

@ -4,6 +4,9 @@
/* XXX Signals should be recorded per thread, now we have thread state. */ /* XXX Signals should be recorded per thread, now we have thread state. */
#include "Python.h" #include "Python.h"
#ifndef MS_WINDOWS
#include "posixmodule.h"
#endif
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
#include <Windows.h> #include <Windows.h>
@ -728,7 +731,7 @@ fill_siginfo(siginfo_t *si)
PyStructSequence_SET_ITEM(result, 1, PyLong_FromLong((long)(si->si_code))); PyStructSequence_SET_ITEM(result, 1, PyLong_FromLong((long)(si->si_code)));
PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si->si_errno))); PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si->si_errno)));
PyStructSequence_SET_ITEM(result, 3, PyLong_FromPid(si->si_pid)); PyStructSequence_SET_ITEM(result, 3, PyLong_FromPid(si->si_pid));
PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si->si_uid))); PyStructSequence_SET_ITEM(result, 4, _PyLong_FromUid(si->si_uid));
PyStructSequence_SET_ITEM(result, 5, PyStructSequence_SET_ITEM(result, 5,
PyLong_FromLong((long)(si->si_status))); PyLong_FromLong((long)(si->si_status)));
PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band)); PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band));