PageRenderTime 199ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/module/pwd/interp_pwd.py

https://bitbucket.org/pypy/pypy/
Python | 133 lines | 102 code | 19 blank | 12 comment | 20 complexity | 4d79c20bb07be5c4cc5c015a74ad62cc MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from rpython.translator.tool.cbuild import ExternalCompilationInfo
  2. from rpython.rtyper.tool import rffi_platform
  3. from rpython.rtyper.lltypesystem import rffi, lltype
  4. from pypy.interpreter.error import OperationError, oefmt
  5. from pypy.interpreter.gateway import unwrap_spec
  6. from rpython.rlib.rarithmetic import r_uint, widen
  7. eci = ExternalCompilationInfo(includes=['pwd.h'])
  8. class CConfig:
  9. _compilation_info_ = eci
  10. uid_t = rffi_platform.SimpleType("uid_t")
  11. gid_t = rffi_platform.SimpleType("gid_t")
  12. config = rffi_platform.configure(CConfig)
  13. uid_t = config['uid_t']
  14. gid_t = config['gid_t']
  15. class CConfig:
  16. _compilation_info_ = eci
  17. passwd = rffi_platform.Struct(
  18. 'struct passwd',
  19. [('pw_name', rffi.CCHARP),
  20. ('pw_passwd', rffi.CCHARP),
  21. ('pw_uid', uid_t),
  22. ('pw_gid', gid_t),
  23. ('pw_gecos', rffi.CCHARP),
  24. ('pw_dir', rffi.CCHARP),
  25. ('pw_shell', rffi.CCHARP)])
  26. config = rffi_platform.configure(CConfig)
  27. passwd_p = lltype.Ptr(config['passwd'])
  28. def external(name, args, result, **kwargs):
  29. return rffi.llexternal(name, args, result, compilation_info=eci, **kwargs)
  30. c_getpwuid = external("getpwuid", [uid_t], passwd_p)
  31. c_getpwnam = external("getpwnam", [rffi.CCHARP], passwd_p)
  32. c_setpwent = external("setpwent", [], lltype.Void)
  33. c_getpwent = external("getpwent", [], passwd_p)
  34. c_endpwent = external("endpwent", [], lltype.Void)
  35. def uid_converter(space, w_uid):
  36. try:
  37. val = space.int_w(w_uid)
  38. if val == -1:
  39. return rffi.cast(uid_t, -1)
  40. elif val < 0:
  41. raise oefmt(space.w_OverflowError, "user id is less than minimum")
  42. else:
  43. val = r_uint(val)
  44. except OperationError as e:
  45. if not e.match(space, space.w_OverflowError):
  46. raise
  47. try:
  48. val = space.uint_w(w_uid)
  49. except OperationError as e:
  50. if e.match(space, space.w_ValueError):
  51. raise oefmt(space.w_OverflowError, "user id is less than minimum")
  52. elif e.match(space, space.w_OverflowError):
  53. raise oefmt(space.w_OverflowError, "user id is greater than maximum")
  54. raise
  55. uid = rffi.cast(uid_t, val)
  56. if val != uid:
  57. raise oefmt(space.w_OverflowError, "user id is greater than maximum")
  58. return uid
  59. def make_struct_passwd(space, pw):
  60. w_passwd_struct = space.getattr(space.getbuiltinmodule('pwd'),
  61. space.wrap('struct_passwd'))
  62. w_tuple = space.newtuple([
  63. space.wrap(rffi.charp2str(pw.c_pw_name)),
  64. space.wrap(rffi.charp2str(pw.c_pw_passwd)),
  65. space.int(space.wrap(pw.c_pw_uid)),
  66. space.int(space.wrap(pw.c_pw_gid)),
  67. space.wrap(rffi.charp2str(pw.c_pw_gecos)),
  68. space.wrap(rffi.charp2str(pw.c_pw_dir)),
  69. space.wrap(rffi.charp2str(pw.c_pw_shell)),
  70. ])
  71. return space.call_function(w_passwd_struct, w_tuple)
  72. def getpwuid(space, w_uid):
  73. """
  74. getpwuid(uid) -> (pw_name,pw_passwd,pw_uid,
  75. pw_gid,pw_gecos,pw_dir,pw_shell)
  76. Return the password database entry for the given numeric user ID.
  77. See pwd.__doc__ for more on password database entries.
  78. """
  79. msg = "getpwuid(): uid not found"
  80. try:
  81. uid = uid_converter(space, w_uid)
  82. except OperationError as e:
  83. if e.match(space, space.w_OverflowError):
  84. raise oefmt(space.w_KeyError, msg)
  85. raise
  86. pw = c_getpwuid(uid)
  87. if not pw:
  88. raise OperationError(space.w_KeyError, space.wrap(
  89. "%s: %d" % (msg, widen(uid))))
  90. return make_struct_passwd(space, pw)
  91. @unwrap_spec(name=str)
  92. def getpwnam(space, name):
  93. """
  94. getpwnam(name) -> (pw_name,pw_passwd,pw_uid,
  95. pw_gid,pw_gecos,pw_dir,pw_shell)
  96. Return the password database entry for the given user name.
  97. See pwd.__doc__ for more on password database entries.
  98. """
  99. pw = c_getpwnam(name)
  100. if not pw:
  101. raise oefmt(space.w_KeyError, "getpwnam(): name not found: %s", name)
  102. return make_struct_passwd(space, pw)
  103. def getpwall(space):
  104. users_w = []
  105. c_setpwent()
  106. try:
  107. while True:
  108. pw = c_getpwent()
  109. if not pw:
  110. break
  111. users_w.append(make_struct_passwd(space, pw))
  112. finally:
  113. c_endpwent()
  114. return space.newlist(users_w)