Author: Amaury Forgeot d'Arc <[email protected]>
Branch: py3.3
Changeset: r78333:7d4ae17b382a
Date: 2015-06-25 08:37 +0200
http://bitbucket.org/pypy/pypy/changeset/7d4ae17b382a/

Log:    hg merge more-rposix, directly in py3.3 branch.

diff too long, truncating to 2000 out of 8516 lines

diff --git a/pypy/module/_io/interp_io.py b/pypy/module/_io/interp_io.py
--- a/pypy/module/_io/interp_io.py
+++ b/pypy/module/_io/interp_io.py
@@ -6,7 +6,9 @@
     TypeDef, interp_attrproperty, generic_new_descr)
 from pypy.module._io.interp_fileio import W_FileIO
 from pypy.module._io.interp_textio import W_TextIOWrapper
-from rpython.rtyper.module.ll_os_stat import STAT_FIELD_TYPES
+from rpython.rlib.rposix_stat import STAT_FIELD_TYPES
+
+HAS_BLKSIZE = 'st_blksize' in STAT_FIELD_TYPES
 
 
 class Cache:
@@ -102,7 +104,7 @@
     if buffering < 0:
         buffering = DEFAULT_BUFFER_SIZE
 
-        if space.config.translation.type_system == 'lltype' and 'st_blksize' 
in STAT_FIELD_TYPES:
+        if HAS_BLKSIZE:
             fileno = space.c_int_w(space.call_method(w_raw, "fileno"))
             try:
                 st = os.fstat(fileno)
diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py
--- a/pypy/module/posix/__init__.py
+++ b/pypy/module/posix/__init__.py
@@ -1,5 +1,5 @@
 from pypy.interpreter.mixedmodule import MixedModule
-from rpython.rtyper.module.ll_os import RegisterOs
+from rpython.rlib import rposix
 from rpython.rlib import rdynload
 
 import os
@@ -176,7 +176,7 @@
     if hasattr(os, 'chroot'):
         interpleveldefs['chroot'] = 'interp_posix.chroot'
 
-    for name in RegisterOs.w_star:
+    for name in rposix.WAIT_MACROS:
         if hasattr(os, name):
             interpleveldefs[name] = 'interp_posix.' + name
 
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
@@ -1,12 +1,11 @@
 import os
 import sys
 
-from rpython.rlib import rposix, objectmodel, rurandom
+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.unroll import unrolling_iterable
-from rpython.rtyper.module import ll_os_stat
-from rpython.rtyper.module.ll_os import RegisterOs
 
 from pypy.interpreter.gateway import unwrap_spec, WrappedDefault
 from pypy.interpreter.error import (OperationError, wrap_oserror,
@@ -37,6 +36,8 @@
                                  space.wrap("integer out of range"))
 
 class FileEncoder(object):
+    is_unicode = True
+
     def __init__(self, space, w_obj):
         self.space = space
         self.w_obj = w_obj
@@ -48,6 +49,8 @@
         return self.space.unicode0_w(self.w_obj)
 
 class FileDecoder(object):
+    is_unicode = False
+
     def __init__(self, space, w_obj):
         self.space = space
         self.w_obj = w_obj
@@ -222,13 +225,13 @@
 
 # ____________________________________________________________
 
-STAT_FIELDS = unrolling_iterable(enumerate(ll_os_stat.STAT_FIELDS))
+STAT_FIELDS = unrolling_iterable(enumerate(rposix_stat.STAT_FIELDS))
 
-STATVFS_FIELDS = unrolling_iterable(enumerate(ll_os_stat.STATVFS_FIELDS))
+STATVFS_FIELDS = unrolling_iterable(enumerate(rposix_stat.STATVFS_FIELDS))
 
 def build_stat_result(space, st):
     FIELDS = STAT_FIELDS    # also when not translating at all
-    lst = [None] * ll_os_stat.N_INDEXABLE_FIELDS
+    lst = [None] * rposix_stat.N_INDEXABLE_FIELDS
     w_keywords = space.newdict()
     stat_float_times = space.fromcache(StatState).stat_float_times
     for i, (name, TYPE) in FIELDS:
@@ -236,7 +239,7 @@
         if name in ('st_atime', 'st_mtime', 'st_ctime'):
             value = int(value)   # rounded to an integer for indexed access
         w_value = space.wrap(value)
-        if i < ll_os_stat.N_INDEXABLE_FIELDS:
+        if i < rposix_stat.N_INDEXABLE_FIELDS:
             lst[i] = w_value
         else:
             space.setitem(w_keywords, space.wrap(name), w_value)
@@ -264,7 +267,7 @@
 
 
 def build_statvfs_result(space, st):
-    vals_w = [None] * len(ll_os_stat.STATVFS_FIELDS)
+    vals_w = [None] * len(rposix_stat.STATVFS_FIELDS)
     for i, (name, _) in STATVFS_FIELDS:
         vals_w[i] = space.wrap(getattr(st, name))
     w_tuple = space.newtuple(vals_w)
@@ -277,7 +280,7 @@
     """Perform a stat system call on the file referenced to by an open
 file descriptor."""
     try:
-        st = os.fstat(fd)
+        st = rposix_stat.fstat(fd)
     except OSError, e:
         raise wrap_oserror(space, e)
     else:
@@ -299,7 +302,7 @@
 """
 
     try:
-        st = dispatch_filename(rposix.stat)(space, w_path)
+        st = dispatch_filename(rposix_stat.stat)(space, w_path)
     except OSError, e:
         raise wrap_oserror2(space, e, w_path)
     else:
@@ -308,7 +311,7 @@
 def lstat(space, w_path):
     "Like stat(path), but do no follow symbolic links."
     try:
-        st = dispatch_filename(rposix.lstat)(space, w_path)
+        st = dispatch_filename(rposix_stat.lstat)(space, w_path)
     except OSError, e:
         raise wrap_oserror2(space, e, w_path)
     else:
@@ -337,7 +340,7 @@
 @unwrap_spec(fd=c_int)
 def fstatvfs(space, fd):
     try:
-        st = os.fstatvfs(fd)
+        st = rposix_stat.fstatvfs(fd)
     except OSError as e:
         raise wrap_oserror(space, e)
     else:
@@ -346,7 +349,7 @@
 
 def statvfs(space, w_path):
     try:
-        st = dispatch_filename(rposix.statvfs)(space, w_path)
+        st = dispatch_filename(rposix_stat.statvfs)(space, w_path)
     except OSError as e:
         raise wrap_oserror2(space, e, w_path)
     else:
@@ -437,11 +440,11 @@
     try:
         if space.isinstance_w(w_path, space.w_unicode):
             path = FileEncoder(space, w_path)
-            fullpath = rposix._getfullpathname(path)
+            fullpath = rposix.getfullpathname(path)
             w_fullpath = space.wrap(fullpath)
         else:
             path = space.str0_w(w_path)
-            fullpath = rposix._getfullpathname(path)
+            fullpath = rposix.getfullpathname(path)
             w_fullpath = space.wrapbytes(fullpath)
     except OSError, e:
         raise wrap_oserror2(space, e, w_path)
@@ -688,7 +691,7 @@
 def kill(space, pid, sig):
     "Kill a process with a signal."
     try:
-        rposix.os_kill(pid, sig)
+        rposix.kill(pid, sig)
     except OSError, e:
         raise wrap_oserror(space, e)
 
@@ -704,7 +707,7 @@
     """Abort the interpreter immediately.  This 'dumps core' or otherwise fails
 in the hardest way possible on the hosting operating system."""
     import signal
-    rposix.os_kill(os.getpid(), signal.SIGABRT)
+    rposix.kill(os.getpid(), signal.SIGABRT)
 
 @unwrap_spec(src='fsencode', dst='fsencode')
 def link(space, src, dst):
@@ -1237,7 +1240,7 @@
         raise wrap_oserror(space, e)
 
 def declare_new_w_star(name):
-    if name in RegisterOs.w_star_returning_int:
+    if name in ('WEXITSTATUS', 'WSTOPSIG', 'WTERMSIG'):
         @unwrap_spec(status=c_int)
         def WSTAR(space, status):
             return space.wrap(getattr(os, name)(status))
@@ -1249,7 +1252,7 @@
     WSTAR.func_name = name
     return WSTAR
 
-for name in RegisterOs.w_star:
+for name in rposix.WAIT_MACROS:
     if hasattr(os, name):
         func = declare_new_w_star(name)
         globals()[name] = func
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
@@ -6,8 +6,8 @@
 from rpython.tool.udir import udir
 from pypy.tool.pytest.objspace import gettestobjspace
 from pypy.conftest import pypydir
-from rpython.rtyper.module.ll_os import RegisterOs
 from rpython.translator.c.test.test_extfunc import need_sparse_files
+from rpython.rlib import rposix
 import os
 import py
 import sys
@@ -539,7 +539,7 @@
         raises(TypeError, "os.utime('xxx', 3)")
         raises(OSError, "os.utime('somefilewhichihopewouldneverappearhere', 
None)")
 
-    for name in RegisterOs.w_star:
+    for name in rposix.WAIT_MACROS:
         if hasattr(os, name):
             values = [0, 1, 127, 128, 255]
             code = py.code.Source("""
diff --git a/pypy/module/time/interp_time.py b/pypy/module/time/interp_time.py
--- a/pypy/module/time/interp_time.py
+++ b/pypy/module/time/interp_time.py
@@ -486,13 +486,6 @@
     secs = pytime.time()
     return space.wrap(secs)
 
