Skip to content

Commit 81b737b

Browse files
committed
use #[pymodule] for pwd
1 parent fd71647 commit 81b737b

1 file changed

Lines changed: 90 additions & 92 deletions

File tree

vm/src/stdlib/pwd.rs

Lines changed: 90 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,105 @@
1-
use crate::{
2-
builtins::{PyIntRef, PyStrRef},
3-
function::{IntoPyException, IntoPyObject},
4-
PyClassImpl, PyObjectRef, PyResult, PyStructSequence, VirtualMachine,
5-
};
6-
use nix::unistd::{self, User};
7-
use std::convert::TryFrom;
8-
use std::ptr::NonNull;
1+
pub(crate) use pwd::make_module;
92

10-
#[pyclass(module = "pwd", name = "struct_passwd")]
11-
#[derive(PyStructSequence)]
12-
struct Passwd {
13-
pw_name: String,
14-
pw_passwd: String,
15-
pw_uid: u32,
16-
pw_gid: u32,
17-
pw_gecos: String,
18-
pw_dir: String,
19-
pw_shell: String,
20-
}
21-
#[pyimpl(with(PyStructSequence))]
22-
impl Passwd {}
3+
#[pymodule]
4+
mod pwd {
5+
use crate::{
6+
builtins::{PyIntRef, PyStrRef},
7+
function::{IntoPyException, IntoPyObject},
8+
PyObjectRef, PyResult, PyStructSequence, VirtualMachine,
9+
};
10+
use nix::unistd::{self, User};
11+
use std::convert::TryFrom;
12+
use std::ptr::NonNull;
2313

24-
impl From<User> for Passwd {
25-
fn from(user: User) -> Self {
26-
// this is just a pain...
27-
let cstr_lossy = |s: std::ffi::CString| {
28-
s.into_string()
29-
.unwrap_or_else(|e| e.into_cstring().to_string_lossy().into_owned())
30-
};
31-
let pathbuf_lossy = |p: std::path::PathBuf| {
32-
p.into_os_string()
33-
.into_string()
34-
.unwrap_or_else(|s| s.to_string_lossy().into_owned())
35-
};
36-
Passwd {
37-
pw_name: user.name,
38-
pw_passwd: cstr_lossy(user.passwd),
39-
pw_uid: user.uid.as_raw(),
40-
pw_gid: user.gid.as_raw(),
41-
pw_gecos: cstr_lossy(user.gecos),
42-
pw_dir: pathbuf_lossy(user.dir),
43-
pw_shell: pathbuf_lossy(user.shell),
44-
}
14+
#[pyattr]
15+
#[pyclass(module = "pwd", name = "struct_passwd")]
16+
#[derive(PyStructSequence)]
17+
struct Passwd {
18+
pw_name: String,
19+
pw_passwd: String,
20+
pw_uid: u32,
21+
pw_gid: u32,
22+
pw_gecos: String,
23+
pw_dir: String,
24+
pw_shell: String,
4525
}
46-
}
26+
#[pyimpl(with(PyStructSequence))]
27+
impl Passwd {}
4728

48-
fn pwd_getpwnam(name: PyStrRef, vm: &VirtualMachine) -> PyResult<Passwd> {
49-
match User::from_name(name.as_str()).map_err(|err| err.into_pyexception(vm))? {
50-
Some(user) => Ok(Passwd::from(user)),
51-
None => {
52-
let name_repr = vm.to_repr(name.as_object())?;
53-
let message = vm
54-
.ctx
55-
.new_str(format!("getpwnam(): name not found: {}", name_repr))
56-
.into();
57-
Err(vm.new_key_error(message))
29+
impl From<User> for Passwd {
30+
fn from(user: User) -> Self {
31+
// this is just a pain...
32+
let cstr_lossy = |s: std::ffi::CString| {
33+
s.into_string()
34+
.unwrap_or_else(|e| e.into_cstring().to_string_lossy().into_owned())
35+
};
36+
let pathbuf_lossy = |p: std::path::PathBuf| {
37+
p.into_os_string()
38+
.into_string()
39+
.unwrap_or_else(|s| s.to_string_lossy().into_owned())
40+
};
41+
Passwd {
42+
pw_name: user.name,
43+
pw_passwd: cstr_lossy(user.passwd),
44+
pw_uid: user.uid.as_raw(),
45+
pw_gid: user.gid.as_raw(),
46+
pw_gecos: cstr_lossy(user.gecos),
47+
pw_dir: pathbuf_lossy(user.dir),
48+
pw_shell: pathbuf_lossy(user.shell),
49+
}
5850
}
5951
}
60-
}
6152

62-
fn pwd_getpwuid(uid: PyIntRef, vm: &VirtualMachine) -> PyResult<Passwd> {
63-
let uid_t = libc::uid_t::try_from(uid.as_bigint()).map(unistd::Uid::from_raw);
64-
let user = match uid_t {
65-
Ok(uid) => User::from_uid(uid).map_err(|err| err.into_pyexception(vm))?,
66-
Err(_) => None,
67-
};
68-
match user {
69-
Some(user) => Ok(Passwd::from(user)),
70-
None => {
71-
let message = vm
72-
.ctx
73-
.new_str(format!("getpwuid(): uid not found: {}", uid.as_bigint()))
74-
.into();
75-
Err(vm.new_key_error(message))
53+
#[pyfunction]
54+
fn getpwnam(name: PyStrRef, vm: &VirtualMachine) -> PyResult<Passwd> {
55+
match User::from_name(name.as_str()).map_err(|err| err.into_pyexception(vm))? {
56+
Some(user) => Ok(Passwd::from(user)),
57+
None => {
58+
let name_repr = vm.to_repr(name.as_object())?;
59+
let message = vm
60+
.ctx
61+
.new_str(format!("getpwnam(): name not found: {}", name_repr))
62+
.into();
63+
Err(vm.new_key_error(message))
64+
}
7665
}
7766
}
78-
}
79-
80-
// TODO: maybe merge this functionality into nix?
81-
fn pwd_getpwall(vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
82-
// setpwent, getpwent, etc are not thread safe. Could use fgetpwent_r, but this is easier
83-
static GETPWALL: parking_lot::Mutex<()> = parking_lot::const_mutex(());
84-
let _guard = GETPWALL.lock();
85-
let mut list = Vec::new();
8667

87-
unsafe { libc::setpwent() };
88-
while let Some(ptr) = NonNull::new(unsafe { libc::getpwent() }) {
89-
let user = User::from(unsafe { ptr.as_ref() });
90-
let passwd = Passwd::from(user).into_pyobject(vm);
91-
list.push(passwd);
68+
#[pyfunction]
69+
fn getpwuid(uid: PyIntRef, vm: &VirtualMachine) -> PyResult<Passwd> {
70+
let uid_t = libc::uid_t::try_from(uid.as_bigint()).map(unistd::Uid::from_raw);
71+
let user = match uid_t {
72+
Ok(uid) => User::from_uid(uid).map_err(|err| err.into_pyexception(vm))?,
73+
Err(_) => None,
74+
};
75+
match user {
76+
Some(user) => Ok(Passwd::from(user)),
77+
None => {
78+
let message = vm
79+
.ctx
80+
.new_str(format!("getpwuid(): uid not found: {}", uid.as_bigint()))
81+
.into();
82+
Err(vm.new_key_error(message))
83+
}
84+
}
9285
}
93-
unsafe { libc::endpwent() };
9486

95-
Ok(list)
96-
}
87+
// TODO: maybe merge this functionality into nix?
88+
#[pyfunction]
89+
fn getpwall(vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
90+
// setpwent, getpwent, etc are not thread safe. Could use fgetpwent_r, but this is easier
91+
static GETPWALL: parking_lot::Mutex<()> = parking_lot::const_mutex(());
92+
let _guard = GETPWALL.lock();
93+
let mut list = Vec::new();
9794

98-
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
99-
let ctx = &vm.ctx;
95+
unsafe { libc::setpwent() };
96+
while let Some(ptr) = NonNull::new(unsafe { libc::getpwent() }) {
97+
let user = User::from(unsafe { ptr.as_ref() });
98+
let passwd = Passwd::from(user).into_pyobject(vm);
99+
list.push(passwd);
100+
}
101+
unsafe { libc::endpwent() };
100102

101-
py_module!(vm, "pwd", {
102-
"struct_passwd" => Passwd::make_class(ctx),
103-
"getpwnam" => named_function!(ctx, pwd, getpwnam),
104-
"getpwuid" => named_function!(ctx, pwd, getpwuid),
105-
"getpwall" => named_function!(ctx, pwd, getpwall),
106-
})
103+
Ok(list)
104+
}
107105
}

0 commit comments

Comments
 (0)