summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md9
-rw-r--r--src/unistd.rs56
-rw-r--r--test/test_unistd.rs8
3 files changed, 70 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index be255211..97268ef2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,9 +8,12 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Added `TimeSpec::from_duration` and `TimeSpec::from_timespec`
(#[1465](https://github.com/nix-rust/nix/pull/1465))
-
- Added `IPV6_V6ONLY` sockopt.
(#[1470](https://github.com/nix-rust/nix/pull/1470))
+- Added `impl From<User> for libc::passwd` trait implementation to convert a `User`
+ into a `libc::passwd`. Consumes the `User` struct to give ownership over
+ the member pointers.
+ (#[1471](https://github.com/nix-rust/nix/pull/1471))
- Added `pthread_kill`.
(#[1472](https://github.com/nix-rust/nix/pull/1472))
@@ -18,6 +21,10 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- `FdSet::{contains, highest, fds}` no longer require a mutable reference.
(#[1464](https://github.com/nix-rust/nix/pull/1464))
+- `User::gecos` and corresponding `libc::passwd::pw_gecos` are supported on
+ 64-bit Android, change conditional compilation to include the field in
+ 64-bit Android builds
+ (#[1471](https://github.com/nix-rust/nix/pull/1471))
### Fixed
diff --git a/src/unistd.rs b/src/unistd.rs
index 268c9994..1cba0303 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -2629,7 +2629,7 @@ pub struct User {
/// Group ID
pub gid: Gid,
/// User information
- #[cfg(not(target_os = "android"))]
+ #[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
pub gecos: CString,
/// Home directory
pub dir: PathBuf,
@@ -2665,7 +2665,7 @@ impl From<&libc::passwd> for User {
User {
name: CStr::from_ptr((*pw).pw_name).to_string_lossy().into_owned(),
passwd: CString::new(CStr::from_ptr((*pw).pw_passwd).to_bytes()).unwrap(),
- #[cfg(not(target_os = "android"))]
+ #[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
gecos: CString::new(CStr::from_ptr((*pw).pw_gecos).to_bytes()).unwrap(),
dir: PathBuf::from(OsStr::from_bytes(CStr::from_ptr((*pw).pw_dir).to_bytes())),
shell: PathBuf::from(OsStr::from_bytes(CStr::from_ptr((*pw).pw_shell).to_bytes())),
@@ -2695,6 +2695,58 @@ impl From<&libc::passwd> for User {
}
#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
+impl From<User> for libc::passwd {
+ fn from(u: User) -> Self {
+ let name = match CString::new(u.name) {
+ Ok(n) => n.into_raw(),
+ Err(_) => CString::new("").unwrap().into_raw(),
+ };
+ let dir = match u.dir.into_os_string().into_string() {
+ Ok(s) => CString::new(s.as_str()).unwrap().into_raw(),
+ Err(_) => CString::new("").unwrap().into_raw(),
+ };
+ let shell = match u.shell.into_os_string().into_string() {
+ Ok(s) => CString::new(s.as_str()).unwrap().into_raw(),
+ Err(_) => CString::new("").unwrap().into_raw(),
+ };
+ Self {
+ pw_name: name,
+ pw_passwd: u.passwd.into_raw(),
+ #[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
+ pw_gecos: u.gecos.into_raw(),
+ pw_dir: dir,
+ pw_shell: shell,
+ pw_uid: u.uid.0,
+ pw_gid: u.gid.0,
+ #[cfg(not(any(target_os = "android",
+ target_os = "fuchsia",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris")))]
+ pw_class: u.class.into_raw(),
+ #[cfg(not(any(target_os = "android",
+ target_os = "fuchsia",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris")))]
+ pw_change: u.change,
+ #[cfg(not(any(target_os = "android",
+ target_os = "fuchsia",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris")))]
+ pw_expire: u.expire,
+ #[cfg(target_os = "illumos")]
+ pw_age: CString::new("").unwrap().into_raw(),
+ #[cfg(target_os = "illumos")]
+ pw_comment: CString::new("").unwrap().into_raw(),
+ #[cfg(target_os = "freebsd")]
+ pw_fields: 0,
+ }
+ }
+}
+
+#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
impl User {
fn from_anything<F>(f: F) -> Result<Option<Self>>
where
diff --git a/test/test_unistd.rs b/test/test_unistd.rs
index b95f1549..984dd2c9 100644
--- a/test/test_unistd.rs
+++ b/test/test_unistd.rs
@@ -1025,6 +1025,14 @@ fn test_access_file_exists() {
assert!(access(&path, AccessFlags::R_OK | AccessFlags::W_OK).is_ok());
}
+#[test]
+fn test_user_into_passwd() {
+ // get the UID of the "nobody" user
+ let nobody = User::from_name("nobody").unwrap().unwrap();
+ let pwd: libc::passwd = nobody.into();
+ let _: User = (&pwd).into();
+}
+
/// Tests setting the filesystem UID with `setfsuid`.
#[cfg(any(target_os = "linux", target_os = "android"))]
#[test]