annotate src/libpam/memory.rs @ 189:b2456d274576 default tip

Add line breaks that rustfmt ate back to documentation.
author Paul Fisher <paul@pfish.zone>
date Thu, 31 Jul 2025 15:42:12 -0400
parents 5e4ea9650f87
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
1 //! Things for dealing with memory.
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
2
148
4b3a5095f68c Move libpam-sys helpers into their own library.
Paul Fisher <paul@pfish.zone>
parents: 143
diff changeset
3 use libpam_sys_helpers::{Buffer, OwnedBinaryPayload};
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
4 use std::ffi::{c_char, CStr, CString, OsStr, OsString};
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
5 use std::marker::{PhantomData, PhantomPinned};
106
49d9e2b5c189 An irresponsible mix of implementing libpam-sys and other stuff.
Paul Fisher <paul@pfish.zone>
parents: 105
diff changeset
6 use std::mem::ManuallyDrop;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
7 use std::ops::{Deref, DerefMut};
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
8 use std::os::unix::ffi::{OsStrExt, OsStringExt};
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
9 use std::ptr::NonNull;
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
10 use std::{mem, ptr, slice};
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
11
180
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
12 /// Like the num_enum crate, but with no dependency on `syn`.
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
13 macro_rules! num_enum {
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
14 (
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
15 $(#[$m:meta])*
185
fb8b547b36b7 Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents: 180
diff changeset
16 $viz:vis enum $name:ident {
180
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
17 $(
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
18 $(#[$im:meta])*
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
19 $item_name:ident = $item_value:path,
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
20 )*
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
21 }
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
22 ) => {
185
fb8b547b36b7 Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents: 180
diff changeset
23 // This is the one place where we depend upon c_int being i32.
fb8b547b36b7 Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents: 180
diff changeset
24 // Ideally, we would be able to say `repr(c_int)` but we can't.
180
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
25 $(#[$m])*
186
5e4ea9650f87 Derive `hash` where it makes sense.
Paul Fisher <paul@pfish.zone>
parents: 185
diff changeset
26 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
185
fb8b547b36b7 Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents: 180
diff changeset
27 #[repr(i32)]
180
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
28 $viz enum $name {
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
29 $(
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
30 $(#[$im])*
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
31 $item_name = $item_value,
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
32 )*
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
33 }
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
34
185
fb8b547b36b7 Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents: 180
diff changeset
35 impl TryFrom<c_int> for $name {
180
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
36 type Error = crate::constants::ErrorCode;
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
37
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
38 #[allow(unused_doc_comments)]
185
fb8b547b36b7 Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents: 180
diff changeset
39 fn try_from(value: c_int) -> crate::constants::Result<$name> {
180
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
40 match value {
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
41 $(
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
42 $(#[$im])*
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
43 $item_value => Ok(Self::$item_name),
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
44 )*
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
45 _ => Err(crate::constants::ErrorCode::BAD_CONST),
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
46 }
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
47 }
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
48 }
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
49
185
fb8b547b36b7 Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents: 180
diff changeset
50 impl From<$name> for c_int {
fb8b547b36b7 Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents: 180
diff changeset
51 fn from(value: $name) -> c_int {
fb8b547b36b7 Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents: 180
diff changeset
52 value as c_int
180
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
53 }
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
54 }
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
55 }
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
56 }
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
57
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
58 pub(crate) use num_enum;
a1bb1d013567 Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents: 159
diff changeset
59
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
60 /// Allocates `count` elements to hold `T`.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
61 #[inline]
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
62 pub fn calloc<T>(count: usize) -> NonNull<T> {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
63 // SAFETY: it's always safe to allocate! Leaking memory is fun!
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
64 unsafe { NonNull::new_unchecked(libc::calloc(count, mem::size_of::<T>()).cast()) }
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
65 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
66
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
67 /// Wrapper for [`libc::free`] to make debugging calls/frees easier.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
68 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
69 /// # Safety
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
70 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
71 /// If you double-free, it's all your fault.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
72 #[inline]
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
73 pub unsafe fn free<T>(p: *mut T) {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
74 libc::free(p.cast())
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
75 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
76
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
77 /// Makes whatever it's in not [`Send`], [`Sync`], or [`Unpin`].
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
78 #[repr(C)]
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
79 #[derive(Debug, Default)]
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
80 pub struct Immovable(pub PhantomData<(*mut u8, PhantomPinned)>);
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
81
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
82 /// Safely converts a `&str` option to a `CString` option.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
83 pub fn option_cstr(prompt: Option<&[u8]>) -> Option<CString> {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
84 prompt.map(|p| CString::new(p).expect("nul is not allowed"))
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
85 }
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
86
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
87 pub fn option_cstr_os(prompt: Option<&OsStr>) -> Option<CString> {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
88 option_cstr(prompt.map(OsStr::as_bytes))
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
89 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
90
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
91 /// Gets the pointer to the given CString, or a null pointer if absent.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
92 pub fn prompt_ptr(prompt: Option<&CStr>) -> *const c_char {
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
93 match prompt {
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
94 Some(c_str) => c_str.as_ptr(),
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
95 None => ptr::null(),
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
96 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
97 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
98
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
99 /// It's like a [`Box`], but C heap managed.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
100 #[derive(Debug)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
101 #[repr(transparent)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
102 pub struct CHeapBox<T>(NonNull<T>);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
103
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
104 // Lots of "as" and "into" associated functions.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
105 #[allow(clippy::wrong_self_convention)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
106 impl<T> CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
107 /// Creates a new CHeapBox holding the given data.
141
a508a69c068a Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
108 pub fn new(value: T) -> Self {
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
109 let memory = calloc(1);
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
110 unsafe { ptr::write(memory.as_ptr(), value) }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
111 // SAFETY: We literally just allocated this.
141
a508a69c068a Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
112 Self(memory)
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
113 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
114
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
115 /// Takes ownership of the given pointer.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
116 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
117 /// # Safety
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
118 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
119 /// You have to provide a valid pointer to the start of an allocation
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
120 /// that was made with `malloc`.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
121 pub unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
122 Self(ptr)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
123 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
124
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
125 /// Converts this CBox into a raw pointer.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
126 pub fn into_ptr(this: Self) -> NonNull<T> {
100
3f11b8d30f63 Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents: 98
diff changeset
127 ManuallyDrop::new(this).0
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
128 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
129
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
130 /// Gets a pointer from this but doesn't convert this into a raw pointer.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
131 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
132 /// You are responsible for ensuring the CHeapBox lives long enough.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
133 pub fn as_ptr(this: &Self) -> NonNull<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
134 this.0
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
135 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
136
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
137 /// Because it's annoying to type `CHeapBox.as_ptr(...).as_ptr()`.
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
138 pub fn as_raw_ptr(this: &Self) -> *mut T {
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
139 this.0.as_ptr()
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
140 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
141
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
142 /// Converts this into a Box of a different type.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
143 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
144 /// # Safety
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
145 ///
141
a508a69c068a Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
146 /// The other type has to have the same size and alignment and
a508a69c068a Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
147 /// have compatible drop behavior with respect to other resources.
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
148 pub unsafe fn cast<R>(this: Self) -> CHeapBox<R> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
149 mem::transmute(this)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
150 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
151 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
152
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
153 impl<T: Default> Default for CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
154 fn default() -> Self {
141
a508a69c068a Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
155 Self::new(Default::default())
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
156 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
157 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
158
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
159 impl Buffer for CHeapBox<u8> {
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
160 fn allocate(len: usize) -> Self {
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
161 // SAFETY: This is all freshly-allocated memory!
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
162 unsafe { Self::from_ptr(calloc(len)) }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
163 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
164
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
165 fn as_ptr(this: &Self) -> *const u8 {
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
166 this.0.as_ptr()
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
167 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
168
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
169 unsafe fn as_mut_slice(this: &mut Self, len: usize) -> &mut [u8] {
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
170 slice::from_raw_parts_mut(this.0.as_ptr(), len)
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
171 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
172
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
173 fn into_ptr(this: Self) -> NonNull<u8> {
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
174 CHeapBox::into_ptr(this)
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
175 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
176
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
177 unsafe fn from_ptr(ptr: NonNull<u8>, _: usize) -> Self {
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
178 CHeapBox::from_ptr(ptr)
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
179 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
180 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
181
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
182 pub type CHeapPayload = OwnedBinaryPayload<CHeapBox<u8>>;
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
183
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
184 impl<T> Deref for CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
185 type Target = T;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
186 fn deref(&self) -> &Self::Target {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
187 // SAFETY: We own this pointer and it is guaranteed valid.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
188 unsafe { Self::as_ptr(self).as_ref() }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
189 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
190 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
191
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
192 impl<T> DerefMut for CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
193 fn deref_mut(&mut self) -> &mut Self::Target {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
194 // SAFETY: We own this pointer and it is guaranteed valid.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
195 unsafe { Self::as_ptr(self).as_mut() }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
196 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
197 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
198
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
199 impl<T> Drop for CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
200 fn drop(&mut self) {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
201 // SAFETY: We own a valid pointer, and will never use it after this.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
202 unsafe {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
203 let ptr = self.0.as_ptr();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
204 ptr::drop_in_place(ptr);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
205 free(ptr)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
206 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
207 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
208 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
209
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
210 /// A null-terminated string allocated on the C heap.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
211 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
212 /// Basically [`CString`], but managed by malloc.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
213 #[derive(Debug)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
214 #[repr(transparent)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
215 pub struct CHeapString(CHeapBox<c_char>);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
216
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
217 impl CHeapString {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
218 /// Creates a new C heap string with the given contents.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
219 pub fn new(text: impl AsRef<[u8]>) -> Self {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
220 let data = text.as_ref();
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
221 if data.contains(&0) {
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
222 panic!("you're not allowed to create a cstring with a nul inside!");
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
223 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
224 // +1 for the null terminator
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
225 let data_alloc: NonNull<c_char> = calloc(data.len() + 1);
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
226 // SAFETY: we just allocated this and we have enough room.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
227 unsafe {
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
228 let dest = slice::from_raw_parts_mut(data_alloc.as_ptr().cast(), data.len());
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
229 dest.copy_from_slice(data);
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
230 Self(CHeapBox::from_ptr(data_alloc))
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
231 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
232 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
233
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
234 /// Converts this C heap string into a raw pointer.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
235 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
236 /// You are responsible for freeing it later.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
237 pub fn into_ptr(self) -> NonNull<c_char> {
100
3f11b8d30f63 Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents: 98
diff changeset
238 let this = ManuallyDrop::new(self);
3f11b8d30f63 Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents: 98
diff changeset
239 CHeapBox::as_ptr(&this.0)
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
240 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
241
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
242 /// Converts this into a dumb box. It will no longer be zeroed upon drop.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
243 pub fn into_box(self) -> CHeapBox<c_char> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
244 unsafe { mem::transmute(self) }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
245 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
246
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
247 /// Takes ownership of a C heap string.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
248 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
249 /// # Safety
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
250 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
251 /// You have to provide a pointer to the start of an allocation that is
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
252 /// a valid 0-terminated C string.
159
634cd5f2ac8b Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents: 148
diff changeset
253 pub unsafe fn from_ptr(ptr: *mut c_char) -> Option<Self> {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
254 NonNull::new(ptr).map(|p| unsafe { Self(CHeapBox::from_ptr(p)) })
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
255 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
256
159
634cd5f2ac8b Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents: 148
diff changeset
257 /// Takes ownership of a CHeapBox.
634cd5f2ac8b Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents: 148
diff changeset
258 ///
634cd5f2ac8b Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents: 148
diff changeset
259 /// # Safety
634cd5f2ac8b Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents: 148
diff changeset
260 ///
634cd5f2ac8b Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents: 148
diff changeset
261 /// The box has to point to a valid 0-terminated C string.
634cd5f2ac8b Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents: 148
diff changeset
262 pub unsafe fn from_box<T>(bx: CHeapBox<T>) -> Self {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
263 Self(CHeapBox::cast(bx))
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
264 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
265
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
266 /// Zeroes the contents of a C string.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
267 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
268 /// # Safety
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
269 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
270 /// You have to provide a valid pointer to a null-terminated C string.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
271 pub unsafe fn zero(ptr: NonNull<c_char>) {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
272 let cstr = ptr.as_ptr();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
273 let len = libc::strlen(cstr.cast());
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
274 for x in 0..len {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
275 ptr::write_volatile(cstr.byte_offset(x as isize), mem::zeroed())
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
276 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
277 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
278 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
279
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
280 impl Drop for CHeapString {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
281 fn drop(&mut self) {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
282 // SAFETY: We own a valid C String
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
283 unsafe { Self::zero(CHeapBox::as_ptr(&self.0)) }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
284 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
285 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
286
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
287 impl Deref for CHeapString {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
288 type Target = CStr;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
289
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
290 fn deref(&self) -> &Self::Target {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
291 // SAFETY: We know we own a valid C string pointer.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
292 let ptr = CHeapBox::as_ptr(&self.0).as_ptr();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
293 unsafe { CStr::from_ptr(ptr) }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
294 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
295 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
296
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
297 /// Creates an owned copy of a string that is returned from a
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
298 /// <code>pam_get_<var>whatever</var></code> function.
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
299 ///
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
300 /// # Safety
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
301 ///
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
302 /// It's on you to provide a valid string.
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
303 pub unsafe fn copy_pam_string(result_ptr: *const c_char) -> Option<OsString> {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
304 NonNull::new(result_ptr.cast_mut())
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
305 .map(NonNull::as_ptr)
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
306 .map(|p| CStr::from_ptr(p))
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
307 .map(CStr::to_bytes)
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
308 .map(Vec::from)
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
309 .map(OsString::from_vec)
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
310 }
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
311
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
312 #[cfg(test)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
313 mod tests {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
314 use super::*;
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
315 use std::cell::Cell;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
316 #[test]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
317 fn test_box() {
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
318 let drop_count: Cell<u32> = Cell::new(0);
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
319
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
320 struct Dropper<'a>(&'a Cell<u32>);
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
321
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
322 impl Drop for Dropper<'_> {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
323 fn drop(&mut self) {
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
324 self.0.set(self.0.get() + 1)
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
325 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
326 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
327
141
a508a69c068a Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
328 let mut dropbox = CHeapBox::new(Dropper(&drop_count));
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
329 _ = dropbox;
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
330 // ensure the old value is dropped when the new one is assigned.
141
a508a69c068a Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
331 dropbox = CHeapBox::new(Dropper(&drop_count));
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
332 assert_eq!(1, drop_count.get());
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
333 *dropbox = Dropper(&drop_count);
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
334 assert_eq!(2, drop_count.get());
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
335 drop(dropbox);
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
336 assert_eq!(3, drop_count.get());
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
337 }
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
338
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
339 #[test]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
340 fn test_strings() {
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
341 let str = CHeapString::new("hello there");
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
342 let str_ptr = str.into_ptr().as_ptr();
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
343 unsafe {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
344 let copied = copy_pam_string(str_ptr).unwrap();
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
345 assert_eq!("hello there", copied);
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
346 CHeapString::zero(NonNull::new(str_ptr).unwrap());
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
347 let idx_three = str_ptr.add(3).as_mut().unwrap();
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
348 *idx_three = 0x80u8 as i8;
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
349 let zeroed = copy_pam_string(str_ptr).unwrap();
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
350 assert!(zeroed.is_empty());
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
351 let _ = CHeapString::from_ptr(str_ptr);
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
352 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
353 }
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
354
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
355 #[test]
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
356 #[should_panic]
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
357 fn test_nul_string() {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
358 CHeapString::new("hell\0 there");
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
359 }
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
360
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
361 #[test]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
362 fn test_option_str() {
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
363 let good = option_cstr(Some("whatever".as_ref()));
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
364 assert_eq!("whatever", good.unwrap().to_str().unwrap());
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
365 let no_str = option_cstr(None);
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
366 assert!(no_str.is_none());
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
367 }
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
368 #[test]
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
369 #[should_panic]
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
370 fn test_nul_cstr() {
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
371 option_cstr(Some("what\0ever".as_ref()));
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
372 }
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
373
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
374 #[test]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
375 fn test_prompt() {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
376 let prompt_cstr = CString::new("good").ok();
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
377 let prompt = prompt_ptr(prompt_cstr.as_deref());
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
378 assert!(!prompt.is_null());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
379 let no_prompt = prompt_ptr(None);
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
380 assert!(no_prompt.is_null());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
381 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
382 }