[pypy-svn] r64596 - in pypy/trunk/pypy: module/posix rlib
afa at codespeak.net
afa at codespeak.net
Thu Apr 23 16:20:10 CEST 2009
Author: afa
Date: Thu Apr 23 16:20:07 2009
New Revision: 64596
Modified:
pypy/trunk/pypy/module/posix/__init__.py
pypy/trunk/pypy/module/posix/interp_posix.py
pypy/trunk/pypy/rlib/rwin32.py
Log:
Implement nt.urandom for Windows.
This fixes test_threaded_import
(Yes: test_threaded_import tests that tempfile.TemporaryFile does not need the import lock;
TemporaryFile uses random(), which tried to use os.urandom, then defaulted to some code that
"import time")
Modified: pypy/trunk/pypy/module/posix/__init__.py
==============================================================================
--- pypy/trunk/pypy/module/posix/__init__.py (original)
+++ pypy/trunk/pypy/module/posix/__init__.py Thu Apr 23 16:20:07 2009
@@ -61,6 +61,10 @@
'utime' : 'interp_posix.utime',
'_statfields': 'interp_posix.getstatfields(space)',
}
+
+ if os.name == 'nt':
+ interpleveldefs['urandom'] = 'interp_posix.win32_urandom'
+
if hasattr(os, 'chown'):
interpleveldefs['chown'] = 'interp_posix.chown'
if hasattr(os, 'ftruncate'):
Modified: pypy/trunk/pypy/module/posix/interp_posix.py
==============================================================================
--- pypy/trunk/pypy/module/posix/interp_posix.py (original)
+++ pypy/trunk/pypy/module/posix/interp_posix.py Thu Apr 23 16:20:07 2009
@@ -5,11 +5,13 @@
from pypy.interpreter.error import OperationError, wrap_oserror
from pypy.rpython.module.ll_os import RegisterOs
from pypy.rpython.module import ll_os_stat
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rpython.tool import rffi_platform
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
import os, sys
_WIN = sys.platform == 'win32'
-
+
def open(space, fname, flag, mode=0777):
"""Open a file (for low level IO).
Return a file descriptor (a small integer)."""
@@ -349,11 +351,16 @@
def __init__(self, space):
self.space = space
self.w_environ = space.newdict()
+ if _WIN:
+ self.cryptProviderPtr = lltype.malloc(
+ rffi.CArray(HCRYPTPROV), 1, zero=True, flavor='raw')
def startup(self, space):
_convertenviron(space, self.w_environ)
def _freeze_(self):
# don't capture the environment in the translated pypy
self.space.call_method(self.w_environ, 'clear')
+ if _WIN:
+ self.cryptProviderPtr[0] = HCRYPTPROV._default
return True
def get(space):
@@ -817,3 +824,73 @@
raise wrap_oserror(space, e)
return space.w_None
chown.unwrap_spec = [ObjSpace, str, int, int]
+
+if _WIN:
+ from pypy.rlib import rwin32
+
+ eci = ExternalCompilationInfo(
+ includes = ['windows.h'],
+ libraries = ['advapi32'],
+ )
+
+ class CConfig:
+ _compilation_info_ = eci
+ PROV_RSA_FULL = rffi_platform.ConstantInteger(
+ "PROV_RSA_FULL")
+ CRYPT_VERIFYCONTEXT = rffi_platform.ConstantInteger(
+ "CRYPT_VERIFYCONTEXT")
+
+ globals().update(rffi_platform.configure(CConfig))
+
+ HCRYPTPROV = rwin32.ULONG_PTR
+
+ CryptAcquireContext = rffi.llexternal(
+ 'CryptAcquireContextA',
+ [rffi.CArrayPtr(HCRYPTPROV),
+ rwin32.LPCSTR, rwin32.LPCSTR, rwin32.DWORD, rwin32.DWORD],
+ rwin32.BOOL,
+ calling_conv='win',
+ compilation_info=eci)
+
+ CryptGenRandom = rffi.llexternal(
+ 'CryptGenRandom',
+ [HCRYPTPROV, rwin32.DWORD, rffi.CArrayPtr(rwin32.BYTE)],
+ rwin32.BOOL,
+ calling_conv='win',
+ compilation_info=eci)
+
+ def win32_urandom(space, n):
+ """urandom(n) -> str
+
+ Return a string of n random bytes suitable for cryptographic use.
+ """
+
+ if n < 0:
+ raise OperationError(space.w_ValueError,
+ space.wrap("negative argument not allowed"))
+
+ provider = get(space).cryptProviderPtr[0]
+ if not provider:
+ # Acquire context.
+ # This handle is never explicitly released. The operating
+ # system will release it when the process terminates.
+ if not CryptAcquireContext(
+ get(space).cryptProviderPtr, None, None,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT):
+ raise rwin32.lastWindowsError("CryptAcquireContext")
+
+ provider = get(space).cryptProviderPtr[0]
+
+ # Get random data
+ buf = lltype.malloc(rffi.CArray(rwin32.BYTE), n,
+ zero=True, # zero seed
+ flavor='raw')
+ try:
+ if not CryptGenRandom(provider, n, buf):
+ raise rwin32.lastWindowsError("CryptGenRandom")
+
+ return space.wrap(
+ rffi.charpsize2str(rffi.cast(rffi.CCHARP, buf), n))
+ finally:
+ lltype.free(buf, flavor='raw')
+ win32_urandom.unwrap_spec = [ObjSpace, int]
Modified: pypy/trunk/pypy/rlib/rwin32.py
==============================================================================
--- pypy/trunk/pypy/rlib/rwin32.py (original)
+++ pypy/trunk/pypy/rlib/rwin32.py Thu Apr 23 16:20:07 2009
@@ -27,6 +27,7 @@
WORD = rffi_platform.SimpleType("WORD", rffi.UINT)
DWORD = rffi_platform.SimpleType("DWORD", rffi.UINT)
BOOL = rffi_platform.SimpleType("BOOL", rffi.LONG)
+ BYTE = rffi_platform.SimpleType("BYTE", rffi.UCHAR)
INT = rffi_platform.SimpleType("INT", rffi.INT)
LONG = rffi_platform.SimpleType("LONG", rffi.LONG)
PLONG = rffi_platform.SimpleType("PLONG", rffi.LONGP)
@@ -36,6 +37,7 @@
LPCSTR = rffi_platform.SimpleType("LPCSTR", rffi.CCHARP)
LPDWORD = rffi_platform.SimpleType("LPDWORD", rffi.INTP)
SIZE_T = rffi_platform.SimpleType("SIZE_T", rffi.SIZE_T)
+ ULONG_PTR = rffi_platform.SimpleType("ULONG_PTR", rffi.ULONG)
HRESULT = rffi_platform.SimpleType("HRESULT", rffi.LONG)
HLOCAL = rffi_platform.SimpleType("HLOCAL", rffi.VOIDP)
@@ -71,6 +73,7 @@
PFILETIME = rffi.CArrayPtr(FILETIME)
GetLastError = winexternal('GetLastError', [], DWORD)
+ SetLastError = winexternal('SetLastError', [DWORD], lltype.Void)
LoadLibrary = winexternal('LoadLibraryA', [rffi.CCHARP], rffi.VOIDP)
GetProcAddress = winexternal('GetProcAddress',
@@ -109,7 +112,7 @@
LocalFree(buf[0])
return result
- def lastWindowsError():
+ def lastWindowsError(context=None):
code = GetLastError()
message = FormatError(code)
return WindowsError(code, message)
More information about the Pypy-commit
mailing list