[pypy-commit] pypy default: _pwd_cffi, to make it a bit more portable than the ctypes version
arigo
noreply at buildbot.pypy.org
Tue May 19 22:39:05 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r77414:1291bd5dee42
Date: 2015-05-19 22:39 +0200
http://bitbucket.org/pypy/pypy/changeset/1291bd5dee42/
Log: _pwd_cffi, to make it a bit more portable than the ctypes version
diff --git a/lib_pypy/_pwd_build.py b/lib_pypy/_pwd_build.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_pwd_build.py
@@ -0,0 +1,38 @@
+from cffi import FFI
+
+ffi = FFI()
+
+ffi.set_source("_pwd_cffi", """
+#include <sys/types.h>
+#include <pwd.h>
+""")
+
+
+ffi.cdef("""
+
+typedef int uid_t;
+typedef int gid_t;
+
+struct passwd {
+ char *pw_name;
+ char *pw_passwd;
+ uid_t pw_uid;
+ gid_t pw_gid;
+ char *pw_gecos;
+ char *pw_dir;
+ char *pw_shell;
+ ...;
+};
+
+struct passwd *getpwuid(uid_t uid);
+struct passwd *getpwnam(const char *name);
+
+struct passwd *getpwent(void);
+void setpwent(void);
+void endpwent(void);
+
+""")
+
+
+if __name__ == "__main__":
+ ffi.compile()
diff --git a/lib_pypy/pwd.py b/lib_pypy/pwd.py
--- a/lib_pypy/pwd.py
+++ b/lib_pypy/pwd.py
@@ -10,65 +10,13 @@
exception is raised if the entry asked for cannot be found.
"""
-import sys
-if sys.platform == 'win32':
- raise ImportError("No pwd module on Windows")
-
-from ctypes_support import standard_c_lib as libc
-from ctypes import Structure, POINTER, c_int, c_char_p, c_long
+from _pwd_cffi import ffi, lib
from _structseq import structseqtype, structseqfield
try: from __pypy__ import builtinify
except ImportError: builtinify = lambda f: f
-uid_t = c_int
-gid_t = c_int
-time_t = c_long
-
-if sys.platform == 'darwin':
- class passwd(Structure):
- _fields_ = (
- ("pw_name", c_char_p),
- ("pw_passwd", c_char_p),
- ("pw_uid", uid_t),
- ("pw_gid", gid_t),
- ("pw_change", time_t),
- ("pw_class", c_char_p),
- ("pw_gecos", c_char_p),
- ("pw_dir", c_char_p),
- ("pw_shell", c_char_p),
- ("pw_expire", time_t),
- ("pw_fields", c_int),
- )
- def __iter__(self):
- yield self.pw_name
- yield self.pw_passwd
- yield self.pw_uid
- yield self.pw_gid
- yield self.pw_gecos
- yield self.pw_dir
- yield self.pw_shell
-else:
- class passwd(Structure):
- _fields_ = (
- ("pw_name", c_char_p),
- ("pw_passwd", c_char_p),
- ("pw_uid", uid_t),
- ("pw_gid", gid_t),
- ("pw_gecos", c_char_p),
- ("pw_dir", c_char_p),
- ("pw_shell", c_char_p),
- )
- def __iter__(self):
- yield self.pw_name
- yield self.pw_passwd
- yield self.pw_uid
- yield self.pw_gid
- yield self.pw_gecos
- yield self.pw_dir
- yield self.pw_shell
-
class struct_passwd:
"""
pwd.struct_passwd: Results from getpw*() routines.
@@ -87,32 +35,16 @@
pw_dir = structseqfield(5)
pw_shell = structseqfield(6)
-passwd_p = POINTER(passwd)
-_getpwuid = libc.getpwuid
-_getpwuid.argtypes = (uid_t,)
-_getpwuid.restype = passwd_p
-
-_getpwnam = libc.getpwnam
-_getpwnam.argtypes = (c_char_p,)
-_getpwnam.restype = passwd_p
-
-_setpwent = libc.setpwent
-_setpwent.argtypes = None
-_setpwent.restype = None
-
-_getpwent = libc.getpwent
-_getpwent.argtypes = None
-_getpwent.restype = passwd_p
-
-_endpwent = libc.endpwent
-_endpwent.argtypes = None
-_endpwent.restype = None
-
- at builtinify
-def mkpwent(pw):
- pw = pw.contents
- return struct_passwd(pw)
+def _mkpwent(pw):
+ return struct_passwd([
+ ffi.string(pw.pw_name),
+ ffi.string(pw.pw_passwd),
+ pw.pw_uid,
+ pw.pw_gid,
+ ffi.string(pw.pw_gecos),
+ ffi.string(pw.pw_dir),
+ ffi.string(pw.pw_shell)])
@builtinify
def getpwuid(uid):
@@ -122,10 +54,10 @@
Return the password database entry for the given numeric user ID.
See pwd.__doc__ for more on password database entries.
"""
- pw = _getpwuid(uid)
+ pw = lib.getpwuid(uid)
if not pw:
raise KeyError("getpwuid(): uid not found: %s" % uid)
- return mkpwent(pw)
+ return _mkpwent(pw)
@builtinify
def getpwnam(name):
@@ -137,10 +69,10 @@
"""
if not isinstance(name, str):
raise TypeError("expected string")
- pw = _getpwnam(name)
+ pw = lib.getpwnam(name)
if not pw:
raise KeyError("getpwname(): name not found: %s" % name)
- return mkpwent(pw)
+ return _mkpwent(pw)
@builtinify
def getpwall():
@@ -150,13 +82,13 @@
See pwd.__doc__ for more on password database entries.
"""
users = []
- _setpwent()
+ lib.setpwent()
while True:
- pw = _getpwent()
+ pw = lib.getpwent()
if not pw:
break
- users.append(mkpwent(pw))
- _endpwent()
+ users.append(_mkpwent(pw))
+ lib.endpwent()
return users
__all__ = ('struct_passwd', 'getpwuid', 'getpwnam', 'getpwall')
@@ -173,4 +105,3 @@
print("All:")
for pw in getpwall():
print(pw)
-
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -55,7 +55,8 @@
ignore_errors=True)
modules = ['_sqlite3_build.py', '_audioop_build.py']
if not sys.platform == 'win32':
- modules += ['_curses_build.py', '_syslog_build.py', '_gdbm_build.py']
+ modules += ['_curses_build.py', '_syslog_build.py', '_gdbm_build.py',
+ '_pwd_build.py']
if not options.no_tk:
modules.append('_tkinter/tklib_build.py')
for module in modules:
More information about the pypy-commit
mailing list