Author: Ronan Lamy <ronan.l...@gmail.com> Branch: py3k Changeset: r86278:69541f67e745 Date: 2016-08-18 15:56 +0100 http://bitbucket.org/pypy/pypy/changeset/69541f67e745/
Log: hg merge default diff --git a/lib_pypy/resource.py b/lib_pypy/resource.py --- a/lib_pypy/resource.py +++ b/lib_pypy/resource.py @@ -86,7 +86,11 @@ if len(limits) != 2: raise ValueError("expected a tuple of 2 integers") - if lib.my_setrlimit(resource, limits[0], limits[1]) == -1: + # accept and round down floats, like CPython does + limit0 = int(limits[0]) + limit1 = int(limits[1]) + + if lib.my_setrlimit(resource, limit0, limit1) == -1: if ffi.errno == EINVAL: raise ValueError("current limit exceeds maximum limit") elif ffi.errno == EPERM: diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -356,6 +356,11 @@ that a C-level traceback is usually of no help at all in PyPy. Debugging PyPy can be annoying. +`This is a clear and useful bug report.`__ (Admittedly, sometimes +the problem is really hard to reproduce, but please try to.) + +.. __: https://bitbucket.org/pypy/pypy/issues/2363/segfault-in-gc-pinned-object-in + In more details: * First, please give the exact PyPy version, and the OS. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1748,6 +1748,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 @@ -177,6 +177,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) @@ -307,6 +310,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(),)) @@ -456,6 +462,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/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -257,6 +257,7 @@ sandboxsafe=True) # split here for JIT backends that don't support floats/longlongs/etc. +@jit.dont_look_inside def is_nonnull_longdouble(cdata): return _is_nonnull_longdouble(read_raw_longdouble_data(cdata)) def is_nonnull_float(cdata, size): diff --git a/pypy/module/_cffi_backend/test/test_re_python.py b/pypy/module/_cffi_backend/test/test_re_python.py --- a/pypy/module/_cffi_backend/test/test_re_python.py +++ b/pypy/module/_cffi_backend/test/test_re_python.py @@ -69,10 +69,21 @@ sub_ffi.set_source('re_py_subsrc', None) sub_ffi.emit_python_code(str(tmpdir.join('re_py_subsrc.py'))) # - space.appexec([space.wrap(str(tmpdir))], """(path): + cls.w_ffi = space.appexec([space.wrap(str(tmpdir))], """(path): import _cffi_backend # force it to be initialized import sys sys.path.insert(0, path) + from re_python_pysrc import ffi + del sys.path[0] + return ffi + """) + cls.w_sub_ffi = space.appexec([space.wrap(str(tmpdir))], """(path): + import _cffi_backend # force it to be initialized + import sys + sys.path.insert(0, path) + from re_py_subsrc import ffi + del sys.path[0] + return ffi """) def teardown_method(self, meth): @@ -86,25 +97,25 @@ def test_constant_1(self): - from re_python_pysrc import ffi + ffi = self.ffi assert ffi.integer_const('FOOBAR') == -42 assert ffi.integer_const('FOOBAZ') == -43 def test_large_constant(self): - from re_python_pysrc import ffi + ffi = self.ffi assert ffi.integer_const('BIGPOS') == 420000000000 assert ffi.integer_const('BIGNEG') == -420000000000 def test_function(self): import _cffi_backend - from re_python_pysrc import ffi + ffi = self.ffi lib = ffi.dlopen(self.extmod) assert lib.add42(-10) == 32 assert type(lib.add42) is _cffi_backend.FFI.CData def test_dlclose(self): import _cffi_backend - from re_python_pysrc import ffi + ffi = self.ffi lib = ffi.dlopen(self.extmod) ffi.dlclose(lib) e = raises(ffi.error, ffi.dlclose, lib) @@ -115,18 +126,18 @@ "library '%s' has been closed" % (self.extmod,)) def test_constant_via_lib(self): - from re_python_pysrc import ffi + ffi = self.ffi lib = ffi.dlopen(self.extmod) assert lib.FOOBAR == -42 assert lib.FOOBAZ == -43 def test_opaque_struct(self): - from re_python_pysrc import ffi + ffi = self.ffi ffi.cast("struct foo_s *", 0) raises(TypeError, ffi.new, "struct foo_s *") def test_nonopaque_struct(self): - from re_python_pysrc import ffi + ffi = self.ffi for p in [ffi.new("struct bar_s *", [5, b"foobar"]), ffi.new("bar_t *", [5, b"foobar"])]: assert p.x == 5 @@ -134,13 +145,13 @@ assert p.a[5] == ord('r') def test_enum(self): - from re_python_pysrc import ffi + ffi = self.ffi assert ffi.integer_const("BB") == 1 e = ffi.cast("enum foo_e", 2) assert ffi.string(e) == "CC" def test_include_1(self): - from re_py_subsrc import ffi + ffi = self.sub_ffi assert ffi.integer_const('FOOBAR') == -42 assert ffi.integer_const('FOOBAZ') == -43 assert ffi.integer_const('k2') == 121212 @@ -153,7 +164,7 @@ assert p.a[4] == ord('a') def test_global_var(self): - from re_python_pysrc import ffi + ffi = self.ffi lib = ffi.dlopen(self.extmod) assert lib.globalvar42 == 1234 p = ffi.addressof(lib, 'globalvar42') @@ -163,25 +174,25 @@ assert lib.globalvar42 == 1238 def test_global_const_int(self): - from re_python_pysrc import ffi + ffi = self.ffi lib = ffi.dlopen(self.extmod) assert lib.globalconst42 == 4321 raises(AttributeError, ffi.addressof, lib, 'globalconst42') def test_global_const_nonint(self): - from re_python_pysrc import ffi + ffi = self.ffi lib = ffi.dlopen(self.extmod) assert ffi.string(lib.globalconsthello, 8) == b"hello" raises(AttributeError, ffi.addressof, lib, 'globalconsthello') def test_rtld_constants(self): - from re_python_pysrc import ffi + ffi = self.ffi ffi.RTLD_NOW # check that we have the attributes ffi.RTLD_LAZY ffi.RTLD_GLOBAL def test_no_such_function_or_global_var(self): - from re_python_pysrc import ffi + ffi = self.ffi lib = ffi.dlopen(self.extmod) e = raises(ffi.error, getattr, lib, 'no_such_function') assert str(e.value).startswith( diff --git a/pypy/module/_multibytecodec/src/cjkcodecs/cjkcodecs.h b/pypy/module/_multibytecodec/src/cjkcodecs/cjkcodecs.h --- a/pypy/module/_multibytecodec/src/cjkcodecs/cjkcodecs.h +++ b/pypy/module/_multibytecodec/src/cjkcodecs/cjkcodecs.h @@ -268,22 +268,26 @@ min = 0; max = haystacksize; - for (pos = haystacksize >> 1; min != max; pos = (min + max) >> 1) + for (pos = haystacksize >> 1; min != max; pos = (min + max) >> 1) { if (value < haystack[pos].uniseq) { - if (max == pos) break; - else max = pos; + if (max != pos) { + max = pos; + continue; + } } else if (value > haystack[pos].uniseq) { - if (min == pos) break; - else min = pos; + if (min != pos) { + min = pos; + continue; + } } - else - break; + break; + } - if (value == haystack[pos].uniseq) - return haystack[pos].code; - else - return DBCINV; + if (value == haystack[pos].uniseq) { + return haystack[pos].code; + } + return DBCINV; } #endif 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 @@ -11,7 +11,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 rpython.tool.sourcetools import func_with_new_name @@ -28,20 +28,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 class FileEncoder(object): is_unicode = True @@ -1527,7 +1528,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): @@ -1535,12 +1536,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): @@ -1548,12 +1547,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): @@ -1561,12 +1558,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): @@ -1574,12 +1569,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='fsencode') def chroot(space, path): @@ -1598,21 +1591,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 @@ -1623,7 +1616,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) @@ -1632,9 +1625,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: @@ -1708,13 +1699,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): @@ -1722,13 +1710,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): @@ -1785,9 +1770,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) @@ -1798,9 +1783,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): @@ -1922,8 +1907,6 @@ an open file descriptor. dir_fd and follow_symlinks may not be implemented on your platform. If they are unavailable, using them will raise a NotImplementedError.""" - check_uid_range(space, uid) - check_uid_range(space, gid) if not (rposix.HAVE_LCHOWN or rposix.HAVE_FCHMODAT): if not follow_symlinks: raise argument_unavailable(space, 'chown', 'follow_symlinks') @@ -1969,8 +1952,6 @@ Change the owner and group id of path to the numeric uid and gid. This function will not follow symbolic links. Equivalent to os.chown(path, uid, gid, follow_symlinks=False).""" - check_uid_range(space, uid) - check_uid_range(space, gid) try: os.lchown(path, uid, gid) except OSError as e: @@ -1983,8 +1964,6 @@ Change the owner and group id of the file given by file descriptor fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, 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 @@ -595,8 +595,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): @@ -641,8 +642,10 @@ 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, 2**32-1) if hasattr(os, 'getsid'): def test_os_getsid(self): diff --git a/pypy/module/test_lib_pypy/test_resource.py b/pypy/module/test_lib_pypy/test_resource.py --- a/pypy/module/test_lib_pypy/test_resource.py +++ b/pypy/module/test_lib_pypy/test_resource.py @@ -45,5 +45,8 @@ def test_setrlimit(): # minimal "does not crash" test - x = resource.getrlimit(resource.RLIMIT_CPU) - resource.setrlimit(resource.RLIMIT_CPU, x) + x, y = resource.getrlimit(resource.RLIMIT_CPU) + resource.setrlimit(resource.RLIMIT_CPU, (x, y)) + x += 0.2 + y += 0.3 + resource.setrlimit(resource.RLIMIT_CPU, (x, y)) # truncated to ints diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py --- a/pypy/objspace/std/mapdict.py +++ b/pypy/objspace/std/mapdict.py @@ -221,7 +221,6 @@ stack_index = 0 while True: current = self - number_to_readd = 0 number_to_readd, attr = self._find_branch_to_move_into(name, index) # we found the attributes further up, need to save the # previous values of the attributes we passed diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -1051,8 +1051,9 @@ metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd # + jd_name = jitdriver_sd.jitdriver.name metainterp_sd.jitlog.start_new_trace(metainterp_sd, - faildescr=resumekey, entry_bridge=False) + faildescr=resumekey, entry_bridge=False, jd_name=jd_name) # if isinstance(resumekey, ResumeAtPositionDescr): inline_short_preamble = False diff --git a/rpython/jit/metainterp/logger.py b/rpython/jit/metainterp/logger.py --- a/rpython/jit/metainterp/logger.py +++ b/rpython/jit/metainterp/logger.py @@ -98,6 +98,7 @@ def log_abort_loop(self, trace, memo=None): debug_start("jit-abort-log") if not have_debug_prints(): + debug_stop("jit-abort-log") return inputargs, operations = self._unpack_trace(trace) logops = self._log_operations(inputargs, operations, ops_offset=None, diff --git a/rpython/jit/metainterp/test/support.py b/rpython/jit/metainterp/test/support.py --- a/rpython/jit/metainterp/test/support.py +++ b/rpython/jit/metainterp/test/support.py @@ -64,6 +64,10 @@ testself.all_graphs = graphs result_kind = history.getkind(graphs[0].getreturnvar().concretetype)[0] + + class FakeJitDriver: + name = 'fakejitdriver' + class FakeJitDriverSD: num_green_args = 0 portal_graph = graphs[0] @@ -72,6 +76,7 @@ result_type = result_kind portal_runner_ptr = "???" vec = False + jitdriver = FakeJitDriver() stats = history.Stats(None) cpu = CPUClass(rtyper, stats, None, False) diff --git a/rpython/rlib/rjitlog/rjitlog.py b/rpython/rlib/rjitlog/rjitlog.py --- a/rpython/rlib/rjitlog/rjitlog.py +++ b/rpython/rlib/rjitlog/rjitlog.py @@ -212,7 +212,7 @@ return method return decor -JITLOG_VERSION = 1 +JITLOG_VERSION = 2 JITLOG_VERSION_16BIT_LE = struct.pack("<H", JITLOG_VERSION) marks = [ @@ -331,7 +331,7 @@ def finish(self): jitlog_teardown() - def start_new_trace(self, metainterp_sd, faildescr=None, entry_bridge=False): + def start_new_trace(self, metainterp_sd, faildescr=None, entry_bridge=False, jd_name=""): # even if the logger is not enabled, increment the trace id self.trace_id += 1 if not jitlog_enabled(): @@ -345,6 +345,7 @@ else: content.append(encode_str('loop')) content.append(encode_le_addr(int(entry_bridge))) + content.append(encode_str(jd_name)) self._write_marked(MARK_START_TRACE, ''.join(content)) def trace_aborted(self): @@ -508,7 +509,9 @@ """ an operation is written as follows: <marker> <opid (16 bit)> \ <len (32 bit)> \ - <res_val>,<arg_0>,...,<arg_n>,<descr> + <res_val>,<arg_0>,...,<arg_n> \ + <descr> + <failarg_0>,...<failarg_n> The marker indicates if the last argument is a descr or a normal argument. """ @@ -517,16 +520,21 @@ le_opnum = encode_le_16bit(op.getopnum()) str_res = self.var_to_str(op) line = ','.join([str_res] + str_args) + failargslist = op.getfailargs() + failargs = '' + if failargslist: + failargs = ','.join([self.var_to_str(farg) for farg in failargslist]) + # if descr: descr_str = descr.repr_of_descr() line = line + ',' + descr_str string = encode_str(line) descr_number = compute_unique_id(descr) le_descr_number = encode_le_addr(descr_number) - return MARK_RESOP_DESCR, le_opnum + string + le_descr_number + return MARK_RESOP_DESCR, le_opnum + string + le_descr_number + encode_str(failargs) else: string = encode_str(line) - return MARK_RESOP, le_opnum + string + return MARK_RESOP, le_opnum + string + encode_str(failargs) def write_core_dump(self, operations, i, op, ops_offset): @@ -578,6 +586,8 @@ return ''.join(dump) def var_to_str(self, arg): + if arg is None: + return '-' try: mv = self.memo[arg] except KeyError: diff --git a/rpython/rlib/rjitlog/test/test_jitlog.py b/rpython/rlib/rjitlog/test/test_jitlog.py --- a/rpython/rlib/rjitlog/test/test_jitlog.py +++ b/rpython/rlib/rjitlog/test/test_jitlog.py @@ -48,7 +48,7 @@ file.ensure() fd = file.open('wb') jl.jitlog_init(fd.fileno()) - logger.start_new_trace(self.make_metainterp_sd()) + logger.start_new_trace(self.make_metainterp_sd(), jd_name='jdname') log_trace = logger.log_trace(jl.MARK_TRACE, None, None) op = ResOperation(rop.DEBUG_MERGE_POINT, [ConstInt(0), ConstInt(0), ConstInt(0)]) log_trace.write([], [op]) @@ -58,6 +58,7 @@ is_32bit = chr(sys.maxint == 2**31-1) assert binary == (jl.MARK_START_TRACE) + jl.encode_le_addr(1) + \ jl.encode_str('loop') + jl.encode_le_addr(0) + \ + jl.encode_str('jdname') + \ (jl.MARK_TRACE) + jl.encode_le_addr(1) + \ (jl.MARK_INPUT_ARGS) + jl.encode_str('') + \ (jl.MARK_INIT_MERGE_POINT) + b'\x05\x00\x01s\x00i\x08s\x00i\x10s' + \ diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -96,12 +96,15 @@ return 0; } ''',] + post_include_bits=['RPY_EXTERN int _PyVerify_fd(int);'] else: separate_module_sources = [] + post_include_bits = [] includes=['errno.h','stdio.h'] errno_eci = ExternalCompilationInfo( includes=includes, separate_module_sources=separate_module_sources, + post_include_bits=post_include_bits, ) # Direct getters/setters, don't use directly! @@ -251,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( @@ -1450,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') @@ -1526,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) -@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 -@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. -@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()) -@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()) -@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)) -@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)) -@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()) -@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)) -@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)) -@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)) -@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)) -@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) -@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') -@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)) #___________________________________________________________________ @@ -2046,3 +2063,40 @@ def mknodat(path, mode, device, dir_fd=AT_FDCWD): error = c_mknodat(dir_fd, path, mode, device) handle_posix_error('mknodat', error) + + +eci_inheritable = eci.merge(ExternalCompilationInfo( + separate_module_sources=[""" +RPY_EXTERN +int rpy_set_inheritable(int fd, int inheritable) +{ + /* XXX minimal impl. XXX */ + int request = inheritable ? FIONCLEX : FIOCLEX; + return ioctl(fd, request, NULL); +} +RPY_EXTERN +int rpy_get_inheritable(int fd) +{ + int flags = fcntl(fd, F_GETFD, 0); + if (flags == -1) + return -1; + return !(flags & FD_CLOEXEC); +} + """], + post_include_bits=['RPY_EXTERN int rpy_set_inheritable(int, int);'])) + +c_set_inheritable = external('rpy_set_inheritable', [rffi.INT, rffi.INT], + rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO, + compilation_info=eci_inheritable) +c_get_inheritable = external('rpy_get_inheritable', [rffi.INT], + rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO, + compilation_info=eci_inheritable) + +def set_inheritable(fd, inheritable): + error = c_set_inheritable(fd, inheritable) + handle_posix_error('set_inheritable', error) + +def get_inheritable(fd): + res = c_get_inheritable(fd) + res = handle_posix_error('get_inheritable', res) + return res != 0 diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py --- a/rpython/rlib/test/test_rposix.py +++ b/rpython/rlib/test/test_rposix.py @@ -572,3 +572,12 @@ os.close(dirfd) assert tmpdir.join('file').check(exists=False) assert tmpdir.join('file2').check(exists=True) + +def test_set_inheritable(): + fd1, fd2 = os.pipe() + rposix.set_inheritable(fd1, True) + assert rposix.get_inheritable(fd1) == True + rposix.set_inheritable(fd1, False) + assert rposix.get_inheritable(fd1) == False + os.close(fd1) + os.close(fd2) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit