diff options
-rw-r--r-- | CHANGELOG.md | 9 | ||||
-rw-r--r-- | src/unistd.rs | 56 | ||||
-rw-r--r-- | test/test_unistd.rs | 8 |
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] |