-if _WIN:
-    class PCCache:
-        pass
-    pccache = PCCache()
-    pccache.divisor = 0.0
-    pccache.ctrStart = 0
-
 def clock(space):
     """clock() -> floating point number
 
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -237,10 +237,11 @@
             else:
                 result = SomeString(no_nul=no_nul)
         elif tp is unicode:
+            no_nul = not u'\x00' in x
             if len(x) == 1:
-                result = SomeUnicodeCodePoint()
+                result = SomeUnicodeCodePoint(no_nul=no_nul)
             else:
-                result = SomeUnicodeString()
+                result = SomeUnicodeString(no_nul=no_nul)
         elif tp is bytearray:
             result = SomeByteArray()
         elif tp is tuple:
diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py
--- a/rpython/annotator/unaryop.py
+++ b/rpython/annotator/unaryop.py
@@ -569,7 +569,7 @@
         enc = s_enc.const
         if enc not in ('ascii', 'latin-1', 'utf-8'):
             raise AnnotatorError("Encoding %s not supported for unicode" % 
(enc,))
-        return SomeString()
+        return SomeString(no_nul=self.no_nul)
     method_encode.can_only_throw = [UnicodeEncodeError]
 
 
@@ -602,7 +602,7 @@
         enc = s_enc.const
         if enc not in ('ascii', 'latin-1', 'utf-8'):
             raise AnnotatorError("Encoding %s not supported for strings" % 
(enc,))
-        return SomeUnicodeString()
+        return SomeUnicodeString(no_nul=self.no_nul)
     method_decode.can_only_throw = [UnicodeDecodeError]
 
 class __extend__(SomeChar, SomeUnicodeCodePoint):
diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py
--- a/rpython/flowspace/objspace.py
+++ b/rpython/flowspace/objspace.py
@@ -18,7 +18,7 @@
     if func.func_code.co_cellvars:
         raise ValueError(
 """RPython functions cannot create closures
-Possible casues:
+Possible causes:
     Function is inner function
     Function uses generator expressions
     Lambda expressions
diff --git a/rpython/jit/metainterp/jitprof.py 
b/rpython/jit/metainterp/jitprof.py
--- a/rpython/jit/metainterp/jitprof.py
+++ b/rpython/jit/metainterp/jitprof.py
@@ -51,7 +51,7 @@
 
 class Profiler(BaseProfiler):
     initialized = False
-    timer = time.time
+    timer = staticmethod(time.time)
     starttime = 0
     t1 = 0
     times = None
