Author: Ronan Lamy <[email protected]> Branch: follow_symlinks Changeset: r83285:66663350a720 Date: 2016-03-23 00:57 +0000 http://bitbucket.org/pypy/pypy/changeset/66663350a720/
Log: hg merge rposix-for-3 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -19,3 +19,4 @@ 850edf14b2c75573720f59e95767335fb1affe55 release-4.0.0 5f8302b8bf9f53056e40426f10c72151564e5b19 release-4.0.1 246c9cf22037b11dc0e8c29ce3f291d3b8c5935a release-5.0 +bbd45126bc691f669c4ebdfbd74456cd274c6b92 release-5.0.1 diff --git a/pypy/doc/release-5.0.1.rst b/pypy/doc/release-5.0.1.rst --- a/pypy/doc/release-5.0.1.rst +++ b/pypy/doc/release-5.0.1.rst @@ -9,6 +9,11 @@ .. _`lxml 3.6.0`: https://pypi.python.org/pypi/lxml/3.6.0 .. _`crash on large files`: https://bitbucket.org/pypy/pypy/issues/2260 + +The changes between PyPy 5.0 and 5.0.1 are only two bug fixes: one in +cpyext, which fixes notably (but not only) lxml; and another for a +corner case of the JIT. + What is PyPy? ============= diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -390,4 +390,4 @@ w_fileobj.cffi_fileobj = CffiFileObj(fd, mode) except OSError, e: raise wrap_oserror(space, e) - return rffi.cast(rffi.CCHARP, fileobj.cffi_fileobj.llf) + return rffi.cast(rffi.CCHARP, w_fileobj.cffi_fileobj.llf) diff --git a/pypy/module/cpyext/bytesobject.py b/pypy/module/cpyext/bytesobject.py --- a/pypy/module/cpyext/bytesobject.py +++ b/pypy/module/cpyext/bytesobject.py @@ -1,4 +1,4 @@ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, oefmt from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.api import ( cpython_api, cpython_struct, bootstrap_function, build_type_checkers, @@ -134,8 +134,8 @@ if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_str: pass # typecheck returned "ok" without forcing 'ref' at all elif not PyBytes_Check(space, ref): # otherwise, use the alternate way - raise OperationError(space.w_TypeError, space.wrap( - "PyBytes_AsString only support strings")) + raise oefmt(space.w_TypeError, + "expected bytes, %T found", from_ref(space, ref)) ref_str = rffi.cast(PyBytesObject, ref) if not ref_str.c_buffer: # copy string buffer @@ -147,8 +147,8 @@ @cpython_api([PyObject, rffi.CCHARPP, rffi.CArrayPtr(Py_ssize_t)], rffi.INT_real, error=-1) def PyBytes_AsStringAndSize(space, ref, buffer, length): if not PyBytes_Check(space, ref): - raise OperationError(space.w_TypeError, space.wrap( - "PyBytes_AsStringAndSize only support strings")) + raise oefmt(space.w_TypeError, + "expected bytes, %T found", from_ref(space, ref)) ref_str = rffi.cast(PyBytesObject, ref) if not ref_str.c_buffer: # copy string buffer diff --git a/pypy/tool/release/repackage.sh b/pypy/tool/release/repackage.sh --- a/pypy/tool/release/repackage.sh +++ b/pypy/tool/release/repackage.sh @@ -1,9 +1,9 @@ # Edit these appropriately before running this script maj=5 min=0 -rev=0 +rev=1 branchname=release-$maj.x # ==OR== release-$maj.$min.x -tagname=release-$maj.$min # ==OR== release-$maj.$min.$rev +tagname=release-$maj.$min.$rev # This script will download latest builds from the buildmaster, rename the top # level directory, and repackage ready to be uploaded to bitbucket. It will also # download source, assuming a tag for the release already exists, and repackage them. diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -22,21 +22,6 @@ from rpython.rlib import rwin32 from rpython.rlib.rwin32file import make_win32_traits -class CConfig: - _compilation_info_ = ExternalCompilationInfo( - includes=['sys/stat.h', - 'unistd.h', - 'fcntl.h'], - ) - for _name in """fchdir fchmod fchmodat fchown fchownat fexecve fdopendir - fpathconf fstat fstatat fstatvfs ftruncate futimens futimes - futimesat linkat lchflags lchmod lchown lstat lutimes - mkdirat mkfifoat mknodat openat readlinkat renameat - symlinkat unlinkat utimensat""".split(): - locals()['HAVE_%s' % _name.upper()] = rffi_platform.Has(_name) -cConfig = rffi_platform.configure(CConfig) -globals().update(cConfig) - class CConstantErrno(CConstant): # these accessors are used when calling get_errno() or set_errno() @@ -1739,3 +1724,176 @@ def getcontroller(self): from rpython.rlib.rposix_environ import OsEnvironController return OsEnvironController() + + +# ____________________________________________________________ +# Support for f... and ...at families of POSIX functions + +class CConfig: + _compilation_info_ = ExternalCompilationInfo( + includes=['sys/stat.h', + 'unistd.h', + 'fcntl.h'], + ) + AT_FDCWD = rffi_platform.DefinedConstantInteger('AT_FDCWD') + AT_SYMLINK_NOFOLLOW = rffi_platform.DefinedConstantInteger('AT_SYMLINK_NOFOLLOW') + AT_EACCESS = rffi_platform.DefinedConstantInteger('AT_EACCESS') + AT_REMOVEDIR = rffi_platform.DefinedConstantInteger('AT_REMOVEDIR') + TIMESPEC = rffi_platform.Struct('struct timespec', [ + ('tv_sec', rffi.TIME_T), + ('tv_nsec', rffi.LONG)]) + + for _name in """faccessat fchdir fchmod fchmodat fchown fchownat fexecve + fdopendir fpathconf fstat fstatat fstatvfs ftruncate + futimens futimes futimesat linkat chflags lchflags lchmod lchown + lstat lutimes mkdirat mkfifoat mknodat openat readlinkat renameat + symlinkat unlinkat utimensat""".split(): + locals()['HAVE_%s' % _name.upper()] = rffi_platform.Has(_name) +cConfig = rffi_platform.configure(CConfig) +globals().update(cConfig) +TIMESPEC2P = rffi.CArrayPtr(TIMESPEC) + +if HAVE_FACCESSAT: + c_faccessat = external('faccessat', + [rffi.INT, rffi.CCHARP, rffi.INT, rffi.INT], rffi.INT) + + def faccessat(pathname, mode, dir_fd=AT_FDCWD, + effective_ids=False, follow_symlinks=True): + """Thin wrapper around faccessat(2) with an interface simlar to + Python3's os.access(). + """ + flags = 0 + if not follow_symlinks: + flags |= AT_SYMLINK_NOFOLLOW + if effective_ids: + flags |= AT_EACCESS + error = c_faccessat(dir_fd, pathname, mode, flags) + return error == 0 + +if HAVE_LINKAT: + c_linkat = external('linkat', + [rffi.INT, rffi.CCHARP, rffi.INT, rffi.CCHARP, rffi.INT], rffi.INT) + + def linkat(src, dst, src_dir_fd=AT_FDCWD, dst_dir_fd=AT_FDCWD, + follow_symlinks=True): + """Thin wrapper around linkat(2) with an interface similar to + Python3's os.link() + """ + if follow_symlinks: + flag = 0 + else: + flag = AT_SYMLINK_NOFOLLOW + error = c_linkat(src_dir_fd, src, dst_dir_fd, dst, flag) + handle_posix_error('linkat', error) + +if HAVE_FUTIMENS: + c_futimens = external('futimens', [rffi.INT, TIMESPEC2P], rffi.INT) + + def futimens(fd, atime, atime_ns, mtime, mtime_ns): + l_times = lltype.malloc(TIMESPEC, 2, flavor='raw') + rffi.setintfield(l_times[0], 'c_tv_sec', atime) + rffi.setintfield(l_times[0], 'c_tv_nsec', atime_ns) + rffi.setintfield(l_times[1], 'c_tv_sec', mtime) + rffi.setintfield(l_times[1], 'c_tv_nsec', mtime_ns) + error = c_futimens(fd, l_times) + handle_posix_error('futimens', error) + +if HAVE_UTIMENSAT: + c_utimensat = external('utimensat', [rffi.INT, TIMESPEC2P], rffi.INT) + + def utimensat(pathname, atime, atime_ns, mtime, mtime_ns, + dir_fd=AT_FDCWD, follow_symlinks=True): + l_times = lltype.malloc(TIMESPEC, 2, flavor='raw') + rffi.setintfield(l_times[0], 'c_tv_sec', atime) + rffi.setintfield(l_times[0], 'c_tv_nsec', atime_ns) + rffi.setintfield(l_times[1], 'c_tv_sec', mtime) + rffi.setintfield(l_times[1], 'c_tv_nsec', mtime_ns) + if follow_symlinks: + flag = 0 + else: + flag = AT_SYMLINK_NOFOLLOW + error = c_futimens(dir_fd, pathname, l_times, flag) + handle_posix_error('utimensat', error) + +if HAVE_MKDIRAT: + c_mkdirat = external('mkdirat', + [rffi.INT, rffi.CCHARP, rffi.INT], rffi.INT, + save_err=rffi.RFFI_SAVE_ERRNO) + + def mkdirat(pathname, mode, dir_fd=AT_FDCWD): + error = c_mkdirat(dir_fd, pathname, mode) + handle_posix_error('mkdirat', error) + +if HAVE_UNLINKAT: + c_unlinkat = external('unlinkat', + [rffi.INT, rffi.CCHARP, rffi.INT], rffi.INT, + save_err=rffi.RFFI_SAVE_ERRNO) + + def unlinkat(pathname, dir_fd=AT_FDCWD, removedir=False): + flag = AT_REMOVEDIR if removedir else 0 + error = c_unlinkat(dir_fd, pathname, flag) + handle_posix_error('unlinkat', error) + +if HAVE_READLINKAT: + c_readlinkat = external( + 'readlinkat', + [rffi.INT, rffi.CCHARP, rffi.CCHARP, rffi.SIZE_T], rffi.SSIZE_T, + save_err=rffi.RFFI_SAVE_ERRNO) + + def readlinkat(pathname, dir_fd=AT_FDCWD): + pathname = _as_bytes0(pathname) + bufsize = 1023 + while True: + buf = lltype.malloc(rffi.CCHARP.TO, bufsize, flavor='raw') + res = widen(c_readlinkat(dir_fd, pathname, buf, bufsize)) + if res < 0: + lltype.free(buf, flavor='raw') + error = get_saved_errno() # failed + raise OSError(error, "readlinkat 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 + +if HAVE_SYMLINKAT: + c_symlinkat = external('symlinkat', + [rffi.CCHARP, rffi.CCHARP, rffi.INT], rffi.INT, + save_err=rffi.RFFI_SAVE_ERRNO) + + def symlinkat(src, dst, dir_fd=AT_FDCWD): + error = c_symlinkat(src, dst, dir_fd) + handle_posix_error('symlinkat', error) + +if HAVE_OPENAT: + c_openat = external('openat', + [rffi.INT, rffi.CCHARP, rffi.INT, rffi.MODE_T], rffi.INT, + save_err=rffi.RFFI_SAVE_ERRNO) + + @enforceargs(s_Str0, int, int, int, typecheck=False) + def openat(path, flags, mode, dir_fd=AT_FDCWD): + fd = c_openat(dir_fd, path, flags, mode) + return handle_posix_error('open', fd) + +if HAVE_MKFIFOAT: + c_mkfifoat = external('mkfifoat', + [rffi.INT, rffi.CCHARP, rffi.MODE_T], rffi.INT, + save_err=rffi.RFFI_SAVE_ERRNO) + + def mkfifoat(path, mode, dir_fd=AT_FDCWD): + error = c_mkfifoat(dir_fd, path, mode) + handle_posix_error('mkfifoat', error) + +if HAVE_MKNODAT: + c_mknodat = external('mknodat', + [rffi.INT, rffi.CCHARP, rffi.MODE_T, rffi.INT], rffi.INT, + save_err=rffi.RFFI_SAVE_ERRNO) + + def mknodat(path, mode, device, dir_fd=AT_FDCWD): + error = c_mknodat(dir_fd, path, mode, device) + handle_posix_error('mknodat', error) diff --git a/rpython/rlib/rvmprof/src/vmprof_config.h b/rpython/rlib/rvmprof/src/vmprof_config.h --- a/rpython/rlib/rvmprof/src/vmprof_config.h +++ b/rpython/rlib/rvmprof/src/vmprof_config.h @@ -1,6 +1,10 @@ #define HAVE_SYS_UCONTEXT_H -#if defined(__FreeBSD__) -#define PC_FROM_UCONTEXT uc_mcontext.mc_rip +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + #ifdef __i386__ + #define PC_FROM_UCONTEXT uc_mcontext.mc_eip + #else + #define PC_FROM_UCONTEXT uc_mcontext.mc_rip + #endif #elif defined( __APPLE__) #if ((ULONG_MAX) == (UINT_MAX)) #define PC_FROM_UCONTEXT uc_mcontext->__ss.__eip @@ -8,10 +12,10 @@ #define PC_FROM_UCONTEXT uc_mcontext->__ss.__rip #endif #elif defined(__arm__) -#define PC_FROM_UCONTEXT uc_mcontext.arm_ip + #define PC_FROM_UCONTEXT uc_mcontext.arm_ip #elif defined(__linux) && defined(__i386) && defined(__GNUC__) -#define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_EIP] + #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_EIP] #else -/* linux, gnuc */ -#define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_RIP] + /* linux, gnuc */ + #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_RIP] #endif diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py --- a/rpython/rlib/test/test_rposix.py +++ b/rpython/rlib/test/test_rposix.py @@ -7,6 +7,10 @@ import errno import py +def rposix_requires(funcname): + return py.test.mark.skipif(not hasattr(rposix, funcname), + reason="Requires rposix.%s()" % funcname) + class TestPosixFunction: def test_access(self): filename = str(udir.join('test_access.txt')) @@ -99,11 +103,25 @@ def test_mkdir(self): filename = str(udir.join('test_mkdir.dir')) rposix.mkdir(filename, 0) - exc = py.test.raises(OSError, rposix.mkdir, filename, 0) - assert exc.value.errno == errno.EEXIST + with py.test.raises(OSError) as excinfo: + rposix.mkdir(filename, 0) + assert excinfo.value.errno == errno.EEXIST if sys.platform == 'win32': assert exc.type is WindowsError + @rposix_requires('mkdirat') + def test_mkdirat(self): + relpath = 'test_mkdirat.dir' + filename = str(udir.join(relpath)) + dirfd = os.open(os.path.dirname(filename), os.O_RDONLY) + try: + rposix.mkdirat(relpath, 0, dir_fd=dirfd) + with py.test.raises(OSError) as excinfo: + rposix.mkdirat(relpath, 0, dir_fd=dirfd) + assert excinfo.value.errno == errno.EEXIST + finally: + os.close(dirfd) + def test_strerror(self): assert rposix.strerror(2) == os.strerror(2) @@ -448,6 +466,38 @@ def _get_filename(self): return str(udir.join('test_open_ascii')) + @rposix_requires('openat') + def test_openat(self): + def f(dirfd): + try: + fd = rposix.openat('test_open_ascii', os.O_RDONLY, 0777, dirfd) + try: + text = os.read(fd, 50) + return text + finally: + os.close(fd) + except OSError: + return '' + + dirfd = os.open(os.path.dirname(self.ufilename), os.O_RDONLY) + try: + assert ll_to_string(interpret(f, [dirfd])) == "test" + finally: + os.close(dirfd) + + @rposix_requires('unlinkat') + def test_unlinkat(self): + def f(dirfd): + return rposix.unlinkat('test_open_ascii', dir_fd=dirfd) + + dirfd = os.open(os.path.dirname(self.ufilename), os.O_RDONLY) + try: + interpret(f, [dirfd]) + finally: + os.close(dirfd) + assert not os.path.exists(self.ufilename) + + class TestPosixUnicode(BasePosixUnicodeOrAscii): def _get_filename(self): return (unicode(udir.join('test_open')) + diff --git a/rpython/translator/c/src/thread_pthread.c b/rpython/translator/c/src/thread_pthread.c --- a/rpython/translator/c/src/thread_pthread.c +++ b/rpython/translator/c/src/thread_pthread.c @@ -37,7 +37,7 @@ # define THREAD_STACK_SIZE 0 /* use default stack size */ # endif -# if (defined(__APPLE__) || defined(__FreeBSD__)) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 +# if (defined(__APPLE__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 /* The default stack size for new threads on OSX is small enough that * we'll get hard crashes instead of 'maximum recursion depth exceeded' * exceptions. @@ -84,7 +84,7 @@ if (tss != 0) pthread_attr_setstacksize(&attrs, tss); #endif -#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) && !defined(__FreeBSD__) +#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) && !(defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM); #endif _______________________________________________ pypy-commit mailing list [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
