[pypy-commit] pypy default: Refactor the uid_t/gid_t handling in rlib.rposix and in interp_posix.py,

arigo pypy.commits at gmail.com
Wed Aug 17 17:19:45 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r86258:a59647bbf2e6
Date: 2016-08-17 23:00 +0200
http://bitbucket.org/pypy/pypy/changeset/a59647bbf2e6/

Log:	Refactor the uid_t/gid_t handling in rlib.rposix and in
	interp_posix.py, based on the clean-up of CPython 2.7.x (see comment
	in interp_posix).

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1703,6 +1703,23 @@
                 "Python int too large for C unsigned short")
         return value
 
+    def c_uid_t_w(self, w_obj):
+        # xxx assumes that uid_t and gid_t are a C unsigned int.
+        # Equivalent to space.c_uint_w(), with the exception that
+        # it also accepts -1 and converts that to UINT_MAX, which
+        # is (uid_t)-1.  And values smaller than -1 raise
+        # OverflowError, not ValueError.
+        try:
+            return self.c_uint_w(w_obj)
+        except OperationError as e:
+            if e.match(self, self.w_ValueError):
+                # ValueError: cannot convert negative integer to unsigned
+                if self.int_w(w_obj) == -1:
+                    return UINT_MAX
+                raise oefmt(self.w_OverflowError,
+                            "user/group id smaller than minimum (-1)")
+            raise
+
     def truncatedint_w(self, w_obj, allow_conversion=True):
         # Like space.gateway_int_w(), but return the integer truncated
         # instead of raising OverflowError.  For obscure cases only.
diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -167,6 +167,9 @@
     def visit_c_ushort(self, el, app_sig):
         self.checked_space_method(el, app_sig)
 
+    def visit_c_uid_t(self, el, app_sig):
+        self.checked_space_method(el, app_sig)
+
     def visit_truncatedint_w(self, el, app_sig):
         self.checked_space_method(el, app_sig)
 
@@ -294,6 +297,9 @@
     def visit_c_ushort(self, typ):
         self.run_args.append("space.c_ushort_w(%s)" % (self.scopenext(),))
 
+    def visit_c_uid_t(self, typ):
+        self.run_args.append("space.c_uid_t_w(%s)" % (self.scopenext(),))
+
     def visit_truncatedint_w(self, typ):
         self.run_args.append("space.truncatedint_w(%s)" % (self.scopenext(),))
 
@@ -440,6 +446,9 @@
     def visit_c_ushort(self, typ):
         self.unwrap.append("space.c_ushort_w(%s)" % (self.nextarg(),))
 
+    def visit_c_uid_t(self, typ):
+        self.unwrap.append("space.c_uid_t_w(%s)" % (self.nextarg(),))
+
     def visit_truncatedint_w(self, typ):
         self.unwrap.append("space.truncatedint_w(%s)" % (self.nextarg(),))
 
diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -4,7 +4,7 @@
 from rpython.rlib import rposix, rposix_stat
 from rpython.rlib import objectmodel, rurandom
 from rpython.rlib.objectmodel import specialize
-from rpython.rlib.rarithmetic import r_longlong, intmask
+from rpython.rlib.rarithmetic import r_longlong, intmask, r_uint
 from rpython.rlib.unroll import unrolling_iterable
 
 from pypy.interpreter.gateway import unwrap_spec
@@ -20,20 +20,21 @@
 
 c_int = "c_int"
 
