Skip to content

Commit ea00191

Browse files
committed
Auto merge of #294 - kamalmarhubi:unistd-libc, r=@posborne
unistd: Use bindings from libc instead of our own Refs #264
2 parents 2f65a3f + 6b24f60 commit ea00191

File tree

3 files changed

+49
-88
lines changed

3 files changed

+49
-88
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ signalfd = []
2222
[dependencies]
2323
libc = "0.2.7"
2424
bitflags = "0.4"
25+
cfg-if = "0.1.0"
2526

2627
[dev-dependencies]
2728
rand = "0.3.8"

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#[macro_use]
1414
extern crate bitflags;
1515

16+
#[macro_use]
17+
extern crate cfg_if;
18+
1619
pub extern crate libc;
1720

1821
#[cfg(test)]

src/unistd.rs

Lines changed: 45 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -3,70 +3,14 @@
33
use {Errno, Error, Result, NixPath};
44
use fcntl::{fcntl, OFlag, O_NONBLOCK, O_CLOEXEC, FD_CLOEXEC};
55
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
6-
use libc::{c_char, c_void, c_int, size_t, pid_t, off_t, uid_t, gid_t};
6+
use libc::{self, c_char, c_void, c_int, size_t, pid_t, off_t, uid_t, gid_t};
77
use std::mem;
88
use std::ffi::CString;
99
use std::os::unix::io::RawFd;
1010

1111
#[cfg(any(target_os = "linux", target_os = "android"))]
1212
pub use self::linux::*;
1313

