[pypy-commit] pypy missing-os-functions: Correctly detects the presence of fchmod and fchown.
amauryfa
noreply at buildbot.pypy.org
Fri Feb 22 16:57:53 CET 2013
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: missing-os-functions
Changeset: r61614:5e890c5dac82
Date: 2013-02-22 16:57 +0100
http://bitbucket.org/pypy/pypy/changeset/5e890c5dac82/
Log: Correctly detects the presence of fchmod and fchown. Tests run and
pass even with an old pypy which does (yet) not provide the
functions.
os.fchmod and os.fchown are not used anymore, they could probably be
removed from ll_os.py
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,6 +1,7 @@
# Package initialisation
from pypy.interpreter.mixedmodule import MixedModule
from rpython.rtyper.module.ll_os import RegisterOs
+from rpython.rlib import rposix
import os, sys
exec 'import %s as posix' % os.name
@@ -95,7 +96,7 @@
}
for name in '''
- wait wait3 wait4 chown lchown fchown fchmod ftruncate
+ wait wait3 wait4 chown lchown ftruncate
fsync fdatasync fchdir putenv unsetenv killpg getpid
link symlink readlink
fork openpty forkpty waitpid execv execve uname sysconf fpathconf
@@ -108,6 +109,12 @@
if hasattr(posix, name):
interpleveldefs[name] = 'interp_posix.%s' % (name,)
+ for name in '''fchmod fchown
+ '''.split():
+ symbol = 'HAS_' + name.upper()
+ if getattr(rposix, symbol):
+ interpleveldefs[name] = 'interp_posix.%s' % (name,)
+
for constant in '''
F_OK R_OK W_OK X_OK NGROUPS_MAX TMP_MAX
WNOHANG WCONTINUED WUNTRACED
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
@@ -20,6 +20,10 @@
c_int = "c_int"
+def oserror_from_errno(space):
+ errno = rposix.get_errno()
+ return wrap_oserror(space, OSError(errno, "OSError"))
+
# CPython 2.7 semantics are too messy to follow exactly,
# e.g. setuid(-2) works on 32-bit but not on 64-bit. As a result,
# we decided to just accept any 'int', i.e. any C signed long, and
@@ -586,10 +590,9 @@
"""Change the access permissions of the file given by file
descriptor fd."""
fd = space.c_filedescriptor_w(w_fd)
- try:
- os.fchmod(fd, mode)
- except OSError, e:
- raise wrap_oserror(space, e)
+ res = rposix.c_fchmod(fd, mode)
+ if res == -1:
+ raise oserror_from_errno(space)
def rename(space, w_old, w_new):
"Rename a file or directory."
@@ -1153,10 +1156,9 @@
fd = space.c_filedescriptor_w(w_fd)
check_uid_range(space, uid)
check_uid_range(space, gid)
- try:
- os.fchown(fd, uid, gid)
- except OSError, e:
- raise wrap_oserror(space, e)
+ res = rposix.c_fchown(fd, uid, gid)
+ if res == -1:
+ raise oserror_from_errno(space)
def getloadavg(space):
try:
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,6 +6,7 @@
from rpython.tool.udir import udir
from pypy.tool.pytest.objspace import gettestobjspace
from pypy.conftest import pypydir
+from rpython.rlib import rposix
from rpython.rtyper.module.ll_os import RegisterOs
from rpython.translator.c.test.test_extfunc import need_sparse_files
import os
@@ -833,7 +834,7 @@
os.symlink('foobar', self.path)
os.lchown(self.path, os.getuid(), os.getgid())
- if hasattr(os, 'fchown'):
+ if rposix.HAS_FCHOWN:
def test_fchown(self):
os = self.posix
f = open(self.path, "w")
@@ -856,7 +857,7 @@
os.chmod(self.path, 0200)
assert (os.stat(self.path).st_mode & 0777) == 0200
- if hasattr(os, 'fchmod'):
+ if rposix.HAS_FCHMOD:
def test_fchmod(self):
os = self.posix
f = open(self.path, "w")
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -1,6 +1,7 @@
import os
from rpython.rtyper.lltypesystem.rffi import CConstant, CExternVariable, INT
from rpython.rtyper.lltypesystem import ll2ctypes, rffi
+from rpython.rtyper.tool import rffi_platform
from rpython.translator.tool.cbuild import ExternalCompilationInfo
from rpython.rlib.rarithmetic import intmask
from rpython.rlib.objectmodel import specialize
@@ -83,14 +84,23 @@
else:
separate_module_sources = []
export_symbols = []
- includes=['errno.h','stdio.h']
-errno_eci = ExternalCompilationInfo(
+ includes=['errno.h', 'stdio.h', 'unistd.h', 'sys/stat.h']
+rposix_eci = ExternalCompilationInfo(
includes=includes,
separate_module_sources=separate_module_sources,
export_symbols=export_symbols,
)
-_get_errno, _set_errno = CExternVariable(INT, 'errno', errno_eci,
+class CConfig:
+ _compilation_info_ = rposix_eci
+
+ HAS_FCHMOD = rffi_platform.Has("fchmod")
+ HAS_FCHOWN = rffi_platform.Has("fchown")
+
+globals().update(rffi_platform.configure(CConfig))
+
+
+_get_errno, _set_errno = CExternVariable(INT, 'errno', rposix_eci,
CConstantErrno, sandboxsafe=True,
_nowrapper=True, c_type='int')
# the default wrapper for set_errno is not suitable for use in critical places
@@ -105,7 +115,7 @@
if os.name == 'nt':
is_valid_fd = rffi.llexternal(
"_PyVerify_fd", [rffi.INT], rffi.INT,
- compilation_info=errno_eci,
+ compilation_info=rposix_eci,
)
@jit.dont_look_inside
def validate_fd(fd):
@@ -127,6 +137,15 @@
except OSError:
pass
+# Expose posix functions
+def external(name, args, result):
+ return rffi.llexternal(name, args, result,
+ compilation_info=CConfig._compilation_info_)
+
+c_fchmod = external('fchmod', [rffi.INT, rffi.MODE_T], rffi.INT)
+c_fchown = external('fchown', [rffi.INT, rffi.INT, rffi.INT], rffi.INT)
+
+
#___________________________________________________________________
# Wrappers around posix functions, that accept either strings, or
# instances with a "as_bytes()" method.
More information about the pypy-commit
mailing list