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