14-
mod ffi {
15-
use libc::{c_char, c_int, size_t};
16-
pub use libc::{fork, close, read, write, pipe, ftruncate, unlink, setpgid, getegid, geteuid, getgid, getpid, getppid, getuid, setuid, setgid, chown};
17-
18-
#[allow(improper_ctypes)]
19-
extern {
20-
// duplicate a file descriptor
21-
// doc: http://man7.org/linux/man-pages/man2/dup.2.html
22-
pub fn dup(oldfd: c_int) -> c_int;
23-
pub fn dup2(oldfd: c_int, newfd: c_int) -> c_int;
24-
25-
// change working directory
26-
// doc: http://man7.org/linux/man-pages/man2/chdir.2.html
27-
pub fn chdir(path: *const c_char) -> c_int;
28-
29-
// Execute PATH with arguments ARGV and environment from `environ'.
30-
// doc: http://man7.org/linux/man-pages/man3/execv.3.html
31-
pub fn execv(path: *const c_char, argv: *const *const c_char) -> c_int;
32-
33-
// execute program
34-
// doc: http://man7.org/linux/man-pages/man2/execve.2.html
35-
pub fn execve(path: *const c_char, argv: *const *const c_char, envp: *const *const c_char) -> c_int;
36-
37-
// Execute FILE, searching in the `PATH' environment variable if it contains
38-
// no slashes, with arguments ARGV and environment from `environ'.
39-
// doc: http://man7.org/linux/man-pages/man3/execvp.3.html
40-
pub fn execvp(filename: *const c_char, argv: *const *const c_char) -> c_int;
41-
42-
// doc: http://man7.org/linux/man-pages/man3/exec.3.html
43-
#[cfg(any(target_os = "linux", target_os = "android"))]
44-
#[cfg(feature = "execvpe")]
45-
pub fn execvpe(filename: *const c_char, argv: *const *const c_char, envp: *const *const c_char) -> c_int;
46-
47-
// run the current process in the background
48-
// doc: http://man7.org/linux/man-pages/man3/daemon.3.html
49-
pub fn daemon(nochdir: c_int, noclose: c_int) -> c_int;
50-
51-
// sets the hostname to the value given
52-
// doc: http://man7.org/linux/man-pages/man2/gethostname.2.html
53-
pub fn gethostname(name: *mut c_char, len: size_t) -> c_int;
54-
55-
// gets the hostname
56-
// doc: http://man7.org/linux/man-pages/man2/sethostname.2.html
57-
pub fn sethostname(name: *const c_char, len: size_t) -> c_int;
58-
59-
// change root directory
60-
// doc: http://man7.org/linux/man-pages/man2/chroot.2.html
61-
pub fn chroot(path: *const c_char) -> c_int;
62-
63-
// synchronize a file's in-core state with storage device
64-
// doc: http://man7.org/linux/man-pages/man2/fsync.2.html
65-
pub fn fsync(fd: c_int) -> c_int;
66-
pub fn fdatasync(fd: c_int) -> c_int;
67-
}
68-
}
69-
7014
#[derive(Clone, Copy)]
7115
pub enum Fork {
7216
Parent(pid_t),
@@ -90,7 +34,7 @@ impl Fork {
9034
}
9135

9236
pub fn fork() -> Result<Fork> {
93-
let res = unsafe { ffi::fork() };
37+
let res = unsafe { libc::fork() };
9438

9539
Errno::result(res).map(|res| match res {
9640
0 => Fork::Child,
@@ -100,28 +44,28 @@ pub fn fork() -> Result<Fork> {
10044

10145
#[inline]
10246
pub fn getpid() -> pid_t {
103-
unsafe { ffi::getpid() } // no error handling, according to man page: "These functions are always successful."
47+
unsafe { libc::getpid() } // no error handling, according to man page: "These functions are always successful."
10448
}
10549
#[inline]
10650
pub fn getppid() -> pid_t {
107-
unsafe { ffi::getppid() } // no error handling, according to man page: "These functions are always successful."
51+
unsafe { libc::getppid() } // no error handling, according to man page: "These functions are always successful."
10852
}
10953
#[inline]
11054
pub fn setpgid(pid: pid_t, pgid: pid_t) -> Result<()> {
111-
let res = unsafe { ffi::setpgid(pid, pgid) };
55+
let res = unsafe { libc::setpgid(pid, pgid) };
11256
Errno::result(res).map(drop)
11357
}
11458

11559
#[inline]
11660
pub fn dup(oldfd: RawFd) -> Result<RawFd> {
117-
let res = unsafe { ffi::dup(oldfd) };
61+
let res = unsafe { libc::dup(oldfd) };
11862

11963
Errno::result(res)
12064
}
12165

12266
#[inline]
12367
pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result<RawFd> {
124-
let res = unsafe { ffi::dup2(oldfd, newfd) };
68+
let res = unsafe { libc::dup2(oldfd, newfd) };
12569

12670
Errno::result(res)
12771
}
@@ -151,7 +95,7 @@ fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
15195
#[inline]
15296
pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
15397
let res = try!(path.with_nix_path(|cstr| {
154-
unsafe { ffi::chdir(cstr.as_ptr()) }
98+
unsafe { libc::chdir(cstr.as_ptr()) }
15599
}));
156100

157101
Errno::result(res).map(drop)
@@ -161,7 +105,7 @@ pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
161105
pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<uid_t>, group: Option<gid_t>) -> Result<()> {
162106
let res = try!(path.with_nix_path(|cstr| {
163107
// We use `0 - 1` to get `-1 : {u,g}id_t` which is specified as the no-op value for chown(3).
164-
unsafe { ffi::chown(cstr.as_ptr(), owner.unwrap_or(0 - 1), group.unwrap_or(0 - 1)) }
108+
unsafe { libc::chown(cstr.as_ptr(), owner.unwrap_or(0 - 1), group.unwrap_or(0 - 1)) }
165109
}));
166110

167111
Errno::result(res).map(drop)
@@ -181,7 +125,7 @@ pub fn execv(path: &CString, argv: &[CString]) -> Result<()> {
181125
let args_p = to_exec_array(argv);
182126

183127
unsafe {
184-
ffi::execv(path.as_ptr(), args_p.as_ptr())
128+
libc::execv(path.as_ptr(), args_p.as_ptr())
185129
};
186130

187131
Err(Error::Sys(Errno::last()))
@@ -193,7 +137,7 @@ pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<()> {
193137
let env_p = to_exec_array(env);
194138

195139
unsafe {
196-
ffi::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
140+
libc::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
197141
};
198142

199143
Err(Error::Sys(Errno::last()))
@@ -204,46 +148,54 @@ pub fn execvp(filename: &CString, args: &[CString]) -> Result<()> {
204148
let args_p = to_exec_array(args);
205149

206150
unsafe {
207-
ffi::execvp(filename.as_ptr(), args_p.as_ptr())
151+
libc::execvp(filename.as_ptr(), args_p.as_ptr())
208152
};
209153

210154
Err(Error::Sys(Errno::last()))
211155
}
212156

213157
pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
214-
let res = unsafe { ffi::daemon(nochdir as c_int, noclose as c_int) };
158+
let res = unsafe { libc::daemon(nochdir as c_int, noclose as c_int) };
215159
Errno::result(res).map(drop)
216160
}
217161

218162
pub fn sethostname(name: &[u8]) -> Result<()> {
163+
// Handle some differences in type of the len arg across platforms.
164+
cfg_if! {
165+
if #[cfg(any(target_os = "macos", target_os = "ios"))] {
166+
type sethostname_len_t = c_int;
167+
} else {
168+
type sethostname_len_t = size_t;
169+
}
170+
}
219171
let ptr = name.as_ptr() as *const c_char;
220-
let len = name.len() as size_t;
172+
let len = name.len() as sethostname_len_t;
221173

222-
let res = unsafe { ffi::sethostname(ptr, len) };
174+
let res = unsafe { libc::sethostname(ptr, len) };
223175
Errno::result(res).map(drop)
224176
}
225177

226178
pub fn gethostname(name: &mut [u8]) -> Result<()> {
227179
let ptr = name.as_mut_ptr() as *mut c_char;
228180
let len = name.len() as size_t;
229181

230-
let res = unsafe { ffi::gethostname(ptr, len) };
182+
let res = unsafe { libc::gethostname(ptr, len) };
231183
Errno::result(res).map(drop)
232184
}
233185

234186
pub fn close(fd: RawFd) -> Result<()> {
235-
let res = unsafe { ffi::close(fd) };
187+
let res = unsafe { libc::close(fd) };
236188
Errno::result(res).map(drop)
237189
}
238190

239191
pub fn read(fd: RawFd, buf: &mut [u8]) -> Result<usize> {
240-
let res = unsafe { ffi::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) };
192+
let res = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) };
241193

242194
Errno::result(res).map(|r| r as usize)
243195
}
244196

245197
pub fn write(fd: RawFd, buf: &[u8]) -> Result<usize> {
246-
let res = unsafe { ffi::write(fd, buf.as_ptr() as *const c_void, buf.len() as size_t) };
198+
let res = unsafe { libc::write(fd, buf.as_ptr() as *const c_void, buf.len() as size_t) };
247199

248200
Errno::result(res).map(|r| r as usize)
249201
}
@@ -252,7 +204,7 @@ pub fn pipe() -> Result<(RawFd, RawFd)> {
252204
unsafe {
253205
let mut fds: [c_int; 2] = mem::uninitialized();
254206

255-
let res = ffi::pipe(fds.as_mut_ptr());
207+
let res = libc::pipe(fds.as_mut_ptr());
256208

257209
try!(Errno::result(res));
258210

@@ -264,7 +216,7 @@ pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
264216
unsafe {
265217
let mut fds: [c_int; 2] = mem::uninitialized();
266218

267-
let res = ffi::pipe(fds.as_mut_ptr());
219+
let res = libc::pipe(fds.as_mut_ptr());
268220

269221
try!(Errno::result(res));
270222

@@ -300,7 +252,7 @@ fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> {
300252
}
301253

302254
pub fn ftruncate(fd: RawFd, len: off_t) -> Result<()> {
303-
Errno::result(unsafe { ffi::ftruncate(fd, len) }).map(drop)
255+
Errno::result(unsafe { libc::ftruncate(fd, len) }).map(drop)
304256
}
305257

306258
pub fn isatty(fd: RawFd) -> Result<bool> {
@@ -323,7 +275,7 @@ pub fn isatty(fd: RawFd) -> Result<bool> {
323275
pub fn unlink<P: ?Sized + NixPath>(path: &P) -> Result<()> {
324276
let res = try!(path.with_nix_path(|cstr| {
325277
unsafe {
326-
ffi::unlink(cstr.as_ptr())
278+
libc::unlink(cstr.as_ptr())
327279
}
328280
}));
329281

@@ -333,22 +285,27 @@ pub fn unlink<P: ?Sized + NixPath>(path: &P) -> Result<()> {
333285
#[inline]
334286
pub fn chroot<P: ?Sized + NixPath>(path: &P) -> Result<()> {
335287
let res = try!(path.with_nix_path(|cstr| {
336-
unsafe { ffi::chroot(cstr.as_ptr()) }
288+
unsafe { libc::chroot(cstr.as_ptr()) }
337289
}));
338290

339291
Errno::result(res).map(drop)
340292
}
341293

342294
#[inline]
343295
pub fn fsync(fd: RawFd) -> Result<()> {
344-
let res = unsafe { ffi::fsync(fd) };
296+
let res = unsafe { libc::fsync(fd) };
345297

346298
Errno::result(res).map(drop)
347299
}
348300

301+
// `fdatasync(2) is in POSIX, but in libc it is only defined in `libc::notbsd`.
302+
// TODO: exclude only Apple systems after https://github.com/rust-lang/libc/pull/211
303+
#[cfg(any(target_os = "linux",
304+
target_os = "android",
305+
target_os = "emscripten"))]
349306
#[inline]
350307
pub fn fdatasync(fd: RawFd) -> Result<()> {
351-
let res = unsafe { ffi::fdatasync(fd) };
308+
let res = unsafe { libc::fdatasync(fd) };
352309

353310
Errno::result(res).map(drop)
354311
}
@@ -361,34 +318,34 @@ pub fn fdatasync(fd: RawFd) -> Result<()> {
361318
// - http://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html
362319
#[inline]
363320
pub fn getuid() -> uid_t {
364-
unsafe { ffi::getuid() }
321+
unsafe { libc::getuid() }
365322
}
366323

367324
#[inline]
368325
pub fn geteuid() -> uid_t {
369-
unsafe { ffi::geteuid() }
326+
unsafe { libc::geteuid() }
370327
}
371328

372329
#[inline]
373330
pub fn getgid() -> gid_t {
374-
unsafe { ffi::getgid() }
331+
unsafe { libc::getgid() }
375332
}
376333

377334
#[inline]
378335
pub fn getegid() -> gid_t {
379-
unsafe { ffi::getegid() }
336+
unsafe { libc::getegid() }
380337
}
381338

382339
#[inline]
383340
pub fn setuid(uid: uid_t) -> Result<()> {
384-
let res = unsafe { ffi::setuid(uid) };
341+
let res = unsafe { libc::setuid(uid) };
385342

386343
Errno::result(res).map(drop)
387344
}
388345

389346
#[inline]
390347
pub fn setgid(gid: gid_t) -> Result<()> {
391-
let res = unsafe { ffi::setgid(gid) };
348+
let res = unsafe { libc::setgid(gid) };
392349

393350
Errno::result(res).map(drop)
394351
}

0 commit comments

Comments
 (0)