diff --git a/rpython/memory/gc/inspector.py b/rpython/memory/gc/inspector.py
--- a/rpython/memory/gc/inspector.py
+++ b/rpython/memory/gc/inspector.py
@@ -3,7 +3,6 @@
 """
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, llgroup
 from rpython.rlib.objectmodel import free_non_gc_object
-from rpython.rtyper.module.ll_os import UNDERSCORE_ON_WIN32
 from rpython.rlib import rposix, rgc, jit
 
 from rpython.memory.support import AddressDict, get_address_stack
@@ -94,7 +93,7 @@
 
 # ----------
 
-raw_os_write = rffi.llexternal(UNDERSCORE_ON_WIN32 + 'write',
+raw_os_write = rffi.llexternal(rposix.UNDERSCORE_ON_WIN32 + 'write',
                                [rffi.INT, llmemory.Address, rffi.SIZE_T],
                                rffi.SIZE_T,
                                sandboxsafe=True, _nowrapper=True)
diff --git a/rpython/memory/gctransform/support.py 
b/rpython/memory/gctransform/support.py
--- a/rpython/memory/gctransform/support.py
+++ b/rpython/memory/gctransform/support.py
@@ -73,15 +73,19 @@
         hop.exception_cannot_occur()
         return hop.inputconst(hop.r_result.lowleveltype, hop.s_result.const)
 
+def write(fd, string):
+    from rpython.rlib.rposix import c_write
+    return c_write(fd, string, len(string))
+
 def ll_call_destructor(destrptr, destr_v, typename):
     try:
         destrptr(destr_v)
     except Exception, e:
         try:
-            os.write(2, "a destructor of type ")
-            os.write(2, typename)
-            os.write(2, " raised an exception ")
-            os.write(2, str(e))
-            os.write(2, " ignoring it\n")
+            write(2, "a destructor of type ")
+            write(2, typename)
+            write(2, " raised an exception ")
+            write(2, str(e))
+            write(2, " ignoring it\n")
         except:
             pass
diff --git a/rpython/rlib/_rposix_repr.py b/rpython/rlib/_rposix_repr.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/_rposix_repr.py
@@ -0,0 +1,122 @@
+"""
+RTyping support for os.stat_result objects.
+They are rtyped just like a tuple of the correct length supporting
+only indexing and the st_xxx attributes.  We need a custom StatResultRepr
+because when rtyping for LL backends we have extra platform-dependent
+items at the end of the tuple, but for OO backends we only want the
+portable items.  This allows the OO backends to assume a fixed shape for
+the tuples returned by os.stat().
+"""
+from rpython.annotator import model as annmodel
+from rpython.rtyper.llannotation import lltype_to_annotation
+from rpython.flowspace.model import Constant
+from rpython.flowspace.operation import op
+from rpython.tool.pairtype import pairtype
+from rpython.rtyper.rmodel import Repr
+from rpython.rtyper.rint import IntegerRepr
+from rpython.rtyper.error import TyperError
+from rpython.rlib import rposix_stat
+
+
+class StatResultRepr(Repr):
+
+    def __init__(self, rtyper):
+        self.rtyper = rtyper
+        self.stat_fields = rposix_stat.STAT_FIELDS
+
+        self.stat_field_indexes = {}
+        for i, (name, TYPE) in enumerate(self.stat_fields):
+            self.stat_field_indexes[name] = i
+
+        self.s_tuple = annmodel.SomeTuple([lltype_to_annotation(TYPE)
+                                           for name, TYPE in self.stat_fields])
+        self.r_tuple = rtyper.getrepr(self.s_tuple)
+        self.lowleveltype = self.r_tuple.lowleveltype
+
+    def redispatch_getfield(self, hop, index):
+        rtyper = self.rtyper
+        s_index = rtyper.annotator.bookkeeper.immutablevalue(index)
+        hop2 = hop.copy()
+        spaceop = op.getitem(hop.args_v[0], Constant(index))
+        spaceop.result = hop.spaceop.result
+        hop2.spaceop = spaceop
+        hop2.args_v = spaceop.args
+        hop2.args_s = [self.s_tuple, s_index]
+        hop2.args_r = [self.r_tuple, rtyper.getrepr(s_index)]
+        return hop2.dispatch()
+
+    def rtype_getattr(self, hop):
+        s_attr = hop.args_s[1]
+        attr = s_attr.const
+        try:
+            index = self.stat_field_indexes[attr]
+        except KeyError:
+            raise TyperError("os.stat().%s: field not available" % (attr,))
+        return self.redispatch_getfield(hop, index)
+
+
+class __extend__(pairtype(StatResultRepr, IntegerRepr)):
+
+    def rtype_getitem((r_sta, r_int), hop):
+        s_int = hop.args_s[1]
+        index = s_int.const
+        return r_sta.redispatch_getfield(hop, index)
+
+
+def specialize_make_stat_result(hop):
+    r_StatResult = hop.rtyper.getrepr(rposix_stat.s_StatResult)
+    [v_result] = hop.inputargs(r_StatResult.r_tuple)
+    # no-op conversion from r_StatResult.r_tuple to r_StatResult
+    hop.exception_cannot_occur()
+    return v_result
+
+
+class StatvfsResultRepr(Repr):
+
+    def __init__(self, rtyper):
+        self.rtyper = rtyper
+        self.statvfs_fields = rposix_stat.STATVFS_FIELDS
+
+        self.statvfs_field_indexes = {}
+        for i, (name, TYPE) in enumerate(self.statvfs_fields):
+            self.statvfs_field_indexes[name] = i
+
+        self.s_tuple = annmodel.SomeTuple([lltype_to_annotation(TYPE)
+                                           for name, TYPE in 
self.statvfs_fields])
+        self.r_tuple = rtyper.getrepr(self.s_tuple)
+        self.lowleveltype = self.r_tuple.lowleveltype
+
+    def redispatch_getfield(self, hop, index):
+        rtyper = self.rtyper
+        s_index = rtyper.annotator.bookkeeper.immutablevalue(index)
+        hop2 = hop.copy()
+        spaceop = op.getitem(hop.args_v[0], Constant(index))
+        spaceop.result = hop.spaceop.result
+        hop2.spaceop = spaceop
+        hop2.args_v = spaceop.args
+        hop2.args_s = [self.s_tuple, s_index]
+        hop2.args_r = [self.r_tuple, rtyper.getrepr(s_index)]
+        return hop2.dispatch()
+
+    def rtype_getattr(self, hop):
+        s_attr = hop.args_s[1]
+        attr = s_attr.const
+        try:
+            index = self.statvfs_field_indexes[attr]
+        except KeyError:
+            raise TyperError("os.statvfs().%s: field not available" % (attr,))
+        return self.redispatch_getfield(hop, index)
+
+
+class __extend__(pairtype(StatvfsResultRepr, IntegerRepr)):
+    def rtype_getitem((r_sta, r_int), hop):
+        s_int = hop.args_s[1]
+        index = s_int.const
+        return r_sta.redispatch_getfield(hop, index)
+
+
+def specialize_make_statvfs_result(hop):
+    r_StatvfsResult = hop.rtyper.getrepr(rposix_stat.s_StatvfsResult)
+    [v_result] = hop.inputargs(r_StatvfsResult.r_tuple)
+    hop.exception_cannot_occur()
+    return v_result
diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py
--- a/rpython/rlib/objectmodel.py
+++ b/rpython/rlib/objectmodel.py
@@ -290,6 +290,20 @@
 def sc_we_are_translated(ctx):
     return Constant(True)
 
+def register_replacement_for(replaced_function, sandboxed_name=None):
+    def wrap(func):
+        from rpython.rtyper.extregistry import ExtRegistryEntry
+        class ExtRegistry(ExtRegistryEntry):
+            _about_ = replaced_function
+            def compute_annotation(self):
+                if sandboxed_name:
+                    config = self.bookkeeper.annotator.translator.config
+                    if config.translation.sandbox:
+                        func._sandbox_external_name = sandboxed_name
+                        func._dont_inline_ = True
+                return self.bookkeeper.immutablevalue(func)
+        return func
+    return wrap
 
 def keepalive_until_here(*values):
     pass
diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py
--- a/rpython/rlib/rarithmetic.py
+++ b/rpython/rlib/rarithmetic.py
@@ -534,7 +534,7 @@
 else:
     r_int64 = int
 
-# needed for ll_os_stat.time_t_to_FILE_TIME in the 64 bit case
+# needed for rposix_stat.time_t_to_FILE_TIME in the 64 bit case
 r_uint32 = build_int('r_uint32', False, 32)
 
 SHRT_MIN = -2**(_get_bitsize('h') - 1)
diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -173,7 +173,6 @@
 
 def create_fdopen_rfile(fd, mode="r", buffering=-1):
     newmode = _sanitize_mode(mode)
-    fd = rffi.cast(rffi.INT, fd)
     rposix.validate_fd(fd)
     ll_mode = rffi.str2charp(newmode)
     try:
diff --git a/rpython/rlib/rpath.py b/rpython/rlib/rpath.py
--- a/rpython/rlib/rpath.py
+++ b/rpython/rlib/rpath.py
@@ -146,7 +146,7 @@
     try:
         if path == '':
             path = os.getcwd()
-        return rposix._getfullpathname(path)
+        return rposix.getfullpathname(path)
     except OSError:
         return path
 
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -1,15 +1,28 @@
 import os
+import sys
+import errno
 from rpython.rtyper.lltypesystem.rffi import CConstant, CExternVariable, INT
+from rpython.rtyper.lltypesystem import lltype, ll2ctypes, rffi
+from rpython.rtyper.module.support import StringTraits, UnicodeTraits
 from rpython.rtyper.tool import rffi_platform
-from rpython.rtyper.lltypesystem import ll2ctypes, rffi
+from rpython.tool.sourcetools import func_renamer
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
-from rpython.rlib.rarithmetic import intmask
-from rpython.rlib.objectmodel import specialize
+from rpython.rlib.rarithmetic import intmask, widen
+from rpython.rlib.objectmodel import (
+    specialize, enforceargs, register_replacement_for)
 from rpython.rlib import jit
 from rpython.translator.platform import platform
+from rpython.rlib import rstring
+from rpython.rlib import debug, rthread
 
-WIN32 = os.name == "nt"
+_WIN32 = sys.platform.startswith('win')
+_CYGWIN = sys.platform == 'cygwin'
+UNDERSCORE_ON_WIN32 = '_' if _WIN32 else ''
+_MACRO_ON_POSIX = True if not _WIN32 else None
 
+if _WIN32:
+    from rpython.rlib import rwin32 
+    from rpython.rlib.rwin32file import make_win32_traits
 
 class CConfig:
     _compilation_info_ = ExternalCompilationInfo(
@@ -162,7 +175,7 @@
             _set_errno(rthread.tlfield_rpy_errno.getraw())
     elif save_err & rffi.RFFI_ZERO_ERRNO_BEFORE:
         _set_errno(rffi.cast(rffi.INT, 0))
-    if WIN32 and (save_err & rffi.RFFI_READSAVED_LASTERROR):
+    if _WIN32 and (save_err & rffi.RFFI_READSAVED_LASTERROR):
         from rpython.rlib import rthread, rwin32
         if save_err & rffi.RFFI_ALT_ERRNO:
             err = rthread.tlfield_alt_lasterror.getraw()
@@ -175,7 +188,7 @@
 
 @specialize.call_location()
 def _errno_after(save_err):
-    if WIN32:
+    if _WIN32:
         if save_err & rffi.RFFI_SAVE_LASTERROR:
             from rpython.rlib import rthread, rwin32
             err = rwin32._GetLastError()
@@ -205,6 +218,7 @@
         "_PyVerify_fd", [rffi.INT], rffi.INT,
         compilation_info=errno_eci,
         ))
+    @enforceargs(int)
     def validate_fd(fd):
         if not is_valid_fd(fd):
             from errno import EBADF
@@ -213,6 +227,7 @@
     def is_valid_fd(fd):
         return 1
 
+    @enforceargs(int)
     def validate_fd(fd):
         pass
 
@@ -225,6 +240,68 @@
         except OSError:
             pass
 
+if _WIN32:
+    includes = ['io.h', 'sys/utime.h', 'sys/types.h']
+    libraries = []
+else:
+    includes = ['unistd.h',  'sys/types.h', 'sys/wait.h',
+                'utime.h', 'sys/time.h', 'sys/times.h',
+                'grp.h', 'dirent.h']
+    libraries = ['util']
+eci = ExternalCompilationInfo(
+    includes=includes,
+    libraries=libraries,
+)
+
+class CConfig:
+    _compilation_info_ = eci
+    SEEK_SET = rffi_platform.DefinedConstantInteger('SEEK_SET')
+    SEEK_CUR = rffi_platform.DefinedConstantInteger('SEEK_CUR')
+    SEEK_END = rffi_platform.DefinedConstantInteger('SEEK_END')
+    OFF_T_SIZE = rffi_platform.SizeOf('off_t')
+
+    HAVE_UTIMES = rffi_platform.Has('utimes')
+    UTIMBUF = rffi_platform.Struct('struct %sutimbuf' % UNDERSCORE_ON_WIN32,
+                                   [('actime', rffi.INT),
+                                    ('modtime', rffi.INT)])
+    if not _WIN32:
+        CLOCK_T = rffi_platform.SimpleType('clock_t', rffi.INT)
+
+        TMS = rffi_platform.Struct(
+            'struct tms', [('tms_utime', rffi.INT),
+                           ('tms_stime', rffi.INT),
+                           ('tms_cutime', rffi.INT),
+                           ('tms_cstime', rffi.INT)])
+
+    GETPGRP_HAVE_ARG = rffi_platform.Has("getpgrp(0)")
+    SETPGRP_HAVE_ARG = rffi_platform.Has("setpgrp(0, 0)")
+
+config = rffi_platform.configure(CConfig)
+globals().update(config)
+
+def external(name, args, result, compilation_info=eci, **kwds):
+    return rffi.llexternal(name, args, result,
+                           compilation_info=compilation_info, **kwds)
+
+# For now we require off_t to be the same size as LONGLONG, which is the
+# interface required by callers of functions that thake an argument of type
+# off_t.
+if not _WIN32:
+    assert OFF_T_SIZE == rffi.sizeof(rffi.LONGLONG)
+
+c_dup = external(UNDERSCORE_ON_WIN32 + 'dup', [rffi.INT], rffi.INT,
+                 save_err=rffi.RFFI_SAVE_ERRNO)
+c_dup2 = external(UNDERSCORE_ON_WIN32 + 'dup2', [rffi.INT, rffi.INT], rffi.INT,
+                  save_err=rffi.RFFI_SAVE_ERRNO)
+c_open = external(UNDERSCORE_ON_WIN32 + 'open',
+                  [rffi.CCHARP, rffi.INT, rffi.MODE_T], rffi.INT,
+                  save_err=rffi.RFFI_SAVE_ERRNO)
+
+# Win32 Unicode functions
+c_wopen = external(UNDERSCORE_ON_WIN32 + 'wopen',
+                   [rffi.CWCHARP, rffi.INT, rffi.MODE_T], rffi.INT,
+                   save_err=rffi.RFFI_SAVE_ERRNO)
+
 #___________________________________________________________________
 # Wrappers around posix functions, that accept either strings, or
 # instances with a "as_bytes()" method.
@@ -237,26 +314,63 @@
     assert path is not None
     if isinstance(path, str):
         return path
+    elif isinstance(path, unicode):
+        # This never happens in PyPy's Python interpreter!
+        # Only in raw RPython code that uses unicode strings.
+        # We implement python2 behavior: silently convert to ascii.
+        return path.encode('ascii')
     else:
         return path.as_bytes()
 
 @specialize.argtype(0)
-def open(path, flags, mode):
-    return os.open(_as_bytes(path), flags, mode)
+def _as_bytes0(path):
+    """Crashes translation if the path contains NUL characters."""
+    res = _as_bytes(path)
+    rstring.check_str0(res)
+    return res
 
 @specialize.argtype(0)
-def stat(path):
-    return os.stat(_as_bytes(path))
+def _as_unicode(path):
+    assert path is not None
+    if isinstance(path, unicode):
+        return path
+    else:
+        return path.as_unicode()
 
 @specialize.argtype(0)
-def lstat(path):
-    return os.lstat(_as_bytes(path))
+def _as_unicode0(path):
+    """Crashes translation if the path contains NUL characters."""
+    res = _as_unicode(path)
+    rstring.check_str0(res)
+    return res
 
+# Returns True when the unicode function should be called:
+# - on Windows
+# - if the path is Unicode.
+unicode_traits = UnicodeTraits()
+string_traits = StringTraits()
+if _WIN32:
+    @specialize.argtype(0)
+    def _prefer_unicode(path):
+        if isinstance(path, str):
+            return False
+        elif isinstance(path, unicode):
+            return True
+        else:
+            return path.is_unicode
 
[email protected](0)
-def statvfs(path):
-    return os.statvfs(_as_bytes(path))
+    @specialize.argtype(0)
+    def _preferred_traits(path):
+        if _prefer_unicode(path):
+            return unicode_traits
+        else:
+            return string_traits
+else:
+    @specialize.argtype(0)
+    def _prefer_unicode(path):
+        return False
 
+<<<<<<< local
 
 @specialize.argtype(0)
 def unlink(path):
@@ -315,10 +429,12 @@
 
 if os.name == 'nt':
     import nt
+=======
+>>>>>>> other
     @specialize.argtype(0)
-    def _getfullpathname(path):
-        return nt._getfullpathname(_as_bytes(path))
-
+    def _preferred_traits(path):
+        return string_traits
+    
 @specialize.argtype(0, 1)
 def putenv(name, value):
     os.environ[_as_bytes(name)] = _as_bytes(value)
@@ -327,8 +443,1355 @@
 def unsetenv(name):
     del os.environ[_as_bytes(name)]
 
-if os.name == 'nt':
+#___________________________________________________________________
+# Implementation of many posix functions.
+# They usually check the return value and raise an (RPython) OSError
+# with errno.
+
+def replace_os_function(name):
+    func = getattr(os, name, None)
+    if func is None:
+        return lambda f: f
+    return register_replacement_for(
+        func,
+        sandboxed_name='ll_os.ll_os_%s' % name)
+
[email protected](0)
+def handle_posix_error(name, result):
+    result = widen(result)
+    if result < 0:
+        raise OSError(get_saved_errno(), '%s failed' % name)
+    return result
+
+@replace_os_function('dup')
+def dup(fd):
+    validate_fd(fd)
+    return handle_posix_error('dup', c_dup(fd))
+
+@replace_os_function('dup2')
+def dup2(fd, newfd):
+    validate_fd(fd)
+    handle_posix_error('dup2', c_dup2(fd, newfd))
+
+#___________________________________________________________________
+
+@replace_os_function('open')
[email protected](0)
+def open(path, flags, mode):
+    if _prefer_unicode(path):
+        fd = c_wopen(_as_unicode0(path), flags, mode)
+    else:
+        fd = c_open(_as_bytes0(path), flags, mode)
+    return handle_posix_error('open', fd)
+
+c_read = external(UNDERSCORE_ON_WIN32 + 'read',
+                  [rffi.INT, rffi.VOIDP, rffi.SIZE_T], rffi.SSIZE_T,
+                  save_err=rffi.RFFI_SAVE_ERRNO)
+c_write = external(UNDERSCORE_ON_WIN32 + 'write',
+                   [rffi.INT, rffi.VOIDP, rffi.SIZE_T], rffi.SSIZE_T,
+                   save_err=rffi.RFFI_SAVE_ERRNO)
+c_close = external(UNDERSCORE_ON_WIN32 + 'close', [rffi.INT], rffi.INT,
+                   releasegil=False, save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('read')
+@enforceargs(int, int)
+def read(fd, count):
+    if count < 0:
+        raise OSError(errno.EINVAL, None)
+    validate_fd(fd)
+    with rffi.scoped_alloc_buffer(count) as buf:
+        void_buf = rffi.cast(rffi.VOIDP, buf.raw)
+        got = handle_posix_error('read', c_read(fd, void_buf, count))
+        return buf.str(got)
+
+@replace_os_function('write')
+@enforceargs(int, None)
+def write(fd, data):
+    count = len(data)
+    validate_fd(fd)
+    with rffi.scoped_nonmovingbuffer(data) as buf:
+        return handle_posix_error('write', c_write(fd, buf, count))
+
+@replace_os_function('close')
+def close(fd):
+    validate_fd(fd)
+    handle_posix_error('close', c_close(fd))
+
+c_lseek = external('_lseeki64' if _WIN32 else 'lseek',
+                   [rffi.INT, rffi.LONGLONG, rffi.INT], rffi.LONGLONG,
+                   macro=_MACRO_ON_POSIX, save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('lseek')
+def lseek(fd, pos, how):
+    validate_fd(fd)
+    if SEEK_SET is not None:
+        if how == 0:
+            how = SEEK_SET
+        elif how == 1: 
+            how = SEEK_CUR
+        elif how == 2:
+            how = SEEK_END
+    return handle_posix_error('lseek', c_lseek(fd, pos, how))
+
+c_ftruncate = external('ftruncate', [rffi.INT, rffi.LONGLONG], rffi.INT,
+                       macro=_MACRO_ON_POSIX, save_err=rffi.RFFI_SAVE_ERRNO)
+c_fsync = external('fsync' if not _WIN32 else '_commit', [rffi.INT], rffi.INT,
+                   save_err=rffi.RFFI_SAVE_ERRNO)
+c_fdatasync = external('fdatasync', [rffi.INT], rffi.INT,
+                       save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('ftruncate')
+def ftruncate(fd, length):
+    validate_fd(fd)
+    handle_posix_error('ftruncate', c_ftruncate(fd, length))
+
+@replace_os_function('fsync')
+def fsync(fd):
+    validate_fd(fd)
+    handle_posix_error('fsync', c_fsync(fd))
+
+@replace_os_function('fdatasync')
+def fdatasync(fd):
+    validate_fd(fd)
+    handle_posix_error('fdatasync', c_fdatasync(fd))
+
+#___________________________________________________________________
+
+c_chdir = external('chdir', [rffi.CCHARP], rffi.INT,
+                   save_err=rffi.RFFI_SAVE_ERRNO)
+c_fchdir = external('fchdir', [rffi.INT], rffi.INT,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+c_access = external(UNDERSCORE_ON_WIN32 + 'access',
+                    [rffi.CCHARP, rffi.INT], rffi.INT)
+c_waccess = external(UNDERSCORE_ON_WIN32 + 'waccess',
+                     [rffi.CWCHARP, rffi.INT], rffi.INT)
+
+@replace_os_function('chdir')
[email protected](0)
+def chdir(path):
+    if not _WIN32:
+        handle_posix_error('chdir', c_chdir(_as_bytes0(path)))
+    else:
+        traits = _preferred_traits(path)
+        win32traits = make_win32_traits(traits)
+        path = traits.as_str0(path)
+
+        # This is a reimplementation of the C library's chdir
+        # function, but one that produces Win32 errors instead of DOS
+        # error codes.
+        # chdir is essentially a wrapper around SetCurrentDirectory;
+        # however, it also needs to set "magic" environment variables
+        # indicating the per-drive current directory, which are of the
+        # form =<drive>:
+        if not win32traits.SetCurrentDirectory(path):
+            raise rwin32.lastSavedWindowsError()
+        MAX_PATH = rwin32.MAX_PATH
+        assert MAX_PATH > 0
+
+        with traits.scoped_alloc_buffer(MAX_PATH) as path:
+            res = win32traits.GetCurrentDirectory(MAX_PATH + 1, path.raw)
+            if not res:
+                raise rwin32.lastSavedWindowsError()
+            res = rffi.cast(lltype.Signed, res)
+            assert res > 0
+            if res <= MAX_PATH + 1:
+                new_path = path.str(res)
+            else:
+                with traits.scoped_alloc_buffer(res) as path:
+                    res = win32traits.GetCurrentDirectory(res, path.raw)
+                    if not res:
+                        raise rwin32.lastSavedWindowsError()
+                    res = rffi.cast(lltype.Signed, res)
+                    assert res > 0
+                    new_path = path.str(res)
+        if traits.str is unicode:
+            if new_path[0] == u'\\' or new_path[0] == u'/':  # UNC path
+                return
+            magic_envvar = u'=' + new_path[0] + u':'
+        else:
+            if new_path[0] == '\\' or new_path[0] == '/':  # UNC path
+                return
+            magic_envvar = '=' + new_path[0] + ':'
+        if not win32traits.SetEnvironmentVariable(magic_envvar, new_path):
+            raise rwin32.lastSavedWindowsError()
+
+@replace_os_function('fchdir')
+def fchdir(fd):
+    validate_fd(fd)
+    handle_posix_error('fchdir', c_fchdir(fd))
+
+@replace_os_function('access')
[email protected](0)
+def access(path, mode):
+    if _WIN32:
+        # All files are executable on Windows
+        mode = mode & ~os.X_OK
+    if _prefer_unicode(path):
+        error = c_waccess(_as_unicode0(path), mode)
+    else:
+        error = c_access(_as_bytes0(path), mode)
+    return error == 0
+
+# This Win32 function is not exposed via os, but needed to get a
+# correct implementation of os.path.abspath.
[email protected](0)
+def getfullpathname(path):
+    length = rwin32.MAX_PATH + 1
+    traits = _preferred_traits(path)
+    win32traits = make_win32_traits(traits)
+    with traits.scoped_alloc_buffer(length) as buf:
+        res = win32traits.GetFullPathName(
+            traits.as_str0(path), rffi.cast(rwin32.DWORD, length),
+            buf.raw, lltype.nullptr(win32traits.LPSTRP.TO))
+        if res == 0:
+            raise rwin32.lastSavedWindowsError("_getfullpathname failed")
+        return buf.str(intmask(res))
+
+c_getcwd = external(UNDERSCORE_ON_WIN32 + 'getcwd',
+                    [rffi.CCHARP, rffi.SIZE_T], rffi.CCHARP,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+c_wgetcwd = external(UNDERSCORE_ON_WIN32 + 'wgetcwd',
+                     [rffi.CWCHARP, rffi.SIZE_T], rffi.CWCHARP,
+                     save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('getcwd')
+def getcwd():
+    bufsize = 256
+    while True:
+        buf = lltype.malloc(rffi.CCHARP.TO, bufsize, flavor='raw')
+        res = c_getcwd(buf, bufsize)
+        if res:
+            break   # ok
+        error = get_saved_errno()
+        lltype.free(buf, flavor='raw')
+        if error != errno.ERANGE:
+            raise OSError(error, "getcwd failed")
+        # else try again with a larger buffer, up to some sane limit
+        bufsize *= 4
+        if bufsize > 1024*1024:  # xxx hard-coded upper limit
+            raise OSError(error, "getcwd result too large")
+    result = rffi.charp2str(res)
+    lltype.free(buf, flavor='raw')
+    return result
+
+@replace_os_function('getcwdu')
+def getcwdu():
+    bufsize = 256
+    while True:
+        buf = lltype.malloc(rffi.CWCHARP.TO, bufsize, flavor='raw')
+        res = c_wgetcwd(buf, bufsize)
+        if res:
+            break   # ok
+        error = get_saved_errno()
+        lltype.free(buf, flavor='raw')
+        if error != errno.ERANGE:
+            raise OSError(error, "getcwd failed")
+        # else try again with a larger buffer, up to some sane limit
+        bufsize *= 4
+        if bufsize > 1024*1024:  # xxx hard-coded upper limit
+            raise OSError(error, "getcwd result too large")
+    result = rffi.wcharp2unicode(res)
+    lltype.free(buf, flavor='raw')
+    return result
+
+if not _WIN32:
+    class CConfig:
+        _compilation_info_ = eci
+        DIRENT = rffi_platform.Struct('struct dirent',
+            [('d_name', lltype.FixedSizeArray(rffi.CHAR, 1))])
+
+    DIRP = rffi.COpaquePtr('DIR')
+    config = rffi_platform.configure(CConfig)
+    DIRENT = config['DIRENT']
+    DIRENTP = lltype.Ptr(DIRENT)
+    c_opendir = external('opendir', [rffi.CCHARP], DIRP,
+                         save_err=rffi.RFFI_SAVE_ERRNO)
+    # XXX macro=True is hack to make sure we get the correct kind of
+    # dirent struct (which depends on defines)
+    c_readdir = external('readdir', [DIRP], DIRENTP,
+                         macro=True, save_err=rffi.RFFI_FULL_ERRNO_ZERO)
+    c_closedir = external('closedir', [DIRP], rffi.INT)
+
+@replace_os_function('listdir')
[email protected](0)
+def listdir(path):
+    if not _WIN32:
+        path = _as_bytes0(path)
+        dirp = c_opendir(path)
+        if not dirp:
+            raise OSError(get_saved_errno(), "opendir failed")
+        result = []
+        while True:
+            direntp = c_readdir(dirp)
+            if not direntp:
+                error = get_saved_errno()
+                break
+            namep = rffi.cast(rffi.CCHARP, direntp.c_d_name)
+            name = rffi.charp2str(namep)
+            if name != '.' and name != '..':
+                result.append(name)
+        c_closedir(dirp)
+        if error:
+            raise OSError(error, "readdir failed")
+        return result
+    else:  # _WIN32 case
+        traits = _preferred_traits(path)
+        win32traits = make_win32_traits(traits)
+        path = traits.as_str0(path)
+
+        if traits.str is unicode:
+            if path and path[-1] not in (u'/', u'\\', u':'):
+                path += u'/'
+            mask = path + u'*.*'
+        else:
+            if path and path[-1] not in ('/', '\\', ':'):
+                path += '/'
+            mask = path + '*.*'
+
+        filedata = lltype.malloc(win32traits.WIN32_FIND_DATA, flavor='raw')
+        try:
+            result = []
+            hFindFile = win32traits.FindFirstFile(mask, filedata)
+            if hFindFile == rwin32.INVALID_HANDLE_VALUE:
+                error = rwin32.GetLastError_saved()
+                if error == win32traits.ERROR_FILE_NOT_FOUND:
+                    return result
+                else:
+                    raise WindowsError(error,  "FindFirstFile failed")
+            while True:
+                name = traits.charp2str(rffi.cast(traits.CCHARP,
+                                                  filedata.c_cFileName))
+                if traits.str is unicode:
+                    if not (name == u"." or name == u".."):
+                        result.append(name)
+                else:
+                    if not (name == "." or name == ".."):
+                        result.append(name)
+                if not win32traits.FindNextFile(hFindFile, filedata):
+                    break
+            # FindNextFile sets error to ERROR_NO_MORE_FILES if
+            # it got to the end of the directory
+            error = rwin32.GetLastError_saved()
+            win32traits.FindClose(hFindFile)
+            if error == win32traits.ERROR_NO_MORE_FILES:
+                return result
+            else:
+                raise WindowsError(error,  "FindNextFile failed")
+        finally:
+            lltype.free(filedata, flavor='raw')
+
+#___________________________________________________________________
+
+c_execv = external('execv', [rffi.CCHARP, rffi.CCHARPP], rffi.INT,
+                   save_err=rffi.RFFI_SAVE_ERRNO)
+c_execve = external('execve',
+                    [rffi.CCHARP, rffi.CCHARPP, rffi.CCHARPP], rffi.INT,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+c_spawnv = external('spawnv',
+                    [rffi.INT, rffi.CCHARP, rffi.CCHARPP], rffi.INT,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+c_spawnve = external('spawnve',
+                    [rffi.INT, rffi.CCHARP, rffi.CCHARPP, rffi.CCHARPP],
+                     rffi.INT,
+                     save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('execv')
+def execv(path, args):
+    rstring.check_str0(path)
+    # This list conversion already takes care of NUL bytes.
+    l_args = rffi.ll_liststr2charpp(args)
+    c_execv(path, l_args)
+    rffi.free_charpp(l_args)
+    raise OSError(get_saved_errno(), "execv failed")
+
+@replace_os_function('execve')
+def execve(path, args, env):
+    envstrs = []
+    for item in env.iteritems():
+        envstr = "%s=%s" % item
+        envstrs.append(envstr)
+
+    rstring.check_str0(path)
+    # This list conversion already takes care of NUL bytes.
+    l_args = rffi.ll_liststr2charpp(args)
+    l_env = rffi.ll_liststr2charpp(envstrs)
+    c_execve(path, l_args, l_env)
+
+    rffi.free_charpp(l_env)
+    rffi.free_charpp(l_args)
+    raise OSError(get_saved_errno(), "execve failed")
+
+@replace_os_function('spawnv')
+def spawnv(mode, path, args):
+    rstring.check_str0(path)
+    l_args = rffi.ll_liststr2charpp(args)
+    childpid = c_spawnv(mode, path, l_args)
+    rffi.free_charpp(l_args)
+    return handle_posix_error('spawnv', childpid)
+
+@replace_os_function('spawnve')
+def spawnve(mode, path, args, env):
+    envstrs = []
+    for item in env.iteritems():
+        envstrs.append("%s=%s" % item)
+    rstring.check_str0(path)
+    l_args = rffi.ll_liststr2charpp(args)
+    l_env = rffi.ll_liststr2charpp(envstrs)
+    childpid = c_spawnve(mode, path, l_args, l_env)
+    rffi.free_charpp(l_env)
+    rffi.free_charpp(l_args)
+    return handle_posix_error('spawnve', childpid)
+
+c_fork = external('fork', [], rffi.PID_T, _nowrapper = True)
+c_openpty = external('openpty',
+                     [rffi.INTP, rffi.INTP, rffi.VOIDP, rffi.VOIDP, 
rffi.VOIDP],
+                     rffi.INT,
+                     save_err=rffi.RFFI_SAVE_ERRNO)
+c_forkpty = external('forkpty',
+                     [rffi.INTP, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP],
+                     rffi.PID_T,
+                     save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('fork')
[email protected]_look_inside
+def fork():
+    # NB. keep forkpty() up-to-date, too
+    ofs = debug.debug_offset()
+    opaqueaddr = rthread.gc_thread_before_fork()
+    childpid = c_fork()
+    rthread.gc_thread_after_fork(childpid, opaqueaddr)
+    childpid = handle_posix_error('fork', childpid)
+    if childpid == 0:
+        debug.debug_forked(ofs)
+    return childpid
+
+@replace_os_function('openpty')
+def openpty():
+    master_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+    slave_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+    try:
+        handle_posix_error(
+            'openpty', c_openpty(master_p, slave_p, None, None, None))
+        return (widen(master_p[0]), widen(slave_p[0]))
+    finally:
+        lltype.free(master_p, flavor='raw')
+        lltype.free(slave_p, flavor='raw')
+
+@replace_os_function('forkpty')
[email protected]_look_inside
+def forkpty():
+    master_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+    master_p[0] = rffi.cast(rffi.INT, -1)
+    try:
+        ofs = debug.debug_offset()
+        opaqueaddr = rthread.gc_thread_before_fork()
+        childpid = c_forkpty(master_p, None, None, None)
+        rthread.gc_thread_after_fork(childpid, opaqueaddr)
+        childpid = handle_posix_error('forkpty', childpid)
+        if childpid == 0:
+            debug.debug_forked(ofs)
+        return (childpid, master_p[0])
+    finally:
+        lltype.free(master_p, flavor='raw')
+
+if _WIN32:
+    # emulate waitpid() with the _cwait() of Microsoft's compiler
+    c__cwait = external('_cwait',
+                        [rffi.INTP, rffi.PID_T, rffi.INT], rffi.PID_T,
+                        save_err=rffi.RFFI_SAVE_ERRNO)
+    def c_waitpid(pid, status_p, options):
+        result = c__cwait(status_p, pid, options)
+        # shift the status left a byte so this is more
+        # like the POSIX waitpid
+        status_p[0] = rffi.cast(rffi.INT, widen(status_p[0]) << 8)
+        return result
+elif _CYGWIN:
+    c_waitpid = external('cygwin_waitpid',
+                         [rffi.PID_T, rffi.INTP, rffi.INT], rffi.PID_T,
+                         save_err=rffi.RFFI_SAVE_ERRNO)
+else:
+    c_waitpid = external('waitpid',
+                         [rffi.PID_T, rffi.INTP, rffi.INT], rffi.PID_T,
+                         save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('waitpid')
+def waitpid(pid, options):
+    status_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+    status_p[0] = rffi.cast(rffi.INT, 0)
+    try:
+        result = handle_posix_error('waitpid',
+                                    c_waitpid(pid, status_p, options))
+        status = widen(status_p[0])
+        return (result, status)
+    finally:
+        lltype.free(status_p, flavor='raw')
+
+def _make_waitmacro(name):
+    c_func = external(name, [lltype.Signed], lltype.Signed,
+                      macro=_MACRO_ON_POSIX)
+    returning_int = name in ('WEXITSTATUS', 'WSTOPSIG', 'WTERMSIG')
+
+    @replace_os_function(name)
+    @func_renamer(name)
+    def _waitmacro(status):
+        if returning_int:
+            return c_func(status)
+        else:
+            return bool(c_func(status))
+
+WAIT_MACROS = ['WCOREDUMP', 'WIFCONTINUED', 'WIFSTOPPED',
+               'WIFSIGNALED', 'WIFEXITED',
+               'WEXITSTATUS', 'WSTOPSIG', 'WTERMSIG']
+for name in WAIT_MACROS:
+    _make_waitmacro(name)
+
+#___________________________________________________________________
+
+c_getlogin = external('getlogin', [], rffi.CCHARP,
+                      releasegil=False, save_err=rffi.RFFI_SAVE_ERRNO)
+c_getloadavg = external('getloadavg', 
+                        [rffi.CArrayPtr(lltype.Float), rffi.INT], rffi.INT)
+
+@replace_os_function('getlogin')
+def getlogin():
+    result = c_getlogin()
+    if not result:
+        raise OSError(get_saved_errno(), "getlogin failed")
+    return rffi.charp2str(result)
+
+@replace_os_function('getloadavg')
+def getloadavg():
+    load = lltype.malloc(rffi.CArrayPtr(lltype.Float).TO, 3, flavor='raw')
+    try:
+        r = c_getloadavg(load, 3)
+        if r != 3:
+            raise OSError
+        return (load[0], load[1], load[2])
+    finally:
+        lltype.free(load, flavor='raw')
+
+#___________________________________________________________________
+
+c_readlink = external('readlink',
+                      [rffi.CCHARP, rffi.CCHARP, rffi.SIZE_T], rffi.SSIZE_T,
+                      save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('readlink')
+def readlink(path):
+    path = _as_bytes0(path)
+    bufsize = 1023
+    while True:
+        buf = lltype.malloc(rffi.CCHARP.TO, bufsize, flavor='raw')
+        res = widen(c_readlink(path, buf, bufsize))
+        if res < 0:
+            lltype.free(buf, flavor='raw')
+            error = get_saved_errno()    # failed
+            raise OSError(error, "readlink failed")
+        elif res < bufsize:
+            break                       # ok
+        else:
+            # buf too small, try again with a larger buffer
+            lltype.free(buf, flavor='raw')
+            bufsize *= 4
+    # convert the result to a string
+    result = rffi.charp2strn(buf, res)
+    lltype.free(buf, flavor='raw')
+    return result
+
+c_isatty = external(UNDERSCORE_ON_WIN32 + 'isatty', [rffi.INT], rffi.INT)
+
+@replace_os_function('isatty')
+def isatty(fd):
+    if not is_valid_fd(fd):
+        return False
+    return c_isatty(fd) != 0
+
+c_ttyname = external('ttyname', [lltype.Signed], rffi.CCHARP,
+                     releasegil=False,
+                     save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('ttyname')
+def ttyname(fd):
+    l_name = c_ttyname(fd)
+    if not l_name:
+        raise OSError(get_saved_errno(), "ttyname raised")
+    return rffi.charp2str(l_name)
+
+c_strerror = external('strerror', [rffi.INT], rffi.CCHARP,
+                      releasegil=False)
+
+@replace_os_function('strerror')
+def strerror(errnum):
+    res = c_strerror(errnum)
+    if not res:
+        raise ValueError("os_strerror failed")
+    return rffi.charp2str(res)
+
+c_system = external('system', [rffi.CCHARP], rffi.INT)
+
+@replace_os_function('system')
+def system(command):
+    return widen(c_system(command))
+
+c_unlink = external('unlink', [rffi.CCHARP], rffi.INT,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+c_mkdir = external('mkdir', [rffi.CCHARP, rffi.MODE_T], rffi.INT,
+                   save_err=rffi.RFFI_SAVE_ERRNO)
+c_rmdir = external(UNDERSCORE_ON_WIN32 + 'rmdir', [rffi.CCHARP], rffi.INT,
+                   save_err=rffi.RFFI_SAVE_ERRNO)
+c_wrmdir = external(UNDERSCORE_ON_WIN32 + 'wrmdir', [rffi.CWCHARP], rffi.INT,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('unlink')
[email protected](0)
+def unlink(path):
+    if not _WIN32:
+        handle_posix_error('unlink', c_unlink(_as_bytes0(path)))
+    else:
+        traits = _preferred_traits(path)
+        win32traits = make_win32_traits(traits)
+        if not win32traits.DeleteFile(traits.as_str0(path)):
+            raise rwin32.lastSavedWindowsError()
+
+@replace_os_function('mkdir')
[email protected](0)
+def mkdir(path, mode=0o777):
+    if not _WIN32:
+        handle_posix_error('mkdir', c_mkdir(_as_bytes0(path), mode))
+    else:
+        traits = _preferred_traits(path)
+        win32traits = make_win32_traits(traits)
+        if not win32traits.CreateDirectory(traits.as_str0(path), None):
+            raise rwin32.lastSavedWindowsError()
+
+@replace_os_function('rmdir')
[email protected](0)
+def rmdir(path):
+    if _prefer_unicode(path):
+        handle_posix_error('wrmdir', c_wrmdir(_as_unicode0(path)))
+    else:
+        handle_posix_error('rmdir', c_rmdir(_as_bytes0(path)))
+
+c_chmod = external('chmod', [rffi.CCHARP, rffi.MODE_T], rffi.INT,
+                   save_err=rffi.RFFI_SAVE_ERRNO)
+c_fchmod = external('fchmod', [rffi.INT, rffi.MODE_T], rffi.INT,
+                    save_err=rffi.RFFI_SAVE_ERRNO,)
+c_rename = external('rename', [rffi.CCHARP, rffi.CCHARP], rffi.INT,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('chmod')
[email protected](0)
+def chmod(path, mode):
+    if not _WIN32:
+        handle_posix_error('chmod', c_chmod(_as_bytes0(path), mode))
+    else:
+        traits = _preferred_traits(path)
+        win32traits = make_win32_traits(traits)
+        path = traits.as_str0(path)
+        attr = win32traits.GetFileAttributes(path)
+        if attr == win32traits.INVALID_FILE_ATTRIBUTES:
+            raise rwin32.lastSavedWindowsError()
+        if mode & 0200: # _S_IWRITE
+            attr &= ~win32traits.FILE_ATTRIBUTE_READONLY
+        else:
+            attr |= win32traits.FILE_ATTRIBUTE_READONLY
+        if not win32traits.SetFileAttributes(path, attr):
+            raise rwin32.lastSavedWindowsError()
+
+@replace_os_function('fchmod')
+def fchmod(fd, mode):
+    handle_posix_error('fchmod', c_fchmod(fd, mode))
+
+@replace_os_function('rename')
[email protected](0, 1)
+def rename(path1, path2):
+    if not _WIN32:
+        handle_posix_error('rename',
+                           c_rename(_as_bytes0(path1), _as_bytes0(path2)))
+    else:
+        traits = _preferred_traits(path1)
+        win32traits = make_win32_traits(traits)
+        path1 = traits.as_str0(path1)
+        path2 = traits.as_str0(path2)
+        if not win32traits.MoveFile(path1, path2):
+            raise rwin32.lastSavedWindowsError()
+
+#___________________________________________________________________
+
+c_mkfifo = external('mkfifo', [rffi.CCHARP, rffi.MODE_T], rffi.INT,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+c_mknod = external('mknod', [rffi.CCHARP, rffi.MODE_T, rffi.INT], rffi.INT,
+#                                           # xxx: actually ^^^ dev_t
+                   macro=_MACRO_ON_POSIX, save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('mkfifo')
[email protected](0)
+def mkfifo(path, mode):
+    handle_posix_error('mkfifo', c_mkfifo(_as_bytes0(path), mode))
+
+@replace_os_function('mknod')
[email protected](0)
+def mknod(path, mode, dev):
+    handle_posix_error('mknod', c_mknod(_as_bytes0(path), mode, dev))
+
+if _WIN32:
+    CreatePipe = external('CreatePipe', [rwin32.LPHANDLE,
+                                         rwin32.LPHANDLE,
+                                         rffi.VOIDP,
+                                         rwin32.DWORD],
+                          rwin32.BOOL)
+    c_open_osfhandle = external('_open_osfhandle', [rffi.INTPTR_T,
+                                                    rffi.INT],
+                                rffi.INT)
+else:
+    INT_ARRAY_P = rffi.CArrayPtr(rffi.INT)
+    c_pipe = external('pipe', [INT_ARRAY_P], rffi.INT,
+                      save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('pipe')
+def pipe():
+    if _WIN32:
+        pread  = lltype.malloc(rwin32.LPHANDLE.TO, 1, flavor='raw')
+        pwrite = lltype.malloc(rwin32.LPHANDLE.TO, 1, flavor='raw')
+        try:
+            if not CreatePipe(
+                    pread, pwrite, lltype.nullptr(rffi.VOIDP.TO), 0):
+                raise WindowsError(rwin32.GetLastError_saved(),
+                                   "CreatePipe failed")
+            hread = rffi.cast(rffi.INTPTR_T, pread[0])
+            hwrite = rffi.cast(rffi.INTPTR_T, pwrite[0])
+        finally:
+            lltype.free(pwrite, flavor='raw')
+            lltype.free(pread, flavor='raw')
+        fdread = c_open_osfhandle(hread, 0)
+        fdwrite = c_open_osfhandle(hwrite, 1)
+        return (fdread, fdwrite)
+    else:
+        filedes = lltype.malloc(INT_ARRAY_P.TO, 2, flavor='raw')
+        try:
+            handle_posix_error('pipe', c_pipe(filedes))
+            return (widen(filedes[0]), widen(filedes[1]))
+        finally:
+            lltype.free(filedes, flavor='raw')
+
+c_link = external('link', [rffi.CCHARP, rffi.CCHARP], rffi.INT,
+                  save_err=rffi.RFFI_SAVE_ERRNO,)
+c_symlink = external('symlink', [rffi.CCHARP, rffi.CCHARP], rffi.INT,
+                     save_err=rffi.RFFI_SAVE_ERRNO)
+
+#___________________________________________________________________
+
+@replace_os_function('link')
[email protected](0, 1)
+def link(oldpath, newpath):
+    oldpath = _as_bytes0(oldpath)
+    newpath = _as_bytes0(newpath)
+    handle_posix_error('link', c_link(oldpath, newpath))
+
+@replace_os_function('symlink')
[email protected](0, 1)
+def symlink(oldpath, newpath):
+    oldpath = _as_bytes0(oldpath)
+    newpath = _as_bytes0(newpath)
+    handle_posix_error('symlink', c_symlink(oldpath, newpath))
+
+c_umask = external(UNDERSCORE_ON_WIN32 + 'umask', [rffi.MODE_T], rffi.MODE_T)
+
+@replace_os_function('umask')
+def umask(newmask):
+    return widen(c_umask(newmask))
+
+c_chown = external('chown', [rffi.CCHARP, rffi.INT, rffi.INT], rffi.INT,
+                   save_err=rffi.RFFI_SAVE_ERRNO)
+c_lchown = external('lchown', [rffi.CCHARP, rffi.INT, rffi.INT], rffi.INT,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+c_fchown = external('fchown', [rffi.INT, rffi.INT, rffi.INT], rffi.INT,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('chown')
+def chown(path, uid, gid):
+    handle_posix_error('chown', c_chown(path, uid, gid))
+
+@replace_os_function('lchown')
+def lchown(path, uid, gid):
+    handle_posix_error('lchown', c_lchown(path, uid, gid))
+
+@replace_os_function('fchown')
+def fchown(fd, uid, gid):
+    handle_posix_error('fchown', c_fchown(fd, uid, gid))
+
+#___________________________________________________________________
+
+UTIMBUFP = lltype.Ptr(UTIMBUF)
+c_utime = external('utime', [rffi.CCHARP, UTIMBUFP], rffi.INT,
+                   save_err=rffi.RFFI_SAVE_ERRNO)
+if HAVE_UTIMES:
+    class CConfig:
+        _compilation_info_ = eci
+        TIMEVAL = rffi_platform.Struct('struct timeval', [
+            ('tv_sec', rffi.LONG),
+            ('tv_usec', rffi.LONG)])
+    config = rffi_platform.configure(CConfig)
+    TIMEVAL = config['TIMEVAL']
+    TIMEVAL2P = rffi.CArrayPtr(TIMEVAL)
+    c_utimes = external('utimes', [rffi.CCHARP, TIMEVAL2P], rffi.INT,
+                        save_err=rffi.RFFI_SAVE_ERRNO)
+
+if _WIN32:
     from rpython.rlib import rwin32
-    os_kill = rwin32.os_kill
+    GetSystemTime = external(
+        'GetSystemTime',
+        [lltype.Ptr(rwin32.SYSTEMTIME)],
+        lltype.Void,
+        calling_conv='win',
+        save_err=rffi.RFFI_SAVE_LASTERROR)
+
+    SystemTimeToFileTime = external(
+        'SystemTimeToFileTime',
+        [lltype.Ptr(rwin32.SYSTEMTIME),
+         lltype.Ptr(rwin32.FILETIME)],
+        rwin32.BOOL,
+        calling_conv='win',
+        save_err=rffi.RFFI_SAVE_LASTERROR)
+
+    SetFileTime = external(
+        'SetFileTime',
+        [rwin32.HANDLE,
+         lltype.Ptr(rwin32.FILETIME),
+         lltype.Ptr(rwin32.FILETIME),
+         lltype.Ptr(rwin32.FILETIME)],
+        rwin32.BOOL,
+        calling_conv='win')
+
+
+@replace_os_function('utime')
[email protected](0, 1)
+def utime(path, times):
+    if not _WIN32:
+        path = _as_bytes0(path)
+        if times is None:
+            error = c_utime(path, lltype.nullptr(UTIMBUFP.TO))
+        else:
+            actime, modtime = times
+            if HAVE_UTIMES:
+                import math
+                l_times = lltype.malloc(TIMEVAL2P.TO, 2, flavor='raw')
+                fracpart, intpart = math.modf(actime)
+                rffi.setintfield(l_times[0], 'c_tv_sec', int(intpart))
+                rffi.setintfield(l_times[0], 'c_tv_usec', int(fracpart * 1e6))
+                fracpart, intpart = math.modf(modtime)
+                rffi.setintfield(l_times[1], 'c_tv_sec', int(intpart))
+                rffi.setintfield(l_times[1], 'c_tv_usec', int(fracpart * 1e6))
+                error = c_utimes(path, l_times)
+                lltype.free(l_times, flavor='raw')
+            else:
+                # we only have utime(), which does not allow
+                # sub-second resolution
+                l_utimbuf = lltype.malloc(UTIMBUFP.TO, flavor='raw')
+                l_utimbuf.c_actime  = rffi.r_time_t(actime)
+                l_utimbuf.c_modtime = rffi.r_time_t(modtime)
+                error = c_utime(path, l_utimbuf)
+                lltype.free(l_utimbuf, flavor='raw')
+        handle_posix_error('utime', error)
+    else:  # _WIN32 case
+        from rpython.rlib.rwin32file import time_t_to_FILE_TIME
+        traits = _preferred_traits(path)
+        win32traits = make_win32_traits(traits)
+        path = traits.as_str0(path)
+        hFile = win32traits.CreateFile(path,
+                           win32traits.FILE_WRITE_ATTRIBUTES, 0,
+                           None, win32traits.OPEN_EXISTING,
+                           win32traits.FILE_FLAG_BACKUP_SEMANTICS,
+                           rwin32.NULL_HANDLE)
+        if hFile == rwin32.INVALID_HANDLE_VALUE:
+            raise rwin32.lastSavedWindowsError()
+        ctime = lltype.nullptr(rwin32.FILETIME)
+        atime = lltype.malloc(rwin32.FILETIME, flavor='raw')
+        mtime = lltype.malloc(rwin32.FILETIME, flavor='raw')
+        try:
+            if times is None:
+                now = lltype.malloc(rwin32.SYSTEMTIME, flavor='raw')
+                try:
+                    GetSystemTime(now)
+                    if (not SystemTimeToFileTime(now, atime) or
+                        not SystemTimeToFileTime(now, mtime)):
+                        raise rwin32.lastSavedWindowsError()
+                finally:
+                    lltype.free(now, flavor='raw')
+            else:
+                actime, modtime = times
+                time_t_to_FILE_TIME(actime, atime)
+                time_t_to_FILE_TIME(modtime, mtime)
+            if not SetFileTime(hFile, ctime, atime, mtime):
+                raise rwin32.lastSavedWindowsError()
+        finally:
+            rwin32.CloseHandle(hFile)
+            lltype.free(atime, flavor='raw')
+            lltype.free(mtime, flavor='raw')
+
+if not _WIN32:
+    TMSP = lltype.Ptr(TMS)
+    c_times = external('times', [TMSP], CLOCK_T,
+                        save_err=rffi.RFFI_SAVE_ERRNO)
+
+    # Here is a random extra platform parameter which is important.
+    # Strictly speaking, this should probably be retrieved at runtime, not
+    # at translation time.
+    CLOCK_TICKS_PER_SECOND = float(os.sysconf('SC_CLK_TCK'))
 else:
-    os_kill = os.kill
+    GetCurrentProcess = external(
+        'GetCurrentProcess', [],
+        rwin32.HANDLE, calling_conv='win')
+    GetProcessTimes = external(
+        'GetProcessTimes', [
+            rwin32.HANDLE,
+            lltype.Ptr(rwin32.FILETIME), lltype.Ptr(rwin32.FILETIME),
+            lltype.Ptr(rwin32.FILETIME), lltype.Ptr(rwin32.FILETIME)],
+        rwin32.BOOL, calling_conv='win')
+
+@replace_os_function('times')
+def times():
+    if not _WIN32:
+        l_tmsbuf = lltype.malloc(TMSP.TO, flavor='raw')
+        try:
+            result = handle_posix_error('times', c_times(l_tmsbuf))
+            return (
+                rffi.cast(lltype.Signed, l_tmsbuf.c_tms_utime)
+                                               / CLOCK_TICKS_PER_SECOND,
+                rffi.cast(lltype.Signed, l_tmsbuf.c_tms_stime)
+                                               / CLOCK_TICKS_PER_SECOND,
+                rffi.cast(lltype.Signed, l_tmsbuf.c_tms_cutime)
+                                               / CLOCK_TICKS_PER_SECOND,
+                rffi.cast(lltype.Signed, l_tmsbuf.c_tms_cstime)
+                                               / CLOCK_TICKS_PER_SECOND,
+                result / CLOCK_TICKS_PER_SECOND)
+        finally:
+            lltype.free(l_tmsbuf, flavor='raw')
+    else:
+        pcreate = lltype.malloc(rwin32.FILETIME, flavor='raw')
+        pexit   = lltype.malloc(rwin32.FILETIME, flavor='raw')
+        pkernel = lltype.malloc(rwin32.FILETIME, flavor='raw')
+        puser   = lltype.malloc(rwin32.FILETIME, flavor='raw')
+        try:
+            hProc = GetCurrentProcess()
+            GetProcessTimes(hProc, pcreate, pexit, pkernel, puser)
+            # The fields of a FILETIME structure are the hi and lo parts
+            # of a 64-bit value expressed in 100 nanosecond units
+            # (of course).
+            return (
+                rffi.cast(lltype.Signed, pkernel.c_dwHighDateTime) * 
429.4967296 +
+                rffi.cast(lltype.Signed, pkernel.c_dwLowDateTime) * 1E-7,
+                rffi.cast(lltype.Signed, puser.c_dwHighDateTime) * 429.4967296 
+
+                rffi.cast(lltype.Signed, puser.c_dwLowDateTime) * 1E-7,
+                0, 0, 0)
+        finally:
+            lltype.free(puser,   flavor='raw')
+            lltype.free(pkernel, flavor='raw')
+            lltype.free(pexit,   flavor='raw')
+            lltype.free(pcreate, flavor='raw')
+
+c_kill = external('kill', [rffi.PID_T, rffi.INT], rffi.INT,
+                  save_err=rffi.RFFI_SAVE_ERRNO)
+c_killpg = external('killpg', [rffi.INT, rffi.INT], rffi.INT,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+c_exit = external('_exit', [rffi.INT], lltype.Void)
+c_nice = external('nice', [rffi.INT], rffi.INT,
+                  save_err=rffi.RFFI_FULL_ERRNO_ZERO)
+
+@replace_os_function('kill')
+def kill(pid, sig):
+    if not _WIN32:
+        return handle_posix_error('kill', c_kill(pid, sig))
+    else:
+        if sig == rwin32.CTRL_C_EVENT or sig == rwin32.CTRL_BREAK_EVENT:
+            if rwin32.GenerateConsoleCtrlEvent(sig, pid) == 0:
+                raise rwin32.lastSavedWindowsError(
+                    'kill() failed generating event')
+            return
+        handle = rwin32.OpenProcess(rwin32.PROCESS_ALL_ACCESS, False, pid)
+        if not handle:
+            raise rwin32.lastSavedWindowsError('kill() failed opening process')
+        try:
+            if rwin32.TerminateProcess(handle, sig) == 0:
+                raise rwin32.lastSavedWindowsError(
+                    'kill() failed to terminate process')
+        finally:
+            rwin32.CloseHandle(handle)
+
+@replace_os_function('killpg')
+def killpg(pgrp, sig):
+    return handle_posix_error('killpg', c_killpg(pgrp, sig))
+
+@replace_os_function('_exit')
+def exit(status):
+    debug.debug_flush()
+    c_exit(status)
+
+@replace_os_function('nice')
+def nice(inc):
+    # Assume that the system provides a standard-compliant version
+    # of nice() that returns the new priority.  Nowadays, FreeBSD
+    # might be the last major non-compliant system (xxx check me).
+    res = widen(c_nice(inc))
+    if res == -1:
+        err = get_saved_errno()
+        if err != 0:
+            raise OSError(err, "os_nice failed")
+    return res
+
+c_ctermid = external('ctermid', [rffi.CCHARP], rffi.CCHARP)
+
+@replace_os_function('ctermid')
+def ctermid():
+    return rffi.charp2str(c_ctermid(lltype.nullptr(rffi.CCHARP.TO)))
+
+c_tmpnam = external('tmpnam', [rffi.CCHARP], rffi.CCHARP)
+
+@replace_os_function('tmpnam')
+def tmpnam():
+    return rffi.charp2str(c_tmpnam(lltype.nullptr(rffi.CCHARP.TO)))
+
+#___________________________________________________________________
+
+c_getpid = external('getpid', [], rffi.PID_T,
+                    releasegil=False, save_err=rffi.RFFI_SAVE_ERRNO)
+c_getppid = external('getppid', [], rffi.PID_T,
+                     releasegil=False, save_err=rffi.RFFI_SAVE_ERRNO)
+c_setsid = external('setsid', [], rffi.PID_T,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+c_getsid = external('getsid', [rffi.PID_T], rffi.PID_T,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('getpid')
+def getpid():
+    return handle_posix_error('getpid', c_getpid())
+
+@replace_os_function('getppid')
+def getppid():
+    return handle_posix_error('getppid', c_getppid())
+
+@replace_os_function('setsid')
+def setsid():
+    return handle_posix_error('setsid', c_setsid())
+
+@replace_os_function('getsid')
+def getsid(pid):
+    return handle_posix_error('getsid', c_getsid(pid))
+
+c_getpgid = external('getpgid', [rffi.PID_T], rffi.PID_T,
+                     save_err=rffi.RFFI_SAVE_ERRNO)
+c_setpgid = external('setpgid', [rffi.PID_T, rffi.PID_T], rffi.INT,
+                     save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('getpgid')
+def getpgid(pid):
+    return handle_posix_error('getpgid', c_getpgid(pid))
+
+@replace_os_function('setpgid')
+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)
+
+@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')
+    try:
+        n = handle_posix_error('getgroups', c_getgroups(n, groups))
+        return [widen(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')
+    try:
+        for i in range(n):
+            groups[i] = rffi.cast(rffi.PID_T, gids[i])
+        handle_posix_error('setgroups', c_setgroups(n, groups))
+    finally:
+        lltype.free(groups, flavor='raw')
+
+@replace_os_function('initgroups')
+def initgroups(user, group):
+    handle_posix_error('initgroups', c_initgroups(user, group))
+
+if GETPGRP_HAVE_ARG:
+    c_getpgrp = external('getpgrp', [rffi.INT], rffi.INT,
+                         save_err=rffi.RFFI_SAVE_ERRNO)
+else:
+    c_getpgrp = external('getpgrp', [], rffi.INT,
+                         save_err=rffi.RFFI_SAVE_ERRNO)
+if SETPGRP_HAVE_ARG:
+    c_setpgrp = external('setpgrp', [rffi.INT, rffi.INT], rffi.INT,
+                         save_err=rffi.RFFI_SAVE_ERRNO)
+else:
+    c_setpgrp = external('setpgrp', [], rffi.INT,
+                         save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('getpgrp')
+def getpgrp():
+    if GETPGRP_HAVE_ARG:
+        return handle_posix_error('getpgrp', c_getpgrp(0))
+    else:
+        return handle_posix_error('getpgrp', c_getpgrp())
+
+@replace_os_function('setpgrp')
+def setpgrp():
+    if SETPGRP_HAVE_ARG:
+        handle_posix_error('setpgrp', c_setpgrp(0, 0))
+    else:
+        handle_posix_error('setpgrp', c_setpgrp())
+
+c_tcgetpgrp = external('tcgetpgrp', [rffi.INT], rffi.PID_T,
+                       save_err=rffi.RFFI_SAVE_ERRNO)
+c_tcsetpgrp = external('tcsetpgrp', [rffi.INT, rffi.PID_T], rffi.INT,
+                       save_err=rffi.RFFI_SAVE_ERRNO)
+
+@replace_os_function('tcgetpgrp')
+def tcgetpgrp(fd):
+    return handle_posix_error('tcgetpgrp', c_tcgetpgrp(fd))
+
+@replace_os_function('tcsetpgrp')
+def tcsetpgrp(fd, pgrp):
+    return handle_posix_error('tcsetpgrp', c_tcsetpgrp(fd, pgrp))
+
+#___________________________________________________________________
+
+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)
+
+@replace_os_function('getuid')
+def getuid():
+    return handle_posix_error('getuid', c_getuid())
+
+@replace_os_function('geteuid')
+def geteuid():
+    return handle_posix_error('geteuid', c_geteuid())
+
+@replace_os_function('setuid')
+def setuid(uid):
+    handle_posix_error('setuid', c_setuid(uid))
+
+@replace_os_function('seteuid')
+def seteuid(uid):
+    handle_posix_error('seteuid', c_seteuid(uid))
+
+@replace_os_function('getgid')
+def getgid():
+    return handle_posix_error('getgid', c_getgid())
+
+@replace_os_function('getegid')
+def getegid():
+    return handle_posix_error('getegid', c_getegid())
+
+@replace_os_function('setgid')
+def setgid(gid):
+    handle_posix_error('setgid', c_setgid(gid))
+
+@replace_os_function('setegid')
+def setegid(gid):
+    handle_posix_error('setegid', c_setegid(gid))
+
+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('setreuid')
+def setreuid(ruid, euid):
+    handle_posix_error('setreuid', c_setreuid(ruid, euid))
+
+@replace_os_function('setregid')
+def setregid(rgid, egid):
+    handle_posix_error('setregid', c_setregid(rgid, egid))
+
+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('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('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')
+
+@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))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to