-# CPython 2.7 semantics are too messy to follow exactly,
-# e.g. setuid(-2) works on 32-bit but not on 64-bit.  As a result,
-# we decided to just accept any 'int', i.e. any C signed long, and
-# check that they are in range(-2**31, 2**32).  In other words, we
-# accept any number that is either a signed or an unsigned C int.
-c_uid_t = int
-c_gid_t = int
-if sys.maxint == 2147483647:
-    def check_uid_range(space, num):
-        pass
-else:
-    def check_uid_range(space, num):
-        if num < -(1 << 31) or num >= (1 << 32):
-            raise oefmt(space.w_OverflowError, "integer out of range")
+# CPython 2.7 semantics used to be too messy, differing on 32-bit vs
+# 64-bit, but this was cleaned up in recent 2.7.x.  Now, any function
+# taking a uid_t or gid_t accepts numbers in range(-1, 2**32) as an
+# r_uint, with -1 being equivalent to 2**32-1.  Any function that
+# returns a uid_t or gid_t returns either an int or a long, depending
+# on whether it fits or not, but always positive.
+c_uid_t = 'c_uid_t'
+c_gid_t = 'c_uid_t'
+
+def wrap_uid(space, uid):
+    if uid <= r_uint(sys.maxint):
+        return space.wrap(intmask(uid))
+    else:
+        return space.wrap(uid)     # an unsigned number
+wrap_gid = wrap_uid
 
 def fsencode_w(space, w_obj):
     if space.isinstance_w(w_obj, space.w_unicode):
@@ -912,7 +913,7 @@
 
     Return the current process's user id.
     """
-    return space.wrap(os.getuid())
+    return wrap_uid(space, os.getuid())
 
 @unwrap_spec(arg=c_uid_t)
 def setuid(space, arg):
@@ -920,12 +921,10 @@
 
     Set the current process's user id.
     """
-    check_uid_range(space, arg)
     try:
         os.setuid(arg)
     except OSError as e:
         raise wrap_oserror(space, e)
-    return space.w_None
 
 @unwrap_spec(arg=c_uid_t)
 def seteuid(space, arg):
@@ -933,12 +932,10 @@
 
     Set the current process's effective user id.
     """
-    check_uid_range(space, arg)
     try:
         os.seteuid(arg)
     except OSError as e:
         raise wrap_oserror(space, e)
-    return space.w_None
 
 @unwrap_spec(arg=c_gid_t)
 def setgid(space, arg):
@@ -946,12 +943,10 @@
 
     Set the current process's group id.
     """
-    check_uid_range(space, arg)
     try:
         os.setgid(arg)
     except OSError as e:
         raise wrap_oserror(space, e)
-    return space.w_None
 
 @unwrap_spec(arg=c_gid_t)
 def setegid(space, arg):
@@ -959,12 +954,10 @@
 
     Set the current process's effective group id.
     """
-    check_uid_range(space, arg)
     try:
         os.setegid(arg)
     except OSError as e:
         raise wrap_oserror(space, e)
-    return space.w_None
 
 @unwrap_spec(path='str0')
 def chroot(space, path):
@@ -983,21 +976,21 @@
 
     Return the current process's group id.
     """
-    return space.wrap(os.getgid())
+    return wrap_gid(space, os.getgid())
 
 def getegid(space):
     """ getegid() -> gid
 
     Return the current process's effective group id.
     """
-    return space.wrap(os.getegid())
+    return wrap_gid(space, os.getegid())
 
 def geteuid(space):
     """ geteuid() -> euid
 
     Return the current process's effective user id.
     """
-    return space.wrap(os.geteuid())
+    return wrap_uid(space, os.geteuid())
 
 def getgroups(space):
     """ getgroups() -> list of group IDs
@@ -1008,7 +1001,7 @@
         list = os.getgroups()
     except OSError as e:
         raise wrap_oserror(space, e)
-    return space.newlist([space.wrap(e) for e in list])
+    return space.newlist([wrap_gid(space, e) for e in list])
 
 def setgroups(space, w_list):
     """ setgroups(list)
@@ -1017,9 +1010,7 @@
     """
     list = []
     for w_gid in space.unpackiterable(w_list):
-        gid = space.int_w(w_gid)
-        check_uid_range(space, gid)
-        list.append(gid)
+        list.append(space.c_uid_t_w(w_gid))
     try:
         os.setgroups(list[:])
     except OSError as e:
@@ -1093,13 +1084,10 @@
 
     Set the current process's real and effective user ids.
     """
-    check_uid_range(space, ruid)
-    check_uid_range(space, euid)
     try:
         os.setreuid(ruid, euid)
     except OSError as e:
         raise wrap_oserror(space, e)
-    return space.w_None
 
 @unwrap_spec(rgid=c_gid_t, egid=c_gid_t)
 def setregid(space, rgid, egid):
@@ -1107,13 +1095,10 @@
 
     Set the current process's real and effective group ids.
     """
-    check_uid_range(space, rgid)
-    check_uid_range(space, egid)
     try:
         os.setregid(rgid, egid)
     except OSError as e:
         raise wrap_oserror(space, e)
-    return space.w_None
 
 @unwrap_spec(pid=c_int)
 def getsid(space, pid):
@@ -1150,7 +1135,7 @@
         raise wrap_oserror(space, e)
     return space.wrap(pgid)
 
- at unwrap_spec(fd=c_int, pgid=c_gid_t)
+ at unwrap_spec(fd=c_int, pgid=c_int)
 def tcsetpgrp(space, fd, pgid):
     """ tcsetpgrp(fd, pgid)
 
@@ -1170,9 +1155,9 @@
         (ruid, euid, suid) = os.getresuid()
     except OSError as e:
         raise wrap_oserror(space, e)
-    return space.newtuple([space.wrap(ruid),
-                           space.wrap(euid),
-                           space.wrap(suid)])
+    return space.newtuple([wrap_uid(space, ruid),
+                           wrap_uid(space, euid),
+                           wrap_uid(space, suid)])
 
 def getresgid(space):
     """ getresgid() -> (rgid, egid, sgid)
@@ -1183,9 +1168,9 @@
         (rgid, egid, sgid) = os.getresgid()
     except OSError as e:
         raise wrap_oserror(space, e)
-    return space.newtuple([space.wrap(rgid),
-                           space.wrap(egid),
-                           space.wrap(sgid)])
+    return space.newtuple([wrap_gid(space, rgid),
+                           wrap_gid(space, egid),
+                           wrap_gid(space, sgid)])
 
 @unwrap_spec(ruid=c_uid_t, euid=c_uid_t, suid=c_uid_t)
 def setresuid(space, ruid, euid, suid):
@@ -1284,8 +1269,6 @@
 @unwrap_spec(path='str0', uid=c_uid_t, gid=c_gid_t)
 def chown(space, path, uid, gid):
     """Change the owner and group id of path to the numeric uid and gid."""
-    check_uid_range(space, uid)
-    check_uid_range(space, gid)
     try:
         os.chown(path, uid, gid)
     except OSError as e:
@@ -1295,8 +1278,6 @@
 def lchown(space, path, uid, gid):
     """Change the owner and group id of path to the numeric uid and gid.
 This function will not follow symbolic links."""
-    check_uid_range(space, uid)
-    check_uid_range(space, gid)
     try:
         os.lchown(path, uid, gid)
     except OSError as e:
@@ -1307,8 +1288,6 @@
     """Change the owner and group id of the file given by file descriptor
 fd to the numeric uid and gid."""
     fd = space.c_filedescriptor_w(w_fd)
-    check_uid_range(space, uid)
-    check_uid_range(space, gid)
     try:
         os.fchown(fd, uid, gid)
     except OSError as e:
diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -621,8 +621,9 @@
     if hasattr(os, 'setuid'):
         def test_os_setuid_error(self):
             os = self.posix
-            raises(OverflowError, os.setuid, -2**31-1)
+            raises(OverflowError, os.setuid, -2)
             raises(OverflowError, os.setuid, 2**32)
+            raises(OSError, os.setuid, -1)
 
     if hasattr(os, 'getgid'):
         def test_os_getgid(self):
@@ -667,8 +668,11 @@
     if hasattr(os, 'setgid'):
         def test_os_setgid_error(self):
             os = self.posix
-            raises(OverflowError, os.setgid, -2**31-1)
+            raises(OverflowError, os.setgid, -2)
             raises(OverflowError, os.setgid, 2**32)
+            raises(OSError, os.setgid, -1)
+            raises(OSError, os.setgid, -1L)
+            raises(OSError, os.setgid, 2**32-1)
 
     if hasattr(os, 'getsid'):
         def test_os_getsid(self):
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -254,6 +254,8 @@
                                    [('actime', rffi.INT),
                                     ('modtime', rffi.INT)])
     if not _WIN32:
+        UID_T = rffi_platform.SimpleType('uid_t', rffi.UINT)
+        GID_T = rffi_platform.SimpleType('gid_t', rffi.UINT)
         CLOCK_T = rffi_platform.SimpleType('clock_t', rffi.INT)
 
         TMS = rffi_platform.Struct(
@@ -1453,32 +1455,33 @@
 def setpgid(pid, gid):
     handle_posix_error('setpgid', c_setpgid(pid, gid))
 
-PID_GROUPS_T = rffi.CArrayPtr(rffi.PID_T)
-c_getgroups = external('getgroups', [rffi.INT, PID_GROUPS_T], rffi.INT,
-                       save_err=rffi.RFFI_SAVE_ERRNO)
-c_setgroups = external('setgroups', [rffi.SIZE_T, PID_GROUPS_T], rffi.INT,
-                       save_err=rffi.RFFI_SAVE_ERRNO)
-c_initgroups = external('initgroups', [rffi.CCHARP, rffi.PID_T], rffi.INT,
-                        save_err=rffi.RFFI_SAVE_ERRNO)
+if not _WIN32:
+    GID_GROUPS_T = rffi.CArrayPtr(GID_T)
+    c_getgroups = external('getgroups', [rffi.INT, GID_GROUPS_T], rffi.INT,
+                           save_err=rffi.RFFI_SAVE_ERRNO)
+    c_setgroups = external('setgroups', [rffi.SIZE_T, GID_GROUPS_T], rffi.INT,
+                           save_err=rffi.RFFI_SAVE_ERRNO)
+    c_initgroups = external('initgroups', [rffi.CCHARP, GID_T], rffi.INT,
+                            save_err=rffi.RFFI_SAVE_ERRNO)
 
 @replace_os_function('getgroups')
 def getgroups():
     n = handle_posix_error('getgroups',
-                           c_getgroups(0, lltype.nullptr(PID_GROUPS_T.TO)))
-    groups = lltype.malloc(PID_GROUPS_T.TO, n, flavor='raw')
+                           c_getgroups(0, lltype.nullptr(GID_GROUPS_T.TO)))
+    groups = lltype.malloc(GID_GROUPS_T.TO, n, flavor='raw')
     try:
         n = handle_posix_error('getgroups', c_getgroups(n, groups))
-        return [widen(groups[i]) for i in range(n)]
+        return [widen_gid(groups[i]) for i in range(n)]
     finally:
         lltype.free(groups, flavor='raw')
 
 @replace_os_function('setgroups')
 def setgroups(gids):
     n = len(gids)
-    groups = lltype.malloc(PID_GROUPS_T.TO, n, flavor='raw')
+    groups = lltype.malloc(GID_GROUPS_T.TO, n, flavor='raw')
     try:
         for i in range(n):
-            groups[i] = rffi.cast(rffi.PID_T, gids[i])
+            groups[i] = rffi.cast(GID_T, gids[i])
         handle_posix_error('setgroups', c_setgroups(n, groups))
     finally:
         lltype.free(groups, flavor='raw')
@@ -1529,104 +1532,115 @@
 
 #___________________________________________________________________
 
-c_getuid = external('getuid', [], rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO)
-c_geteuid = external('geteuid', [], rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO)
-c_setuid = external('setuid', [rffi.INT], rffi.INT,
-                    save_err=rffi.RFFI_SAVE_ERRNO)
-c_seteuid = external('seteuid', [rffi.INT], rffi.INT,
-                     save_err=rffi.RFFI_SAVE_ERRNO)
-c_getgid = external('getgid', [], rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO)
-c_getegid = external('getegid', [], rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO)
-c_setgid = external('setgid', [rffi.INT], rffi.INT,
-                    save_err=rffi.RFFI_SAVE_ERRNO)
-c_setegid = external('setegid', [rffi.INT], rffi.INT,
-                     save_err=rffi.RFFI_SAVE_ERRNO)
+if not _WIN32:
+    c_getuid = external('getuid', [], UID_T)
+    c_geteuid = external('geteuid', [], UID_T)
+    c_setuid = external('setuid', [UID_T], rffi.INT,
+                        save_err=rffi.RFFI_SAVE_ERRNO)
+    c_seteuid = external('seteuid', [UID_T], rffi.INT,
+                         save_err=rffi.RFFI_SAVE_ERRNO)
+    c_getgid = external('getgid', [], GID_T)
+    c_getegid = external('getegid', [], GID_T)
+    c_setgid = external('setgid', [GID_T], rffi.INT,
+                        save_err=rffi.RFFI_SAVE_ERRNO)
+    c_setegid = external('setegid', [GID_T], rffi.INT,
+                         save_err=rffi.RFFI_SAVE_ERRNO)
 
- at replace_os_function('getuid')
-def getuid():
-    return handle_posix_error('getuid', c_getuid())
+    def widen_uid(x):
+        return rffi.cast(lltype.Unsigned, x)
+    widen_gid = widen_uid
 
- at replace_os_function('geteuid')
-def geteuid():
-    return handle_posix_error('geteuid', c_geteuid())
+    # NOTE: the resulting type of functions that return a uid/gid is
+    # always Unsigned.  The argument type of functions that take a
+    # uid/gid should also be Unsigned.
 
- at replace_os_function('setuid')
-def setuid(uid):
-    handle_posix_error('setuid', c_setuid(uid))
+    @replace_os_function('getuid')
+    def getuid():
+        return widen_uid(c_getuid())
 
- at replace_os_function('seteuid')
-def seteuid(uid):
-    handle_posix_error('seteuid', c_seteuid(uid))
+    @replace_os_function('geteuid')
+    def geteuid():
+        return widen_uid(c_geteuid())
 
- at replace_os_function('getgid')
-def getgid():
-    return handle_posix_error('getgid', c_getgid())
+    @replace_os_function('setuid')
+    def setuid(uid):
+        handle_posix_error('setuid', c_setuid(uid))
 
- at replace_os_function('getegid')
-def getegid():
-    return handle_posix_error('getegid', c_getegid())
+    @replace_os_function('seteuid')
+    def seteuid(uid):
+        handle_posix_error('seteuid', c_seteuid(uid))
 
- at replace_os_function('setgid')
-def setgid(gid):
-    handle_posix_error('setgid', c_setgid(gid))
+    @replace_os_function('getgid')
+    def getgid():
+        return widen_gid(c_getgid())
 
- at replace_os_function('setegid')
-def setegid(gid):
-    handle_posix_error('setegid', c_setegid(gid))
+    @replace_os_function('getegid')
+    def getegid():
+        return widen_gid(c_getegid())
 
-c_setreuid = external('setreuid', [rffi.INT, rffi.INT], rffi.INT,
-                      save_err=rffi.RFFI_SAVE_ERRNO)
-c_setregid = external('setregid', [rffi.INT, rffi.INT], rffi.INT,
-                      save_err=rffi.RFFI_SAVE_ERRNO)
+    @replace_os_function('setgid')
+    def setgid(gid):
+        handle_posix_error('setgid', c_setgid(gid))
 
- at replace_os_function('setreuid')
-def setreuid(ruid, euid):
-    handle_posix_error('setreuid', c_setreuid(ruid, euid))
+    @replace_os_function('setegid')
+    def setegid(gid):
+        handle_posix_error('setegid', c_setegid(gid))
 
- at replace_os_function('setregid')
-def setregid(rgid, egid):
-    handle_posix_error('setregid', c_setregid(rgid, egid))
+    c_setreuid = external('setreuid', [UID_T, UID_T], rffi.INT,
+                          save_err=rffi.RFFI_SAVE_ERRNO)
+    c_setregid = external('setregid', [GID_T, GID_T], rffi.INT,
+                          save_err=rffi.RFFI_SAVE_ERRNO)
 
-c_getresuid = external('getresuid', [rffi.INTP] * 3, rffi.INT,
-                       save_err=rffi.RFFI_SAVE_ERRNO)
-c_getresgid = external('getresgid', [rffi.INTP] * 3, rffi.INT,
-                       save_err=rffi.RFFI_SAVE_ERRNO)
-c_setresuid = external('setresuid', [rffi.INT] * 3, rffi.INT,
-                       save_err=rffi.RFFI_SAVE_ERRNO)
-c_setresgid = external('setresgid', [rffi.INT] * 3, rffi.INT,
-                       save_err=rffi.RFFI_SAVE_ERRNO)
+    @replace_os_function('setreuid')
+    def setreuid(ruid, euid):
+        handle_posix_error('setreuid', c_setreuid(ruid, euid))
 
- at replace_os_function('getresuid')
-def getresuid():
-    out = lltype.malloc(rffi.INTP.TO, 3, flavor='raw')
-    try:
-        handle_posix_error('getresuid',
-                           c_getresuid(rffi.ptradd(out, 0),
-                                       rffi.ptradd(out, 1),
-                                       rffi.ptradd(out, 2)))
-        return (widen(out[0]), widen(out[1]), widen(out[2]))
-    finally:
-        lltype.free(out, flavor='raw')
+    @replace_os_function('setregid')
+    def setregid(rgid, egid):
+        handle_posix_error('setregid', c_setregid(rgid, egid))
 
- at replace_os_function('getresgid')
-def getresgid():
-    out = lltype.malloc(rffi.INTP.TO, 3, flavor='raw')
-    try:
-        handle_posix_error('getresgid',
-                           c_getresgid(rffi.ptradd(out, 0),
-                                       rffi.ptradd(out, 1),
-                                       rffi.ptradd(out, 2)))
-        return (widen(out[0]), widen(out[1]), widen(out[2]))
-    finally:
-        lltype.free(out, flavor='raw')
+    UID_T_P = lltype.Ptr(lltype.Array(UID_T, hints={'nolength': True}))
+    GID_T_P = lltype.Ptr(lltype.Array(GID_T, hints={'nolength': True}))
+    c_getresuid = external('getresuid', [UID_T_P] * 3, rffi.INT,
+                           save_err=rffi.RFFI_SAVE_ERRNO)
+    c_getresgid = external('getresgid', [GID_T_P] * 3, rffi.INT,
+                           save_err=rffi.RFFI_SAVE_ERRNO)
+    c_setresuid = external('setresuid', [UID_T] * 3, rffi.INT,
+                           save_err=rffi.RFFI_SAVE_ERRNO)
+    c_setresgid = external('setresgid', [GID_T] * 3, rffi.INT,
+                           save_err=rffi.RFFI_SAVE_ERRNO)
 
- at replace_os_function('setresuid')
-def setresuid(ruid, euid, suid):
-    handle_posix_error('setresuid', c_setresuid(ruid, euid, suid))
+    @replace_os_function('getresuid')
+    def getresuid():
+        out = lltype.malloc(UID_T_P.TO, 3, flavor='raw')
+        try:
+            handle_posix_error('getresuid',
+                               c_getresuid(rffi.ptradd(out, 0),
+                                           rffi.ptradd(out, 1),
+                                           rffi.ptradd(out, 2)))
+            return (widen_uid(out[0]), widen_uid(out[1]), widen_uid(out[2]))
+        finally:
+            lltype.free(out, flavor='raw')
 
- at replace_os_function('setresgid')
-def setresgid(rgid, egid, sgid):
-    handle_posix_error('setresgid', c_setresgid(rgid, egid, sgid))
+    @replace_os_function('getresgid')
+    def getresgid():
+        out = lltype.malloc(GID_T_P.TO, 3, flavor='raw')
+        try:
+            handle_posix_error('getresgid',
+                               c_getresgid(rffi.ptradd(out, 0),
+                                           rffi.ptradd(out, 1),
+                                           rffi.ptradd(out, 2)))
+            return (widen_gid(out[0]), widen_gid(out[1]), widen_gid(out[2]))
+        finally:
+            lltype.free(out, flavor='raw')
+
+    @replace_os_function('setresuid')
+    def setresuid(ruid, euid, suid):
+        handle_posix_error('setresuid', c_setresuid(ruid, euid, suid))
+
+    @replace_os_function('setresgid')
+    def setresgid(rgid, egid, sgid):
+        handle_posix_error('setresgid', c_setresgid(rgid, egid, sgid))
 
 #___________________________________________________________________
 


More information about the pypy-commit mailing list