annotate src/libpam/memory.rs @ 171:e27c5c667a5a

Create full new types for return code and flags, separate end to end. This plumbs the ReturnCode and RawFlags types through the places where we call into or are called from PAM. Also adds Sun documentation to the project.
author Paul Fisher <paul@pfish.zone>
date Fri, 25 Jul 2025 20:52:14 -0400
parents 634cd5f2ac8b
children a1bb1d013567
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
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
12 /// Allocates `count` elements to hold `T`.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
13 #[inline]
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
14 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
15 // 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
16 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
17 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
18
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
19 /// 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
20 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
21 /// # Safety
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
22 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
23 /// 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
24 #[inline]
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
25 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
26 libc::free(p.cast())
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
27 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
28
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
29 /// 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
30 #[repr(C)]
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
31 #[derive(Debug, Default)]
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
32 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
33
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
34 /// 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
35 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
36 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
37 }
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
38
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
39 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
40 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
41 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
42
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
43 /// 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
44 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
45 match prompt {
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
46 Some(c_str) => c_str.as_ptr(),
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
47 None => ptr::null(),
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
48 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
49 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
50
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
51 /// 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
52 #[derive(Debug)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
53 #[repr(transparent)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
54 pub struct CHeapBox<T>(NonNull<T>);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
55
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
56 // 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
57 #[allow(clippy::wrong_self_convention)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
58 impl<T> CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
59 /// 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
60 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
61 let memory = calloc(1);
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
62 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
63 // SAFETY: We literally just allocated this.
141
a508a69c068a Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
64 Self(memory)
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
65 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
66
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
67 /// Takes ownership of the given pointer.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
68 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
69 /// # Safety
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
70 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
71 /// 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
72 /// that was made with `malloc`.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
73 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
74 Self(ptr)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
75 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
76
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
77 /// 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
78 pub fn into_ptr(this: Self) -> NonNull<T> {
100
3f11b8d30f63 Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents: 98
diff changeset
79 ManuallyDrop::new(this).0
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
80 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
81
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
82 /// 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
83 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
84 /// 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
85 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
86 this.0
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
87 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
88
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
89 /// 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
90 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
91 this.0.as_ptr()
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
92 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
93
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
94 /// 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
95 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
96 /// # Safety
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
97 ///
141
a508a69c068a Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
98 /// 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
99 /// 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
100 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
101 mem::transmute(this)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
102 }
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
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
105 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
106 fn default() -> Self {
141
a508a69c068a Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
107 Self::new(Default::default())
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
108 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
109 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
110
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
111 impl Buffer for CHeapBox<u8> {
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
112 fn allocate(len: usize) -> Self {
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
113 // 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
114 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
115 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
116
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
117 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
118 this.0.as_ptr()
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
119 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
120
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
121 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
122 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
123 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
124
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
125 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
126 CHeapBox::into_ptr(this)
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
127 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
128
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
129 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
130 CHeapBox::from_ptr(ptr)
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
131 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
132 }
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
133
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
134 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
135
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
136 impl<T> Deref for CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
137 type Target = T;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
138 fn deref(&self) -> &Self::Target {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
139 // 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
140 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
141 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
142 }
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 impl<T> DerefMut for CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
145 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
146 // 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
147 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
148 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
149 }
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 impl<T> Drop for CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
152 fn drop(&mut self) {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
153 // 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
154 unsafe {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
155 let ptr = self.0.as_ptr();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
156 ptr::drop_in_place(ptr);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
157 free(ptr)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
158 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
159 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
160 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
161
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
162 /// 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
163 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
164 /// Basically [`CString`], but managed by malloc.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
165 #[derive(Debug)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
166 #[repr(transparent)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
167 pub struct CHeapString(CHeapBox<c_char>);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
168
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
169 impl CHeapString {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
170 /// 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
171 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
172 let data = text.as_ref();
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
173 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
174 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
175 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
176 // +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
177 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
178 // 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
179 unsafe {
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
180 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
181 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
182 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
183 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
184 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
185
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
186 /// 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
187 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
188 /// 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
189 pub fn into_ptr(self) -> NonNull<c_char> {
100
3f11b8d30f63 Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents: 98
diff changeset
190 let this = ManuallyDrop::new(self);
3f11b8d30f63 Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents: 98
diff changeset
191 CHeapBox::as_ptr(&this.0)
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
192 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
193
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
194 /// 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
195 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
196 unsafe { mem::transmute(self) }
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 /// 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
200 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
201 /// # Safety
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
202 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
203 /// 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
204 /// 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
205 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
206 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
207 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
208
159
634cd5f2ac8b Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents: 148
diff changeset
209 /// 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
210 ///
634cd5f2ac8b Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents: 148
diff changeset
211 /// # Safety
634cd5f2ac8b Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents: 148
diff changeset
212 ///
634cd5f2ac8b Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents: 148
diff changeset
213 /// 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
214 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
215 Self(CHeapBox::cast(bx))
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
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
218 /// 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
219 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
220 /// # Safety
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
221 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
222 /// 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
223 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
224 let cstr = ptr.as_ptr();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
225 let len = libc::strlen(cstr.cast());
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
226 for x in 0..len {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
227 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
228 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
229 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
230 }
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 impl Drop for CHeapString {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
233 fn drop(&mut self) {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
234 // 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
235 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
236 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
237 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
238
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
239 impl Deref for CHeapString {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
240 type Target = CStr;
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 fn deref(&self) -> &Self::Target {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
243 // 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
244 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
245 unsafe { CStr::from_ptr(ptr) }
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 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
248
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
249 /// 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
250 /// <code>pam_get_<var>whatever</var></code> function.
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
251 ///
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
252 /// # Safety
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
253 ///
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
254 /// 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
255 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
256 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
257 .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
258 .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
259 .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
260 .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
261 .map(OsString::from_vec)
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
262 }
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
263
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
264 #[cfg(test)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
265 mod tests {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
266 use super::*;
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
267 use std::cell::Cell;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
268 #[test]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
269 fn test_box() {
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
270 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
271
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
272 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
273
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
274 impl Drop for Dropper<'_> {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
275 fn drop(&mut self) {
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
276 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
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
141
a508a69c068a Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents: 139
diff changeset
280 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
281 _ = dropbox;
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
282 // 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
283 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
284 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
285 *dropbox = Dropper(&drop_count);
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
286 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
287 drop(dropbox);
139
33b9622ed6d2 Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents: 106
diff changeset
288 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
289 }
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
290
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
291 #[test]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
292 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
293 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
294 let str_ptr = str.into_ptr().as_ptr();
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
295 unsafe {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
296 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
297 assert_eq!("hello there", copied);
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
298 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
299 let idx_three = str_ptr.add(3).as_mut().unwrap();
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
300 *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
301 let zeroed = copy_pam_string(str_ptr).unwrap();
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
302 assert!(zeroed.is_empty());
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
303 let _ = CHeapString::from_ptr(str_ptr);
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
304 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
305 }
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
306
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
307 #[test]
143
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
308 #[should_panic]
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
309 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
310 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
311 }
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
312
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
313 #[test]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
314 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
315 let good = option_cstr(Some("whatever".as_ref()));
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
316 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
317 let no_str = option_cstr(None);
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
318 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
319 }
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
320 #[test]
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
321 #[should_panic]
ebb71a412b58 Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents: 141
diff changeset
322 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
323 option_cstr(Some("what\0ever".as_ref()));
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
324 }
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
325
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
326 #[test]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
327 fn test_prompt() {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
328 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
329 let prompt = prompt_ptr(prompt_cstr.as_deref());
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
330 assert!(!prompt.is_null());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
331 let no_prompt = prompt_ptr(None);
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
332 assert!(no_prompt.is_null());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
333 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
334 }