1#![crate_name = "nix"]
6#![cfg(unix)]
7#![allow(non_camel_case_types)]
8#![cfg_attr(test, deny(warnings))]
9#![recursion_limit = "500"]
10#![deny(unused)]
11#![deny(unstable_features)]
12#![deny(missing_copy_implementations)]
13#![deny(missing_debug_implementations)]
14#![warn(missing_docs)]
15
16pub use libc;
18
19#[macro_use] mod macros;
21
22#[cfg(not(target_os = "redox"))]
24#[allow(missing_docs)]
25pub mod dir;
26pub mod env;
27#[allow(missing_docs)]
28pub mod errno;
29pub mod features;
30#[allow(missing_docs)]
31pub mod fcntl;
32#[cfg(any(target_os = "android",
33 target_os = "dragonfly",
34 target_os = "freebsd",
35 target_os = "ios",
36 target_os = "linux",
37 target_os = "macos",
38 target_os = "netbsd",
39 target_os = "illumos",
40 target_os = "openbsd"))]
41pub mod ifaddrs;
42#[cfg(any(target_os = "android",
43 target_os = "linux"))]
44#[allow(missing_docs)]
45pub mod kmod;
46#[cfg(any(target_os = "android",
47 target_os = "freebsd",
48 target_os = "linux"))]
49pub mod mount;
50#[cfg(any(target_os = "dragonfly",
51 target_os = "freebsd",
52 target_os = "fushsia",
53 target_os = "linux",
54 target_os = "netbsd"))]
55#[allow(missing_docs)]
56pub mod mqueue;
57#[cfg(not(target_os = "redox"))]
58pub mod net;
59pub mod poll;
60#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
61pub mod pty;
62pub mod sched;
63pub mod sys;
64#[allow(missing_docs)]
65pub mod time;
66#[cfg(all(target_os = "linux",
69 any(target_arch = "x86", target_arch = "x86_64")))]
70#[allow(missing_docs)]
71pub mod ucontext;
72#[allow(missing_docs)]
73pub mod unistd;
74
75use libc::{c_char, PATH_MAX};
82
83use std::{ptr, result};
84use std::ffi::{CStr, OsStr};
85use std::os::unix::ffi::OsStrExt;
86use std::path::{Path, PathBuf};
87
88use errno::Errno;
89
90pub type Result<T> = result::Result<T, Errno>;
92
93pub type Error = Errno;
104
105pub trait NixPath {
107 fn is_empty(&self) -> bool;
109
110 fn len(&self) -> usize;
112
113 fn with_nix_path<T, F>(&self, f: F) -> Result<T>
117 where F: FnOnce(&CStr) -> T;
118}
119
120impl NixPath for str {
121 fn is_empty(&self) -> bool {
122 NixPath::is_empty(OsStr::new(self))
123 }
124
125 fn len(&self) -> usize {
126 NixPath::len(OsStr::new(self))
127 }
128
129 fn with_nix_path<T, F>(&self, f: F) -> Result<T>
130 where F: FnOnce(&CStr) -> T {
131 OsStr::new(self).with_nix_path(f)
132 }
133}
134
135impl NixPath for OsStr {
136 fn is_empty(&self) -> bool {
137 self.as_bytes().is_empty()
138 }
139
140 fn len(&self) -> usize {
141 self.as_bytes().len()
142 }
143
144 fn with_nix_path<T, F>(&self, f: F) -> Result<T>
145 where F: FnOnce(&CStr) -> T {
146 self.as_bytes().with_nix_path(f)
147 }
148}
149
150impl NixPath for CStr {
151 fn is_empty(&self) -> bool {
152 self.to_bytes().is_empty()
153 }
154
155 fn len(&self) -> usize {
156 self.to_bytes().len()
157 }
158
159 fn with_nix_path<T, F>(&self, f: F) -> Result<T>
160 where F: FnOnce(&CStr) -> T {
161 if self.len() >= PATH_MAX as usize {
163 return Err(Errno::ENAMETOOLONG)
164 }
165
166 Ok(f(self))
167 }
168}
169
170impl NixPath for [u8] {
171 fn is_empty(&self) -> bool {
172 self.is_empty()
173 }
174
175 fn len(&self) -> usize {
176 self.len()
177 }
178
179 fn with_nix_path<T, F>(&self, f: F) -> Result<T>
180 where F: FnOnce(&CStr) -> T {
181 let mut buf = [0u8; PATH_MAX as usize];
182
183 if self.len() >= PATH_MAX as usize {
184 return Err(Errno::ENAMETOOLONG)
185 }
186
187 match self.iter().position(|b| *b == 0) {
188 Some(_) => Err(Errno::EINVAL),
189 None => {
190 unsafe {
191 ptr::copy_nonoverlapping(self.as_ptr(), buf.as_mut_ptr(), self.len());
193 Ok(f(CStr::from_ptr(buf.as_ptr() as *const c_char)))
194 }
195
196 }
197 }
198 }
199}
200
201impl NixPath for Path {
202 fn is_empty(&self) -> bool {
203 NixPath::is_empty(self.as_os_str())
204 }
205
206 fn len(&self) -> usize {
207 NixPath::len(self.as_os_str())
208 }
209
210 fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
211 self.as_os_str().with_nix_path(f)
212 }
213}
214
215impl NixPath for PathBuf {
216 fn is_empty(&self) -> bool {
217 NixPath::is_empty(self.as_os_str())
218 }
219
220 fn len(&self) -> usize {
221 NixPath::len(self.as_os_str())
222 }
223
224 fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
225 self.as_os_str().with_nix_path(f)
226 }
227}