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