1use linux_unsafe::args::AsRawV;
13use linux_unsafe::int;
14
15pub const F_DUPFD: DirectFcntlCmd<int, super::File> = unsafe { fcntl_cmd(0) };
18
19pub const F_GETFD: DirectFcntlCmd<(), int> = unsafe { fcntl_cmd(1) };
21
22pub const F_SETFD: DirectFcntlCmd<int, ()> = unsafe { fcntl_cmd(2) };
24
25pub const F_GETFL: DirectFcntlCmd<(), int> = unsafe { fcntl_cmd(3) };
27
28pub const F_SETFL: DirectFcntlCmd<int, ()> = unsafe { fcntl_cmd(4) };
30
31pub const F_GETLK: MutPtrFcntlCmd<linux_unsafe::flock, ()> = unsafe { fcntl_cmd_mut_ptr(5) };
33
34pub const F_SETLK: MutPtrFcntlCmd<linux_unsafe::flock, ()> = unsafe { fcntl_cmd_mut_ptr(6) };
36
37pub const F_SETLKW: MutPtrFcntlCmd<linux_unsafe::flock, ()> = unsafe { fcntl_cmd_mut_ptr(7) };
40
41pub const F_OFD_GETLK: MutPtrFcntlCmd<linux_unsafe::flock, ()> = unsafe { fcntl_cmd_mut_ptr(36) };
43
44pub const F_OFD_SETLK: MutPtrFcntlCmd<linux_unsafe::flock, ()> = unsafe { fcntl_cmd_mut_ptr(37) };
46
47pub const F_OFD_SETLKW: MutPtrFcntlCmd<linux_unsafe::flock, ()> = unsafe { fcntl_cmd_mut_ptr(38) };
50
51const F_LINUX_SPECIFIC_BASE: int = 1024;
52
53pub const F_DUPFD_CLOEXEC: DirectFcntlCmd<int, int> =
57 unsafe { fcntl_cmd(F_LINUX_SPECIFIC_BASE + 6) };
58
59pub unsafe trait FcntlCmd<'a> {
64 type ExtArg
66 where
67 Self: 'a;
68
69 type RawArg: AsRawV;
71
72 type Result;
74
75 fn prepare_fcntl_args(&self, arg: Self::ExtArg) -> (int, Self::RawArg);
77
78 fn prepare_fcntl_result(&self, raw: int) -> Self::Result;
80}
81
82pub const unsafe fn fcntl_cmd<Arg, Result>(cmd: int) -> DirectFcntlCmd<Arg, Result>
88where
89 Arg: AsRawV,
90 Result: FromFcntlResult,
91{
92 DirectFcntlCmd::<Arg, Result> {
93 cmd,
94 _phantom: core::marker::PhantomData,
95 }
96}
97
98pub const unsafe fn fcntl_cmd_const_ptr<Arg, Result>(cmd: int) -> ConstPtrFcntlCmd<Arg, Result>
104where
105 *const Arg: AsRawV,
106 Result: FromFcntlResult,
107{
108 ConstPtrFcntlCmd::<Arg, Result> {
109 cmd,
110 _phantom: core::marker::PhantomData,
111 }
112}
113
114pub const unsafe fn fcntl_cmd_mut_ptr<Arg, Result>(cmd: int) -> MutPtrFcntlCmd<Arg, Result>
120where
121 *mut Arg: AsRawV,
122 Result: FromFcntlResult,
123{
124 MutPtrFcntlCmd::<Arg, Result> {
125 cmd,
126 _phantom: core::marker::PhantomData,
127 }
128}
129
130#[repr(transparent)]
133pub struct DirectFcntlCmd<Arg: AsRawV, Result: FromFcntlResult> {
134 cmd: int,
135 _phantom: core::marker::PhantomData<(Arg, Result)>,
136}
137
138unsafe impl<'a, Arg: AsRawV, Result: FromFcntlResult> FcntlCmd<'a> for DirectFcntlCmd<Arg, Result> {
139 type ExtArg = Arg where Self: 'a;
140 type RawArg = Arg;
141
142 fn prepare_fcntl_args(&self, arg: Arg) -> (int, Self::RawArg) {
143 (self.cmd, arg)
144 }
145
146 type Result = Result;
147
148 fn prepare_fcntl_result(&self, raw: int) -> Self::Result {
149 unsafe { Self::Result::prepare_result(raw) }
150 }
151}
152
153#[repr(transparent)]
156pub struct ConstPtrFcntlCmd<Arg, Result: FromFcntlResult> {
157 cmd: int,
158 _phantom: core::marker::PhantomData<(Arg, Result)>,
159}
160
161unsafe impl<'a, Arg, Result: FromFcntlResult> FcntlCmd<'a> for ConstPtrFcntlCmd<Arg, Result> {
162 type ExtArg = &'a Arg where Self: 'a;
163 type RawArg = *const Arg;
164
165 fn prepare_fcntl_args(&self, arg: &'a Arg) -> (int, Self::RawArg) {
166 (self.cmd, arg as *const Arg)
167 }
168
169 type Result = Result;
170
171 fn prepare_fcntl_result(&self, raw: int) -> Self::Result {
172 unsafe { Self::Result::prepare_result(raw) }
173 }
174}
175
176#[repr(transparent)]
179pub struct MutPtrFcntlCmd<Arg, Result: FromFcntlResult> {
180 cmd: int,
181 _phantom: core::marker::PhantomData<(Arg, Result)>,
182}
183
184unsafe impl<'a, Arg, Result: FromFcntlResult> FcntlCmd<'a> for MutPtrFcntlCmd<Arg, Result> {
185 type ExtArg = &'a mut Arg where Self: 'a;
186 type RawArg = *mut Arg;
187
188 fn prepare_fcntl_args(&self, arg: &'a mut Arg) -> (int, Self::RawArg) {
189 (self.cmd, arg as *mut Arg)
190 }
191
192 type Result = Result;
193
194 fn prepare_fcntl_result(&self, raw: int) -> Self::Result {
195 unsafe { Self::Result::prepare_result(raw) }
196 }
197}
198
199pub trait FromFcntlResult {
201 unsafe fn prepare_result(raw: int) -> Self;
202}
203
204impl FromFcntlResult for int {
205 #[inline(always)]
206 unsafe fn prepare_result(raw: int) -> Self {
207 raw
208 }
209}
210
211impl FromFcntlResult for () {
212 #[inline(always)]
213 unsafe fn prepare_result(_: int) -> () {
214 ()
215 }
216}
217
218impl FromFcntlResult for super::File {
219 #[inline(always)]
220 unsafe fn prepare_result(raw: int) -> Self {
221 super::File::from_raw_fd(raw)
222 }
223}