pypy /pypy/module/pwd/interp_pwd.py

Language Python Lines 134
MD5 Hash 4d79c20bb07be5c4cc5c015a74ad62cc Estimated Cost $2,459 (why?)
Repository https://bitbucket.org/pypy/pypy/ View Raw File View Project SPDX
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
from rpython.translator.tool.cbuild import ExternalCompilationInfo
from rpython.rtyper.tool import rffi_platform
from rpython.rtyper.lltypesystem import rffi, lltype
from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.gateway import unwrap_spec
from rpython.rlib.rarithmetic import r_uint, widen


eci = ExternalCompilationInfo(includes=['pwd.h'])

class CConfig:
    _compilation_info_ = eci

    uid_t = rffi_platform.SimpleType("uid_t")
    gid_t = rffi_platform.SimpleType("gid_t")

config = rffi_platform.configure(CConfig)

uid_t = config['uid_t']
gid_t = config['gid_t']

class CConfig:
    _compilation_info_ = eci

    passwd = rffi_platform.Struct(
        'struct passwd',
        [('pw_name', rffi.CCHARP),
         ('pw_passwd', rffi.CCHARP),
         ('pw_uid', uid_t),
         ('pw_gid', gid_t),
         ('pw_gecos', rffi.CCHARP),
         ('pw_dir', rffi.CCHARP),
         ('pw_shell', rffi.CCHARP)])

config = rffi_platform.configure(CConfig)

passwd_p = lltype.Ptr(config['passwd'])

def external(name, args, result, **kwargs):
    return rffi.llexternal(name, args, result, compilation_info=eci, **kwargs)

c_getpwuid = external("getpwuid", [uid_t], passwd_p)
c_getpwnam = external("getpwnam", [rffi.CCHARP], passwd_p)
c_setpwent = external("setpwent", [], lltype.Void)
c_getpwent = external("getpwent", [], passwd_p)
c_endpwent = external("endpwent", [], lltype.Void)


def uid_converter(space, w_uid):
    try:
        val = space.int_w(w_uid)
        if val == -1:
            return rffi.cast(uid_t, -1)
        elif val < 0:
            raise oefmt(space.w_OverflowError, "user id is less than minimum")
        else:
            val = r_uint(val)
    except OperationError as e:
        if not e.match(space, space.w_OverflowError):
            raise
        try:
            val = space.uint_w(w_uid)
        except OperationError as e:
            if e.match(space, space.w_ValueError):
                raise oefmt(space.w_OverflowError, "user id is less than minimum")
            elif e.match(space, space.w_OverflowError):
                raise oefmt(space.w_OverflowError, "user id is greater than maximum")
            raise
    uid = rffi.cast(uid_t, val)
    if val != uid:
        raise oefmt(space.w_OverflowError, "user id is greater than maximum")
    return uid

def make_struct_passwd(space, pw):
    w_passwd_struct = space.getattr(space.getbuiltinmodule('pwd'),
                                    space.wrap('struct_passwd'))
    w_tuple = space.newtuple([
        space.wrap(rffi.charp2str(pw.c_pw_name)),
        space.wrap(rffi.charp2str(pw.c_pw_passwd)),
        space.int(space.wrap(pw.c_pw_uid)),
        space.int(space.wrap(pw.c_pw_gid)),
        space.wrap(rffi.charp2str(pw.c_pw_gecos)),
        space.wrap(rffi.charp2str(pw.c_pw_dir)),
        space.wrap(rffi.charp2str(pw.c_pw_shell)),
        ])
    return space.call_function(w_passwd_struct, w_tuple)


def getpwuid(space, w_uid):
    """
    getpwuid(uid) -> (pw_name,pw_passwd,pw_uid,
                      pw_gid,pw_gecos,pw_dir,pw_shell)
    Return the password database entry for the given numeric user ID.
    See pwd.__doc__ for more on password database entries.
    """
    msg = "getpwuid(): uid not found"
    try:
        uid = uid_converter(space, w_uid)
    except OperationError as e:
        if e.match(space, space.w_OverflowError):
            raise oefmt(space.w_KeyError, msg)
        raise
    pw = c_getpwuid(uid)
    if not pw:
        raise OperationError(space.w_KeyError, space.wrap(
            "%s: %d" % (msg, widen(uid))))
    return make_struct_passwd(space, pw)

@unwrap_spec(name=str)
def getpwnam(space, name):
    """
    getpwnam(name) -> (pw_name,pw_passwd,pw_uid,
                        pw_gid,pw_gecos,pw_dir,pw_shell)
    Return the password database entry for the given user name.
    See pwd.__doc__ for more on password database entries.
    """
    pw = c_getpwnam(name)
    if not pw:
        raise oefmt(space.w_KeyError, "getpwnam(): name not found: %s", name)
    return make_struct_passwd(space, pw)

def getpwall(space):
    users_w = []
    c_setpwent()
    try:
        while True:
            pw = c_getpwent()
            if not pw:
                break
            users_w.append(make_struct_passwd(space, pw))
    finally:
        c_endpwent()
    return space.newlist(users_w)
Back to Top