Mercurial > crates > nonstick
annotate src/libpam/memory.rs @ 189:b2456d274576 default tip
Add line breaks that rustfmt ate back to documentation.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 31 Jul 2025 15:42:12 -0400 |
parents | 5e4ea9650f87 |
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])* |
185
fb8b547b36b7
Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents:
180
diff
changeset
|
16 $viz:vis enum $name:ident { |
180
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 ) => { |
185
fb8b547b36b7
Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents:
180
diff
changeset
|
23 // This is the one place where we depend upon c_int being i32. |
fb8b547b36b7
Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents:
180
diff
changeset
|
24 // Ideally, we would be able to say `repr(c_int)` but we can't. |
180
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
25 $(#[$m])* |
186
5e4ea9650f87
Derive `hash` where it makes sense.
Paul Fisher <paul@pfish.zone>
parents:
185
diff
changeset
|
26 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] |
185
fb8b547b36b7
Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents:
180
diff
changeset
|
27 #[repr(i32)] |
180
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
28 $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
|
29 $( |
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
30 $(#[$im])* |
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
31 $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
|
32 )* |
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
33 } |
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
34 |
185
fb8b547b36b7
Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents:
180
diff
changeset
|
35 impl TryFrom<c_int> for $name { |
180
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
36 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
|
37 |
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
38 #[allow(unused_doc_comments)] |
185
fb8b547b36b7
Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents:
180
diff
changeset
|
39 fn try_from(value: c_int) -> crate::constants::Result<$name> { |
180
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
40 match value { |
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
41 $( |
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
42 $(#[$im])* |
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
43 $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
|
44 )* |
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
45 _ => 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
|
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 } |
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
49 |
185
fb8b547b36b7
Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents:
180
diff
changeset
|
50 impl From<$name> for c_int { |
fb8b547b36b7
Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents:
180
diff
changeset
|
51 fn from(value: $name) -> c_int { |
fb8b547b36b7
Banish al(most al)l use of `i32` in favor of `c_int`.
Paul Fisher <paul@pfish.zone>
parents:
180
diff
changeset
|
52 value as c_int |
180
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 } |
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
57 |
a1bb1d013567
Remove `syn` from the dependency tree by implementing our own num_enum.
Paul Fisher <paul@pfish.zone>
parents:
159
diff
changeset
|
58 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
|
59 |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
60 /// Allocates `count` elements to hold `T`. |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
61 #[inline] |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
62 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
|
63 // 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
|
64 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
|
65 } |
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 /// 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
|
68 /// |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
69 /// # Safety |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
70 /// |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
71 /// 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
|
72 #[inline] |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
73 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
|
74 libc::free(p.cast()) |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
75 } |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
76 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
77 /// 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
|
78 #[repr(C)] |
80
5aa1a010f1e8
Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents:
79
diff
changeset
|
79 #[derive(Debug, Default)] |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
80 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
|
81 |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
82 /// 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
|
83 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
|
84 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
|
85 } |
ebb71a412b58
Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents:
141
diff
changeset
|
86 |
ebb71a412b58
Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents:
141
diff
changeset
|
87 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
|
88 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
|
89 } |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
90 |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
91 /// 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
|
92 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
|
93 match prompt { |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
94 Some(c_str) => c_str.as_ptr(), |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
95 None => ptr::null(), |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
96 } |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
97 } |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
98 |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
99 /// 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
|
100 #[derive(Debug)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
101 #[repr(transparent)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
102 pub struct CHeapBox<T>(NonNull<T>); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
103 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
104 // 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
|
105 #[allow(clippy::wrong_self_convention)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
106 impl<T> CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
107 /// 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
|
108 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
|
109 let memory = calloc(1); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
110 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
|
111 // SAFETY: We literally just allocated this. |
141
a508a69c068a
Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents:
139
diff
changeset
|
112 Self(memory) |
98
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 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
115 /// Takes ownership of the given pointer. |
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 /// # Safety |
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 /// 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
|
120 /// that was made with `malloc`. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
121 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
|
122 Self(ptr) |
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 /// 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
|
126 pub fn into_ptr(this: Self) -> NonNull<T> { |
100
3f11b8d30f63
Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents:
98
diff
changeset
|
127 ManuallyDrop::new(this).0 |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
128 } |
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 /// 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
|
131 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
132 /// 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
|
133 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
|
134 this.0 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
135 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
136 |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
137 /// 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
|
138 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
|
139 this.0.as_ptr() |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
140 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
141 |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
142 /// 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
|
143 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
144 /// # Safety |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
145 /// |
141
a508a69c068a
Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents:
139
diff
changeset
|
146 /// 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
|
147 /// 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
|
148 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
|
149 mem::transmute(this) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
150 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
151 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
152 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
153 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
|
154 fn default() -> Self { |
141
a508a69c068a
Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents:
139
diff
changeset
|
155 Self::new(Default::default()) |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
156 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
157 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
158 |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
159 impl Buffer for CHeapBox<u8> { |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
160 fn allocate(len: usize) -> Self { |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
161 // 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
|
162 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
|
163 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
164 |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
165 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
|
166 this.0.as_ptr() |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
167 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
168 |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
169 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
|
170 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
|
171 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
172 |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
173 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
|
174 CHeapBox::into_ptr(this) |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
175 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
176 |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
177 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
|
178 CHeapBox::from_ptr(ptr) |
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 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
181 |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
182 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
|
183 |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
184 impl<T> Deref for CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
185 type Target = T; |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
186 fn deref(&self) -> &Self::Target { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
187 // 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
|
188 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
|
189 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
190 } |
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 impl<T> DerefMut for CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
193 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
|
194 // 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
|
195 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
|
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 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
199 impl<T> Drop for CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
200 fn drop(&mut self) { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
201 // 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
|
202 unsafe { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
203 let ptr = self.0.as_ptr(); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
204 ptr::drop_in_place(ptr); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
205 free(ptr) |
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 } |
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 /// 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
|
211 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
212 /// Basically [`CString`], but managed by malloc. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
213 #[derive(Debug)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
214 #[repr(transparent)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
215 pub struct CHeapString(CHeapBox<c_char>); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
216 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
217 impl CHeapString { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
218 /// 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
|
219 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
|
220 let data = text.as_ref(); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
221 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
|
222 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
|
223 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
224 // +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
|
225 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
|
226 // 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
|
227 unsafe { |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
228 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
|
229 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
|
230 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
|
231 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
232 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
233 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
234 /// 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
|
235 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
236 /// 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
|
237 pub fn into_ptr(self) -> NonNull<c_char> { |
100
3f11b8d30f63
Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents:
98
diff
changeset
|
238 let this = ManuallyDrop::new(self); |
3f11b8d30f63
Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents:
98
diff
changeset
|
239 CHeapBox::as_ptr(&this.0) |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
240 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
241 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
242 /// 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
|
243 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
|
244 unsafe { mem::transmute(self) } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
245 } |
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 /// 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
|
248 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
249 /// # Safety |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
250 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
251 /// 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
|
252 /// 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
|
253 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
|
254 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
|
255 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
256 |
159
634cd5f2ac8b
Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents:
148
diff
changeset
|
257 /// 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
|
258 /// |
634cd5f2ac8b
Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents:
148
diff
changeset
|
259 /// # Safety |
634cd5f2ac8b
Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents:
148
diff
changeset
|
260 /// |
634cd5f2ac8b
Separate logging into its own trait apart from the rest of PAM.
Paul Fisher <paul@pfish.zone>
parents:
148
diff
changeset
|
261 /// 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
|
262 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
|
263 Self(CHeapBox::cast(bx)) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
264 } |
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 /// 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
|
267 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
268 /// # Safety |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
269 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
270 /// 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
|
271 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
|
272 let cstr = ptr.as_ptr(); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
273 let len = libc::strlen(cstr.cast()); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
274 for x in 0..len { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
275 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
|
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 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
279 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
280 impl Drop for CHeapString { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
281 fn drop(&mut self) { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
282 // 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
|
283 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
|
284 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
285 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
286 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
287 impl Deref for CHeapString { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
288 type Target = CStr; |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
289 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
290 fn deref(&self) -> &Self::Target { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
291 // 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
|
292 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
|
293 unsafe { CStr::from_ptr(ptr) } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
294 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
295 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
296 |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
297 /// 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
|
298 /// <code>pam_get_<var>whatever</var></code> function. |
72 | 299 /// |
300 /// # Safety | |
301 /// | |
302 /// 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
|
303 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
|
304 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
|
305 .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
|
306 .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
|
307 .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
|
308 .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
|
309 .map(OsString::from_vec) |
72 | 310 } |
311 | |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
312 #[cfg(test)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
313 mod tests { |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
314 use super::*; |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
315 use std::cell::Cell; |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
316 #[test] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
317 fn test_box() { |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
318 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
|
319 |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
320 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
|
321 |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
322 impl Drop for Dropper<'_> { |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
323 fn drop(&mut self) { |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
324 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
|
325 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
326 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
327 |
141
a508a69c068a
Remove a lot of Results from functions.
Paul Fisher <paul@pfish.zone>
parents:
139
diff
changeset
|
328 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
|
329 _ = dropbox; |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
330 // 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
|
331 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
|
332 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
|
333 *dropbox = Dropper(&drop_count); |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
334 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
|
335 drop(dropbox); |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
336 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
|
337 } |
143
ebb71a412b58
Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents:
141
diff
changeset
|
338 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
339 #[test] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
340 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
|
341 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
|
342 let str_ptr = str.into_ptr().as_ptr(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
343 unsafe { |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
344 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
|
345 assert_eq!("hello there", copied); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
346 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
|
347 let idx_three = str_ptr.add(3).as_mut().unwrap(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
348 *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
|
349 let zeroed = copy_pam_string(str_ptr).unwrap(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
350 assert!(zeroed.is_empty()); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
351 let _ = CHeapString::from_ptr(str_ptr); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
352 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
353 } |
72 | 354 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
355 #[test] |
143
ebb71a412b58
Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents:
141
diff
changeset
|
356 #[should_panic] |
ebb71a412b58
Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents:
141
diff
changeset
|
357 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
|
358 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
|
359 } |
ebb71a412b58
Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents:
141
diff
changeset
|
360 |
ebb71a412b58
Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents:
141
diff
changeset
|
361 #[test] |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
362 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
|
363 let good = option_cstr(Some("whatever".as_ref())); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
364 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
|
365 let no_str = option_cstr(None); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
366 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
|
367 } |
ebb71a412b58
Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents:
141
diff
changeset
|
368 #[test] |
ebb71a412b58
Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents:
141
diff
changeset
|
369 #[should_panic] |
ebb71a412b58
Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents:
141
diff
changeset
|
370 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
|
371 option_cstr(Some("what\0ever".as_ref())); |
71
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(); |
143
ebb71a412b58
Turn everything into OsString and Just Walk Out! for strings with nul.
Paul Fisher <paul@pfish.zone>
parents:
141
diff
changeset
|
377 let prompt = prompt_ptr(prompt_cstr.as_deref()); |
71
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 } |