Mercurial > crates > nonstick
annotate src/libpam/memory.rs @ 105:13b4d2a19674
Support Rust v1.75.0.
This is the version included in Ubuntu 24.04 LTS and Debian Trixie,
so it's old enough to have wide penetration without being too old
to get new features (Debian Stable, I love you but v1.63 is just
not going to work out).
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 26 Jun 2025 00:48:51 -0400 |
parents | 3f11b8d30f63 |
children | 49d9e2b5c189 |
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}; |
105 | 9 use std::mem::{ManuallyDrop}; |
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}; |
105 | 14 use memoffset::offset_of; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
15 |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
16 /// 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
|
17 #[derive(Debug)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
18 pub struct NoMem; |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
19 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
20 impl Display for NoMem { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
21 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
|
22 write!(f, "out of memory!") |
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 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
26 impl Error for NoMem {} |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
27 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
28 impl From<NoMem> for ErrorCode { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
29 fn from(_: NoMem) -> Self { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
30 ErrorCode::BufferError |
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 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
33 |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
34 /// Allocates `count` elements to hold `T`. |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
35 #[inline] |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
36 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
|
37 // SAFETY: it's always safe to allocate! Leaking memory is fun! |
105 | 38 NonNull::new(unsafe { libc::calloc(count, mem::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
|
39 } |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
40 |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
41 /// 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
|
42 /// |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
43 /// # Safety |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
44 /// |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
45 /// 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
|
46 #[inline] |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
47 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
|
48 libc::free(p.cast()) |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
49 } |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
50 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
51 /// 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
|
52 #[repr(C)] |
80
5aa1a010f1e8
Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents:
79
diff
changeset
|
53 #[derive(Debug, Default)] |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
54 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
|
55 |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
56 /// 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
|
57 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
|
58 prompt |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
59 .map(CString::new) |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
60 .transpose() |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
61 .map_err(|_| ErrorCode::ConversationError) |
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 |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
64 /// 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
|
65 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
|
66 match prompt { |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
67 Some(c_str) => c_str.as_ptr(), |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
68 None => ptr::null(), |
60
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 } |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
71 |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
72 /// 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
|
73 #[derive(Debug)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
74 #[repr(transparent)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
75 pub struct CHeapBox<T>(NonNull<T>); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
76 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
77 // 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
|
78 #[allow(clippy::wrong_self_convention)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
79 impl<T> CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
80 /// 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
|
81 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
|
82 let memory = calloc(1)?; |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
83 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
|
84 // SAFETY: We literally just allocated this. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
85 Ok(Self(memory)) |
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 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
88 /// Takes ownership of the given pointer. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
89 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
90 /// # Safety |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
91 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
92 /// 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
|
93 /// that was made with `malloc`. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
94 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
|
95 Self(ptr) |
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 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
98 /// 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
|
99 pub fn into_ptr(this: Self) -> NonNull<T> { |
100
3f11b8d30f63
Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents:
98
diff
changeset
|
100 ManuallyDrop::new(this).0 |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
101 } |
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 /// 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
|
104 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
105 /// 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
|
106 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
|
107 this.0 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
108 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
109 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
110 /// 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
|
111 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
112 /// # Safety |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
113 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
114 /// 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
|
115 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
|
116 mem::transmute(this) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
117 } |
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 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
|
121 fn default() -> Self { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
122 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
|
123 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
124 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
125 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
126 impl<T> Deref for CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
127 type Target = T; |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
128 fn deref(&self) -> &Self::Target { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
129 // 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
|
130 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
|
131 } |
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 impl<T> DerefMut for CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
135 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
|
136 // 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
|
137 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
|
138 } |
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 impl<T> Drop for CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
142 fn drop(&mut self) { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
143 // 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
|
144 unsafe { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
145 let ptr = self.0.as_ptr(); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
146 ptr::drop_in_place(ptr); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
147 free(ptr) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
148 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
149 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
150 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
151 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
152 /// 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
|
153 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
154 /// Basically [`CString`], but managed by malloc. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
155 #[derive(Debug)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
156 #[repr(transparent)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
157 pub struct CHeapString(CHeapBox<c_char>); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
158 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
159 impl CHeapString { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
160 /// 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
|
161 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
|
162 let data = text.as_bytes(); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
163 if data.contains(&0) { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
164 return Err(ErrorCode::ConversationError); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
165 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
166 // +1 for the null terminator |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
167 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
|
168 // 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
|
169 unsafe { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
170 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
|
171 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
|
172 } |
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 /// 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
|
176 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
177 /// 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
|
178 pub fn into_ptr(self) -> NonNull<c_char> { |
100
3f11b8d30f63
Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents:
98
diff
changeset
|
179 let this = ManuallyDrop::new(self); |
3f11b8d30f63
Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents:
98
diff
changeset
|
180 CHeapBox::as_ptr(&this.0) |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
181 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
182 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
183 /// 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
|
184 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
|
185 unsafe { mem::transmute(self) } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
186 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
187 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
188 /// 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
|
189 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
190 /// # Safety |
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 /// 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
|
193 /// a valid 0-terminated C string. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
194 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
|
195 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
|
196 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
197 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
198 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
|
199 Self(CHeapBox::cast(bx)) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
200 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
201 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
202 /// 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
|
203 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
204 /// # Safety |
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 /// 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
|
207 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
|
208 let cstr = ptr.as_ptr(); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
209 let len = libc::strlen(cstr.cast()); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
210 for x in 0..len { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
211 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
|
212 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
213 } |
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 impl Drop for CHeapString { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
217 fn drop(&mut self) { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
218 // 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
|
219 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
|
220 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
221 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
222 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
223 impl Deref for CHeapString { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
224 type Target = CStr; |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
225 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
226 fn deref(&self) -> &Self::Target { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
227 // 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
|
228 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
|
229 unsafe { CStr::from_ptr(ptr) } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
230 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
231 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
232 |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
233 /// 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
|
234 /// <code>pam_get_<var>whatever</var></code> function. |
72 | 235 /// |
236 /// # Safety | |
237 /// | |
238 /// 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
|
239 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
|
240 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
|
241 Some(data) => Some( |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
242 CStr::from_ptr(data.as_ptr()) |
72 | 243 .to_str() |
244 .map_err(|_| ErrorCode::ConversationError)?, | |
95
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
245 ), |
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
246 None => return Ok(None), |
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 Ok(borrowed.map(String::from)) |
72 | 249 } |
250 | |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
251 /// Binary data used in requests and responses. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
252 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
253 /// 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
|
254 /// This must be allocated on the C heap. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
255 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
256 /// A Linux-PAM extension. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
257 #[repr(C)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
258 pub struct CBinaryData { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
259 /// 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
|
260 total_length: [u8; 4], |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
261 /// A tag of undefined meaning. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
262 data_type: u8, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
263 /// Pointer to an array of length [`length`](Self::length) − 5 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
264 data: [u8; 0], |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
265 _marker: Immovable, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
266 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
267 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
268 impl CBinaryData { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
269 /// 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
|
270 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
|
271 let buffer_size = |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
272 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
|
273 // 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
|
274 unsafe { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
275 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
|
276 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
|
277 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
|
278 dest.data_type = data_type; |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
279 libc::memcpy( |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
280 Self::data_ptr(dest_buffer).cast(), |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
281 data.as_ptr().cast(), |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
282 data.len(), |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
283 ); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
284 Ok(CHeapBox::from_ptr(dest_buffer)) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
285 } |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
286 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
287 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
288 fn length(&self) -> usize { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
289 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
|
290 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
291 |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
292 fn data_ptr(ptr: NonNull<Self>) -> *mut u8 { |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
293 unsafe { |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
294 ptr.as_ptr() |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
295 .cast::<u8>() |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
296 .byte_offset(offset_of!(Self, data) as isize) |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
297 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
298 } |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
299 |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
300 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
|
301 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
|
302 } |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
303 |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
304 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
|
305 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
|
306 } |
2128123b9406
Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents:
78
diff
changeset
|
307 |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
308 pub unsafe fn zero_contents(ptr: NonNull<Self>) { |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
309 for byte in Self::data_slice(ptr) { |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
310 ptr::write_volatile(byte as *mut u8, mem::zeroed()); |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
311 } |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
312 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
|
313 } |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
314 |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
315 #[allow(clippy::wrong_self_convention)] |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
316 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
|
317 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
|
318 (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
|
319 } |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
320 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
321 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
322 #[cfg(test)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
323 mod tests { |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
324 use super::*; |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
325 use std::hint; |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
326 #[test] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
327 fn test_box() { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
328 #[allow(non_upper_case_globals)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
329 static mut drop_count: u32 = 0; |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
330 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
331 struct Dropper(i32); |
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 impl Drop for Dropper { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
334 fn drop(&mut self) { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
335 unsafe { drop_count += 1 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
336 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
337 } |
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 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
|
340 hint::black_box(dropbox.0); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
341 dropbox = CHeapBox::new(Dropper(10)).unwrap(); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
342 assert_eq!(1, unsafe { drop_count }); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
343 hint::black_box(dropbox.0); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
344 drop(dropbox); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
345 assert_eq!(2, unsafe { drop_count }); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
346 } |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
347 #[test] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
348 fn test_strings() { |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
349 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
|
350 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
|
351 CHeapString::new("hell\0 there").unwrap_err(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
352 unsafe { |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
353 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
|
354 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
|
355 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
|
356 let idx_three = str_ptr.add(3).as_mut().unwrap(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
357 *idx_three = 0x80u8 as i8; |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
358 let zeroed = copy_pam_string(str_ptr).unwrap().unwrap(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
359 assert!(zeroed.is_empty()); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
360 let _ = CHeapString::from_ptr(str_ptr); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
361 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
362 } |
72 | 363 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
364 #[test] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
365 fn test_option_str() { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
366 let good = option_cstr(Some("whatever")).unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
367 assert_eq!("whatever", good.unwrap().to_str().unwrap()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
368 let no_str = option_cstr(None).unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
369 assert!(no_str.is_none()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
370 let bad_str = option_cstr(Some("what\0ever")).unwrap_err(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
371 assert_eq!(ErrorCode::ConversationError, bad_str); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
372 } |
72 | 373 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
374 #[test] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
375 fn test_prompt() { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
376 let prompt_cstr = CString::new("good").ok(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
377 let prompt = prompt_ptr(prompt_cstr.as_ref()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
378 assert!(!prompt.is_null()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
379 let no_prompt = prompt_ptr(None); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
380 assert!(no_prompt.is_null()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
381 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
382 } |