Mercurial > crates > nonstick
annotate src/libpam/memory.rs @ 98:b87100c5eed4
Start on environment variables, and make pointers nicer.
This starts work on the PAM environment handling, and in so doing,
introduces the CHeapBox and CHeapString structs. These are analogous
to Box and CString, but they're located on the C heap rather than
being Rust-managed memory.
This is because environment variables deal with even more pointers
and it turns out we can lose a lot of manual freeing using homemade
smart pointers.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Tue, 24 Jun 2025 04:25:25 -0400 |
parents | 51c9d7e8261a |
children | 3f11b8d30f63 |
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 | 237 /// |
238 /// # Safety | |
239 /// | |
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 | 245 .to_str() |
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 | 251 } |
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 | 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 | 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 } |