annotate src/libpam/memory.rs @ 99:8840fa6534f6

Streamline dependencies and rename to openpam-extensions.
author Paul Fisher <paul@pfish.zone>
date Tue, 24 Jun 2025 14:54:47 -0400
parents b87100c5eed4
children 3f11b8d30f63
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
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
3 use crate::Result;
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
4 use crate::{BinaryData, ErrorCode};
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
5 use std::error::Error;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
6 use std::ffi::{c_char, CStr, CString};
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
7 use std::fmt::{Display, Formatter, Result as FmtResult};
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
8 use std::marker::{PhantomData, PhantomPinned};
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
9 use std::mem::offset_of;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
10 use std::ops::{Deref, DerefMut};
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
11 use std::ptr::NonNull;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
12 use std::result::Result as StdResult;
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
13 use std::{mem, ptr, slice};
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
14
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
15 /// Raised from `calloc` when you have no memory!
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
16 #[derive(Debug)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
17 pub struct NoMem;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
18
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
19 impl Display for NoMem {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
20 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
21 write!(f, "out of memory!")
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
22 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
23 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
24
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
25 impl Error for NoMem {}
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
26
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
27 impl From<NoMem> for ErrorCode {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
28 fn from(_: NoMem) -> Self {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
29 ErrorCode::BufferError
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
30 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
31 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
32
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
33 /// Allocates `count` elements to hold `T`.
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
34 #[inline]
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
35 pub fn calloc<T>(count: usize) -> StdResult<NonNull<T>, NoMem> {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
36 // SAFETY: it's always safe to allocate! Leaking memory is fun!
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
37 NonNull::new(unsafe { libc::calloc(count, size_of::<T>()) }.cast()).ok_or(NoMem)
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
38 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
39
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
40 /// 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
41 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
42 /// # Safety
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
43 ///
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
44 /// 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
45 #[inline]
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
46 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
47 libc::free(p.cast())
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
48 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
49
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
50 /// 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
51 #[repr(C)]
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
52 #[derive(Debug, Default)]
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
53 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
54
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
55 /// Safely converts a `&str` option to a `CString` option.
64
bbe84835d6db More organization; add lots of docs.
Paul Fisher <paul@pfish.zone>
parents: 60
diff changeset
56 pub fn option_cstr(prompt: Option<&str>) -> Result<Option<CString>> {
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
57 prompt
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
58 .map(CString::new)
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
59 .transpose()
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
60 .map_err(|_| ErrorCode::ConversationError)
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
61 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
62
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
63 /// Gets the pointer to the given CString, or a null pointer if absent.
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
64 pub fn prompt_ptr(prompt: Option<&CString>) -> *const c_char {
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
65 match prompt {
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
66 Some(c_str) => c_str.as_ptr(),
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
67 None => ptr::null(),
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
68 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
69 }
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
70
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
71 /// 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
72 #[derive(Debug)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
73 #[repr(transparent)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
74 pub struct CHeapBox<T>(NonNull<T>);
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 // 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
77 #[allow(clippy::wrong_self_convention)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
78 impl<T> CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
79 /// Creates a new CHeapBox holding the given data.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
80 pub fn new(value: T) -> Result<Self> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
81 let memory = calloc(1)?;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
82 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
83 // SAFETY: We literally just allocated this.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
84 Ok(Self(memory))
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
85 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
86
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
87 /// Takes ownership of the given pointer.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
88 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
89 /// # Safety
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
90 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
91 /// 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
92 /// that was made with `malloc`.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
93 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
94 Self(ptr)
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
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
97 /// 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
98 pub fn into_ptr(this: Self) -> NonNull<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
99 let ret = this.0;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
100 mem::forget(this);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
101 ret
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 /// 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
105 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
106 /// 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
107 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
108 this.0
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
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
111 /// 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
112 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
113 /// # Safety
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 /// The different type has to be compatible in size/alignment and drop behavior.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
116 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
117 mem::transmute(this)
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 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
120
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
121 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
122 fn default() -> Self {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
123 Self::new(Default::default()).expect("allocation should not fail")
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 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
126
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
127 impl<T> Deref for CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
128 type Target = T;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
129 fn deref(&self) -> &Self::Target {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
130 // 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
131 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
132 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
133 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
134
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
135 impl<T> DerefMut for CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
136 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
137 // 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
138 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
139 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
140 }
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 impl<T> Drop for CHeapBox<T> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
143 fn drop(&mut self) {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
144 // 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
145 unsafe {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
146 let ptr = self.0.as_ptr();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
147 ptr::drop_in_place(ptr);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
148 free(ptr)
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 }
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 /// 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
154 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
155 /// Basically [`CString`], but managed by malloc.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
156 #[derive(Debug)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
157 #[repr(transparent)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
158 pub struct CHeapString(CHeapBox<c_char>);
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 impl CHeapString {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
161 /// Creates a new C heap string with the given contents.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
162 pub fn new(text: &str) -> Result<Self> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
163 let data = text.as_bytes();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
164 if data.contains(&0) {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
165 return Err(ErrorCode::ConversationError);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
166 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
167 // +1 for the null terminator
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
168 let data_alloc: NonNull<c_char> = calloc(data.len() + 1)?;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
169 // 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
170 unsafe {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
171 libc::memcpy(data_alloc.as_ptr().cast(), data.as_ptr().cast(), data.len());
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
172 Ok(Self(CHeapBox::from_ptr(data_alloc)))
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
173 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
174 }
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 /// 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
177 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
178 /// 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
179 pub fn into_ptr(self) -> NonNull<c_char> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
180 let ptr = CHeapBox::as_ptr(&self.0);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
181 mem::forget(self);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
182 ptr
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 /// 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
186 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
187 unsafe { mem::transmute(self) }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
188 }
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 /// 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
191 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
192 /// # Safety
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 /// 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
195 /// a valid 0-terminated C string.
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
196 unsafe fn from_ptr(ptr: *mut c_char) -> Option<Self> {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
197 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
198 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
199
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
200 unsafe fn from_box<T>(bx: CHeapBox<T>) -> Self {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
201 Self(CHeapBox::cast(bx))
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
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
204 /// 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
205 ///
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
206 /// # Safety
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 /// 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
209 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
210 let cstr = ptr.as_ptr();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
211 let len = libc::strlen(cstr.cast());
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
212 for x in 0..len {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
213 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
214 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
215 }
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 impl Drop for CHeapString {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
219 fn drop(&mut self) {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
220 // 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
221 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
222 }
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
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
225 impl Deref for CHeapString {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
226 type Target = CStr;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
227
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
228 fn deref(&self) -> &Self::Target {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
229 // 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
230 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
231 unsafe { CStr::from_ptr(ptr) }
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
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
235 /// 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
236 /// <code>pam_get_<var>whatever</var></code> function.
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
237 ///
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
238 /// # Safety
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
239 ///
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
240 /// It's on you to provide a valid string.
95
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
241 pub unsafe fn copy_pam_string(result_ptr: *const c_char) -> Result<Option<String>> {
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
242 let borrowed = match NonNull::new(result_ptr.cast_mut()) {
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
243 Some(data) => Some(
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
244 CStr::from_ptr(data.as_ptr())
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
245 .to_str()
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
246 .map_err(|_| ErrorCode::ConversationError)?,
95
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
247 ),
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
248 None => return Ok(None),
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
249 };
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
250 Ok(borrowed.map(String::from))
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
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
253 /// Binary data used in requests and responses.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
254 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
255 /// This is an unsized data type whose memory goes beyond its data.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
256 /// This must be allocated on the C heap.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
257 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
258 /// A Linux-PAM extension.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
259 #[repr(C)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
260 pub struct CBinaryData {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
261 /// The total length of the structure; a u32 in network byte order (BE).
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
262 total_length: [u8; 4],
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
263 /// A tag of undefined meaning.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
264 data_type: u8,
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
265 /// Pointer to an array of length [`length`](Self::length) − 5
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
266 data: [u8; 0],
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
267 _marker: Immovable,
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
268 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
269
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
270 impl CBinaryData {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
271 /// Copies the given data to a new BinaryData on the heap.
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
272 pub fn alloc((data, data_type): (&[u8], u8)) -> Result<CHeapBox<CBinaryData>> {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
273 let buffer_size =
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
274 u32::try_from(data.len() + 5).map_err(|_| ErrorCode::ConversationError)?;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
275 // SAFETY: We're only allocating here.
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
276 unsafe {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
277 let mut dest_buffer: NonNull<Self> = calloc::<u8>(buffer_size as usize)?.cast();
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
278 let dest = dest_buffer.as_mut();
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
279 dest.total_length = buffer_size.to_be_bytes();
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
280 dest.data_type = data_type;
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
281 libc::memcpy(
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
282 Self::data_ptr(dest_buffer).cast(),
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
283 data.as_ptr().cast(),
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
284 data.len(),
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
285 );
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
286 Ok(CHeapBox::from_ptr(dest_buffer))
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
287 }
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
288 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
289
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
290 fn length(&self) -> usize {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
291 u32::from_be_bytes(self.total_length).saturating_sub(5) as usize
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
292 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
293
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
294 fn data_ptr(ptr: NonNull<Self>) -> *mut u8 {
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
295 unsafe {
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
296 ptr.as_ptr()
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
297 .cast::<u8>()
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
298 .byte_offset(offset_of!(Self, data) as isize)
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
299 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
300 }
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
301
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
302 unsafe fn data_slice<'a>(ptr: NonNull<Self>) -> &'a mut [u8] {
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
303 unsafe { slice::from_raw_parts_mut(Self::data_ptr(ptr), ptr.as_ref().length()) }
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
304 }
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
305
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
306 pub unsafe fn data<'a>(ptr: NonNull<Self>) -> (&'a [u8], u8) {
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
307 unsafe { (Self::data_slice(ptr), ptr.as_ref().data_type) }
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
308 }
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
309
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
310 pub unsafe fn zero_contents(ptr: NonNull<Self>) {
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
311 for byte in Self::data_slice(ptr) {
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
312 ptr::write_volatile(byte as *mut u8, mem::zeroed());
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
313 }
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
314 ptr::write_volatile(ptr.as_ptr(), mem::zeroed());
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
315 }
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
316
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
317 #[allow(clippy::wrong_self_convention)]
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
318 pub unsafe fn as_binary_data(ptr: NonNull<Self>) -> BinaryData {
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
319 let (data, data_type) = unsafe { (CBinaryData::data_slice(ptr), ptr.as_ref().data_type) };
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
320 (Vec::from(data), data_type).into()
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
321 }
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
322 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
323
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
324 #[cfg(test)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
325 mod tests {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
326 use super::*;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
327 use std::hint;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
328 #[test]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
329 fn test_box() {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
330 #[allow(non_upper_case_globals)]
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
331 static mut drop_count: u32 = 0;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
332
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
333 struct Dropper(i32);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
334
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
335 impl Drop for Dropper {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
336 fn drop(&mut self) {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
337 unsafe { drop_count += 1 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
338 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
339 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
340
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
341 let mut dropbox = CHeapBox::new(Dropper(9)).unwrap();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
342 hint::black_box(dropbox.0);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
343 dropbox = CHeapBox::new(Dropper(10)).unwrap();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
344 assert_eq!(1, unsafe { drop_count });
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
345 hint::black_box(dropbox.0);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
346 drop(dropbox);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
347 assert_eq!(2, unsafe { drop_count });
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
348 }
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
349 #[test]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
350 fn test_strings() {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
351 let str = CHeapString::new("hello there").unwrap();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
352 let str_ptr = str.into_ptr().as_ptr();
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
353 CHeapString::new("hell\0 there").unwrap_err();
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
354 unsafe {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
355 let copied = copy_pam_string(str_ptr).unwrap();
95
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
356 assert_eq!("hello there", copied.unwrap());
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
357 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
358 let idx_three = str_ptr.add(3).as_mut().unwrap();
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
359 *idx_three = 0x80u8 as i8;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
360 let zeroed = copy_pam_string(str_ptr).unwrap().unwrap();
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
361 assert!(zeroed.is_empty());
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
362 let _ = CHeapString::from_ptr(str_ptr);
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
363 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
364 }
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
365
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
366 #[test]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
367 fn test_option_str() {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
368 let good = option_cstr(Some("whatever")).unwrap();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
369 assert_eq!("whatever", good.unwrap().to_str().unwrap());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
370 let no_str = option_cstr(None).unwrap();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
371 assert!(no_str.is_none());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
372 let bad_str = option_cstr(Some("what\0ever")).unwrap_err();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
373 assert_eq!(ErrorCode::ConversationError, bad_str);
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
374 }
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
375
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
376 #[test]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
377 fn test_prompt() {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
378 let prompt_cstr = CString::new("good").ok();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
379 let prompt = prompt_ptr(prompt_cstr.as_ref());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
380 assert!(!prompt.is_null());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
381 let no_prompt = prompt_ptr(None);
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
382 assert!(no_prompt.is_null());
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
383 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
384 }