Skip to content

Commit 94d8a4e

Browse files
committed
Use libc_enum! where possible
Some enums which use different names for values than libc still set the discriminators manually. closes nix-rust#254
1 parent 1b9d205 commit 94d8a4e

File tree

4 files changed

+213
-196
lines changed

4 files changed

+213
-196
lines changed

src/sys/aio.rs

Lines changed: 102 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,41 @@ use sys::time::TimeSpec;
1313

1414
/// Mode for `AioCb::fsync`. Controls whether only data or both data and
1515
/// metadata are synced.
16-
#[repr(i32)]
17-
#[derive(Clone, Copy, Debug, PartialEq)]
18-
pub enum AioFsyncMode {
19-
/// do it like `fsync`
20-
O_SYNC = libc::O_SYNC,
21-
/// on supported operating systems only, do it like `fdatasync`
22-
#[cfg(any(target_os = "openbsd", target_os = "bitrig",
23-
target_os = "netbsd", target_os = "macos", target_os = "ios",
24-
target_os = "linux"))]
25-
O_DSYNC = libc::O_DSYNC
16+
libc_enum! {
17+
#[repr(i32)]
18+
pub enum AioFsyncMode {
19+
/// do it like `fsync`
20+
O_SYNC,
21+
/// on supported operating systems only, do it like `fdatasync`
22+
#[cfg(any(target_os = "openbsd", target_os = "bitrig",
23+
target_os = "netbsd", target_os = "macos", target_os = "ios",
24+
target_os = "linux"))]
25+
O_DSYNC
26+
}
2627
}
2728

28-
/// When used with `lio_listio`, determines whether a given `aiocb` should be
29-
/// used for a read operation, a write operation, or ignored. Has no effect for
30-
/// any other aio functions.
31-
#[repr(i32)]
32-
#[derive(Clone, Copy, Debug, PartialEq)]
33-
pub enum LioOpcode {
34-
LIO_NOP = libc::LIO_NOP,
35-
LIO_WRITE = libc::LIO_WRITE,
36-
LIO_READ = libc::LIO_READ
29+
libc_enum! {
30+
/// When used with `lio_listio`, determines whether a given `aiocb` should be
31+
/// used for a read operation, a write operation, or ignored. Has no effect for
32+
/// any other aio functions.
33+
#[repr(i32)]
34+
pub enum LioOpcode {
35+
LIO_NOP,
36+
LIO_WRITE,
37+
LIO_READ,
38+
}
3739
}
3840

39-
/// Mode for `lio_listio`.
40-
#[repr(i32)]
41-
#[derive(Clone, Copy, Debug, PartialEq)]
42-
pub enum LioMode {
43-
/// Requests that `lio_listio` block until all requested operations have
44-
/// been completed
45-
LIO_WAIT = libc::LIO_WAIT,
46-
/// Requests that `lio_listio` return immediately
47-
LIO_NOWAIT = libc::LIO_NOWAIT,
41+
libc_enum! {
42+
/// Mode for `lio_listio`.
43+
#[repr(i32)]
44+
pub enum LioMode {
45+
/// Requests that `lio_listio` block until all requested operations have
46+
/// been completed
47+
LIO_WAIT,
48+
/// Requests that `lio_listio` return immediately
49+
LIO_NOWAIT,
50+
}
4851
}
4952

5053
/// Return values for `AioCb::cancel and aio_cancel_all`
@@ -68,7 +71,7 @@ enum Keeper<'a> {
6871
/// Keeps a reference to a Boxed slice
6972
boxed(Rc<Box<[u8]>>),
7073
/// Keeps a reference to a slice
71-
phantom(PhantomData<&'a mut [u8]>)
74+
phantom(PhantomData<&'a mut [u8]>),
7275
}
7376

7477
/// The basic structure used by all aio functions. Each `aiocb` represents one
@@ -80,7 +83,7 @@ pub struct AioCb<'a> {
8083
/// Could this `AioCb` potentially have any in-kernel state?
8184
in_progress: bool,
8285
/// Used to keep buffers from Drop'ing
83-
keeper: Keeper<'a>
86+
keeper: Keeper<'a>,
8487
}
8588

8689
impl<'a> AioCb<'a> {
@@ -97,15 +100,18 @@ impl<'a> AioCb<'a> {
97100
/// be prioritized at the process's priority level minus `prio`
98101
/// * `sigev_notify` Determines how you will be notified of event
99102
/// completion.
100-
pub fn from_fd(fd: RawFd, prio: libc::c_int,
101-
sigev_notify: SigevNotify) -> AioCb<'a> {
103+
pub fn from_fd(fd: RawFd, prio: libc::c_int, sigev_notify: SigevNotify) -> AioCb<'a> {
102104
let mut a = AioCb::common_init(fd, prio, sigev_notify);
103105
a.aio_offset = 0;
104106
a.aio_nbytes = 0;
105107
a.aio_buf = null_mut();
106108

107-
let aiocb = AioCb { aiocb: a, mutable: false, in_progress: false,
108-
keeper: Keeper::none};
109+
let aiocb = AioCb {
110+
aiocb: a,
111+
mutable: false,
112+
in_progress: false,
113+
keeper: Keeper::none,
114+
};
109115
aiocb
110116
}
111117

@@ -120,17 +126,26 @@ impl<'a> AioCb<'a> {
120126
/// completion.
121127
/// * `opcode` This field is only used for `lio_listio`. It determines
122128
/// which operation to use for this individual aiocb
123-
pub fn from_mut_slice(fd: RawFd, offs: off_t, buf: &'a mut [u8],
124-
prio: libc::c_int, sigev_notify: SigevNotify,
125-
opcode: LioOpcode) -> AioCb<'a> {
129+
pub fn from_mut_slice(
130+
fd: RawFd,
131+
offs: off_t,
132+
buf: &'a mut [u8],
133+
prio: libc::c_int,
134+
sigev_notify: SigevNotify,
135+
opcode: LioOpcode,
136+
) -> AioCb<'a> {
126137
let mut a = AioCb::common_init(fd, prio, sigev_notify);
127138
a.aio_offset = offs;
128139
a.aio_nbytes = buf.len() as size_t;
129140
a.aio_buf = buf.as_ptr() as *mut c_void;
130141
a.aio_lio_opcode = opcode as libc::c_int;
131142

132-
let aiocb = AioCb { aiocb: a, mutable: true, in_progress: false,
133-
keeper: Keeper::phantom(PhantomData)};
143+
let aiocb = AioCb {
144+
aiocb: a,
145+
mutable: true,
146+
in_progress: false,
147+
keeper: Keeper::phantom(PhantomData),
148+
};
134149
aiocb
135150
}
136151

@@ -148,17 +163,26 @@ impl<'a> AioCb<'a> {
148163
/// completion.
149164
/// * `opcode` This field is only used for `lio_listio`. It determines
150165
/// which operation to use for this individual aiocb
151-
pub fn from_boxed_slice(fd: RawFd, offs: off_t, buf: Rc<Box<[u8]>>,
152-
prio: libc::c_int, sigev_notify: SigevNotify,
153-
opcode: LioOpcode) -> AioCb<'a> {
166+
pub fn from_boxed_slice(
167+
fd: RawFd,
168+
offs: off_t,
169+
buf: Rc<Box<[u8]>>,
170+
prio: libc::c_int,
171+
sigev_notify: SigevNotify,
172+
opcode: LioOpcode,
173+
) -> AioCb<'a> {
154174
let mut a = AioCb::common_init(fd, prio, sigev_notify);
155175
a.aio_offset = offs;
156176
a.aio_nbytes = buf.len() as size_t;
157177
a.aio_buf = buf.as_ptr() as *mut c_void;
158178
a.aio_lio_opcode = opcode as libc::c_int;
159179

160-
let aiocb = AioCb{ aiocb: a, mutable: true, in_progress: false,
161-
keeper: Keeper::boxed(buf)};
180+
let aiocb = AioCb {
181+
aiocb: a,
182+
mutable: true,
183+
in_progress: false,
184+
keeper: Keeper::boxed(buf),
185+
};
162186
aiocb
163187
}
164188

@@ -175,31 +199,42 @@ impl<'a> AioCb<'a> {
175199
// then lio_listio wouldn't work, because that function needs a slice of
176200
// AioCb, and they must all be the same type. We're basically stuck with
177201
// using an unsafe function, since aio (as designed in C) is an unsafe API.
178-
pub fn from_slice(fd: RawFd, offs: off_t, buf: &'a [u8],
179-
prio: libc::c_int, sigev_notify: SigevNotify,
180-
opcode: LioOpcode) -> AioCb {
202+
pub fn from_slice(
203+
fd: RawFd,
204+
offs: off_t,
205+
buf: &'a [u8],
206+
prio: libc::c_int,
207+
sigev_notify: SigevNotify,
208+
opcode: LioOpcode,
209+
) -> AioCb {
181210
let mut a = AioCb::common_init(fd, prio, sigev_notify);
182211
a.aio_offset = offs;
183212
a.aio_nbytes = buf.len() as size_t;
184213
// casting an immutable buffer to a mutable pointer looks unsafe,
185214
// but technically its only unsafe to dereference it, not to create
186215
// it.
187216
a.aio_buf = buf.as_ptr() as *mut c_void;
188-
assert!(opcode != LioOpcode::LIO_READ, "Can't read into an immutable buffer");
217+
assert!(
218+
opcode != LioOpcode::LIO_READ,
219+
"Can't read into an immutable buffer"
220+
);
189221
a.aio_lio_opcode = opcode as libc::c_int;
190222

191-
let aiocb = AioCb { aiocb: a, mutable: false, in_progress: false,
192-
keeper: Keeper::none};
223+
let aiocb = AioCb {
224+
aiocb: a,
225+
mutable: false,
226+
in_progress: false,
227+
keeper: Keeper::none,
228+
};
193229
aiocb
194230
}
195231

196-
fn common_init(fd: RawFd, prio: libc::c_int,
197-
sigev_notify: SigevNotify) -> libc::aiocb {
232+
fn common_init(fd: RawFd, prio: libc::c_int, sigev_notify: SigevNotify) -> libc::aiocb {
198233
// Use mem::zeroed instead of explicitly zeroing each field, because the
199234
// number and name of reserved fields is OS-dependent. On some OSes,
200235
// some reserved fields are used the kernel for state, and must be
201236
// explicitly zeroed when allocated.
202-
let mut a = unsafe { mem::zeroed::<libc::aiocb>()};
237+
let mut a = unsafe { mem::zeroed::<libc::aiocb>() };
203238
a.aio_fildes = fd;
204239
a.aio_reqprio = prio;
205240
a.aio_sigevent = SigEvent::new(sigev_notify).sigevent();
@@ -218,7 +253,7 @@ impl<'a> AioCb<'a> {
218253
libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
219254
libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
220255
-1 => Err(Error::last()),
221-
_ => panic!("unknown aio_cancel return value")
256+
_ => panic!("unknown aio_cancel return value"),
222257
}
223258
}
224259

@@ -230,18 +265,15 @@ impl<'a> AioCb<'a> {
230265
0 => Ok(()),
231266
num if num > 0 => Err(Error::from_errno(Errno::from_i32(num))),
232267
-1 => Err(Error::last()),
233-
num => panic!("unknown aio_error return value {:?}", num)
268+
num => panic!("unknown aio_error return value {:?}", num),
234269
}
235270
}
236271

237272
/// An asynchronous version of `fsync`.
238273
pub fn fsync(&mut self, mode: AioFsyncMode) -> Result<()> {
239274
let p: *mut libc::aiocb = &mut self.aiocb;
240-
Errno::result(unsafe {
241-
libc::aio_fsync(mode as libc::c_int, p)
242-
}).map(|_| {
243-
self.in_progress = true;
244-
})
275+
Errno::result(unsafe { libc::aio_fsync(mode as libc::c_int, p) })
276+
.map(|_| { self.in_progress = true; })
245277
}
246278

247279
/// Returns the `aiocb`'s `LioOpcode` field
@@ -253,7 +285,7 @@ impl<'a> AioCb<'a> {
253285
libc::LIO_READ => Some(LioOpcode::LIO_READ),
254286
libc::LIO_WRITE => Some(LioOpcode::LIO_WRITE),
255287
libc::LIO_NOP => Some(LioOpcode::LIO_NOP),
256-
_ => None
288+
_ => None,
257289
}
258290
}
259291

@@ -280,11 +312,7 @@ impl<'a> AioCb<'a> {
280312
pub fn read(&mut self) -> Result<()> {
281313
assert!(self.mutable, "Can't read into an immutable buffer");
282314
let p: *mut libc::aiocb = &mut self.aiocb;
283-
Errno::result(unsafe {
284-
libc::aio_read(p)
285-
}).map(|_| {
286-
self.in_progress = true;
287-
})
315+
Errno::result(unsafe { libc::aio_read(p) }).map(|_| { self.in_progress = true; })
288316
}
289317

290318
/// Returns the `SigEvent` stored in the `AioCb`
@@ -305,13 +333,8 @@ impl<'a> AioCb<'a> {
305333
/// Asynchronously writes from a buffer to a file descriptor
306334
pub fn write(&mut self) -> Result<()> {
307335
let p: *mut libc::aiocb = &mut self.aiocb;
308-
Errno::result(unsafe {
309-
libc::aio_write(p)
310-
}).map(|_| {
311-
self.in_progress = true;
312-
})
336+
Errno::result(unsafe { libc::aio_write(p) }).map(|_| { self.in_progress = true; })
313337
}
314-
315338
}
316339

317340
/// Cancels outstanding AIO requests. All requests for `fd` will be cancelled.
@@ -321,7 +344,7 @@ pub fn aio_cancel_all(fd: RawFd) -> Result<AioCancelStat> {
321344
libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
322345
libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
323346
-1 => Err(Error::last()),
324-
_ => panic!("unknown aio_cancel return value")
347+
_ => panic!("unknown aio_cancel return value"),
325348
}
326349
}
327350

@@ -331,32 +354,25 @@ pub fn aio_cancel_all(fd: RawFd) -> Result<AioCancelStat> {
331354
pub fn aio_suspend(list: &[&AioCb], timeout: Option<TimeSpec>) -> Result<()> {
332355
// We must use transmute because Rust doesn't understand that a pointer to a
333356
// Struct is the same as a pointer to its first element.
334-
let plist = unsafe {
335-
mem::transmute::<&[&AioCb], *const [*const libc::aiocb]>(list)
336-
};
357+
let plist = unsafe { mem::transmute::<&[&AioCb], *const [*const libc::aiocb]>(list) };
337358
let p = plist as *const *const libc::aiocb;
338359
let timep = match timeout {
339-
None => null::<libc::timespec>(),
340-
Some(x) => x.as_ref() as *const libc::timespec
360+
None => null::<libc::timespec>(),
361+
Some(x) => x.as_ref() as *const libc::timespec,
341362
};
342-
Errno::result(unsafe {
343-
libc::aio_suspend(p, list.len() as i32, timep)
344-
}).map(drop)
363+
Errno::result(unsafe { libc::aio_suspend(p, list.len() as i32, timep) }).map(drop)
345364
}
346365

347366

348367
/// Submits multiple asynchronous I/O requests with a single system call. The
349368
/// order in which the requests are carried out is not specified.
350369
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
351-
pub fn lio_listio(mode: LioMode, list: &[&mut AioCb],
352-
sigev_notify: SigevNotify) -> Result<()> {
370+
pub fn lio_listio(mode: LioMode, list: &[&mut AioCb], sigev_notify: SigevNotify) -> Result<()> {
353371
let sigev = SigEvent::new(sigev_notify);
354372
let sigevp = &mut sigev.sigevent() as *mut libc::sigevent;
355373
// We must use transmute because Rust doesn't understand that a pointer to a
356374
// Struct is the same as a pointer to its first element.
357-
let plist = unsafe {
358-
mem::transmute::<&[&mut AioCb], *const [*mut libc::aiocb]>(list)
359-
};
375+
let plist = unsafe { mem::transmute::<&[&mut AioCb], *const [*mut libc::aiocb]>(list) };
360376
let p = plist as *const *mut libc::aiocb;
361377
Errno::result(unsafe {
362378
libc::lio_listio(mode as i32, p, list.len() as i32, sigevp)

0 commit comments

Comments
 (0)