3
3
use { Errno , Error , Result , NixPath } ;
4
4
use fcntl:: { fcntl, OFlag , O_NONBLOCK , O_CLOEXEC , FD_CLOEXEC } ;
5
5
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} ;
7
7
use std:: mem;
8
8
use std:: ffi:: CString ;
9
9
use std:: os:: unix:: io:: RawFd ;
10
10
11
11
#[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
12
12
pub use self :: linux:: * ;
13
13
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
-
70
14
#[ derive( Clone , Copy ) ]
71
15
pub enum Fork {
72
16
Parent ( pid_t ) ,
@@ -90,7 +34,7 @@ impl Fork {
90
34
}
91
35
92
36
pub fn fork ( ) -> Result < Fork > {
93
- let res = unsafe { ffi :: fork ( ) } ;
37
+ let res = unsafe { libc :: fork ( ) } ;
94
38
95
39
Errno :: result ( res) . map ( |res| match res {
96
40
0 => Fork :: Child ,
@@ -100,28 +44,28 @@ pub fn fork() -> Result<Fork> {
100
44
101
45
#[ inline]
102
46
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."
104
48
}
105
49
#[ inline]
106
50
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."
108
52
}
109
53
#[ inline]
110
54
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) } ;
112
56
Errno :: result ( res) . map ( drop)
113
57
}
114
58
115
59
#[ inline]
116
60
pub fn dup ( oldfd : RawFd ) -> Result < RawFd > {
117
- let res = unsafe { ffi :: dup ( oldfd) } ;
61
+ let res = unsafe { libc :: dup ( oldfd) } ;
118
62
119
63
Errno :: result ( res)
120
64
}
121
65
122
66
#[ inline]
123
67
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) } ;
125
69
126
70
Errno :: result ( res)
127
71
}
@@ -151,7 +95,7 @@ fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
151
95
#[ inline]
152
96
pub fn chdir < P : ?Sized + NixPath > ( path : & P ) -> Result < ( ) > {
153
97
let res = try!( path. with_nix_path ( |cstr| {
154
- unsafe { ffi :: chdir ( cstr. as_ptr ( ) ) }
98
+ unsafe { libc :: chdir ( cstr. as_ptr ( ) ) }
155
99
} ) ) ;
156
100
157
101
Errno :: result ( res) . map ( drop)
@@ -161,7 +105,7 @@ pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
161
105
pub fn chown < P : ?Sized + NixPath > ( path : & P , owner : Option < uid_t > , group : Option < gid_t > ) -> Result < ( ) > {
162
106
let res = try!( path. with_nix_path ( |cstr| {
163
107
// 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 ) ) }
165
109
} ) ) ;
166
110
167
111
Errno :: result ( res) . map ( drop)
@@ -181,7 +125,7 @@ pub fn execv(path: &CString, argv: &[CString]) -> Result<()> {
181
125
let args_p = to_exec_array ( argv) ;
182
126
183
127
unsafe {
184
- ffi :: execv ( path. as_ptr ( ) , args_p. as_ptr ( ) )
128
+ libc :: execv ( path. as_ptr ( ) , args_p. as_ptr ( ) )
185
129
} ;
186
130
187
131
Err ( Error :: Sys ( Errno :: last ( ) ) )
@@ -193,7 +137,7 @@ pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<()> {
193
137
let env_p = to_exec_array ( env) ;
194
138
195
139
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 ( ) )
197
141
} ;
198
142
199
143
Err ( Error :: Sys ( Errno :: last ( ) ) )
@@ -204,46 +148,54 @@ pub fn execvp(filename: &CString, args: &[CString]) -> Result<()> {
204
148
let args_p = to_exec_array ( args) ;
205
149
206
150
unsafe {
207
- ffi :: execvp ( filename. as_ptr ( ) , args_p. as_ptr ( ) )
151
+ libc :: execvp ( filename. as_ptr ( ) , args_p. as_ptr ( ) )
208
152
} ;
209
153
210
154
Err ( Error :: Sys ( Errno :: last ( ) ) )
211
155
}
212
156
213
157
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 ) } ;
215
159
Errno :: result ( res) . map ( drop)
216
160
}
217
161
218
162
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
+ }
219
171
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 ;
221
173
222
- let res = unsafe { ffi :: sethostname ( ptr, len) } ;
174
+ let res = unsafe { libc :: sethostname ( ptr, len) } ;
223
175
Errno :: result ( res) . map ( drop)
224
176
}
225
177
226
178
pub fn gethostname ( name : & mut [ u8 ] ) -> Result < ( ) > {
227
179
let ptr = name. as_mut_ptr ( ) as * mut c_char ;
228
180
let len = name. len ( ) as size_t ;
229
181
230
- let res = unsafe { ffi :: gethostname ( ptr, len) } ;
182
+ let res = unsafe { libc :: gethostname ( ptr, len) } ;
231
183
Errno :: result ( res) . map ( drop)
232
184
}
233
185
234
186
pub fn close ( fd : RawFd ) -> Result < ( ) > {
235
- let res = unsafe { ffi :: close ( fd) } ;
187
+ let res = unsafe { libc :: close ( fd) } ;
236
188
Errno :: result ( res) . map ( drop)
237
189
}
238
190
239
191
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 ) } ;
241
193
242
194
Errno :: result ( res) . map ( |r| r as usize )
243
195
}
244
196
245
197
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 ) } ;
247
199
248
200
Errno :: result ( res) . map ( |r| r as usize )
249
201
}
@@ -252,7 +204,7 @@ pub fn pipe() -> Result<(RawFd, RawFd)> {
252
204
unsafe {
253
205
let mut fds: [ c_int ; 2 ] = mem:: uninitialized ( ) ;
254
206
255
- let res = ffi :: pipe ( fds. as_mut_ptr ( ) ) ;
207
+ let res = libc :: pipe ( fds. as_mut_ptr ( ) ) ;
256
208
257
209
try!( Errno :: result ( res) ) ;
258
210
@@ -264,7 +216,7 @@ pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
264
216
unsafe {
265
217
let mut fds: [ c_int ; 2 ] = mem:: uninitialized ( ) ;
266
218
267
- let res = ffi :: pipe ( fds. as_mut_ptr ( ) ) ;
219
+ let res = libc :: pipe ( fds. as_mut_ptr ( ) ) ;
268
220
269
221
try!( Errno :: result ( res) ) ;
270
222
@@ -300,7 +252,7 @@ fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> {
300
252
}
301
253
302
254
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)
304
256
}
305
257
306
258
pub fn isatty ( fd : RawFd ) -> Result < bool > {
@@ -323,7 +275,7 @@ pub fn isatty(fd: RawFd) -> Result<bool> {
323
275
pub fn unlink < P : ?Sized + NixPath > ( path : & P ) -> Result < ( ) > {
324
276
let res = try!( path. with_nix_path ( |cstr| {
325
277
unsafe {
326
- ffi :: unlink ( cstr. as_ptr ( ) )
278
+ libc :: unlink ( cstr. as_ptr ( ) )
327
279
}
328
280
} ) ) ;
329
281
@@ -333,22 +285,27 @@ pub fn unlink<P: ?Sized + NixPath>(path: &P) -> Result<()> {
333
285
#[ inline]
334
286
pub fn chroot < P : ?Sized + NixPath > ( path : & P ) -> Result < ( ) > {
335
287
let res = try!( path. with_nix_path ( |cstr| {
336
- unsafe { ffi :: chroot ( cstr. as_ptr ( ) ) }
288
+ unsafe { libc :: chroot ( cstr. as_ptr ( ) ) }
337
289
} ) ) ;
338
290
339
291
Errno :: result ( res) . map ( drop)
340
292
}
341
293
342
294
#[ inline]
343
295
pub fn fsync ( fd : RawFd ) -> Result < ( ) > {
344
- let res = unsafe { ffi :: fsync ( fd) } ;
296
+ let res = unsafe { libc :: fsync ( fd) } ;
345
297
346
298
Errno :: result ( res) . map ( drop)
347
299
}
348
300
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" ) ) ]
349
306
#[ inline]
350
307
pub fn fdatasync ( fd : RawFd ) -> Result < ( ) > {
351
- let res = unsafe { ffi :: fdatasync ( fd) } ;
308
+ let res = unsafe { libc :: fdatasync ( fd) } ;
352
309
353
310
Errno :: result ( res) . map ( drop)
354
311
}
@@ -361,34 +318,34 @@ pub fn fdatasync(fd: RawFd) -> Result<()> {
361
318
// - http://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html
362
319
#[ inline]
363
320
pub fn getuid ( ) -> uid_t {
364
- unsafe { ffi :: getuid ( ) }
321
+ unsafe { libc :: getuid ( ) }
365
322
}
366
323
367
324
#[ inline]
368
325
pub fn geteuid ( ) -> uid_t {
369
- unsafe { ffi :: geteuid ( ) }
326
+ unsafe { libc :: geteuid ( ) }
370
327
}
371
328
372
329
#[ inline]
373
330
pub fn getgid ( ) -> gid_t {
374
- unsafe { ffi :: getgid ( ) }
331
+ unsafe { libc :: getgid ( ) }
375
332
}
376
333
377
334
#[ inline]
378
335
pub fn getegid ( ) -> gid_t {
379
- unsafe { ffi :: getegid ( ) }
336
+ unsafe { libc :: getegid ( ) }
380
337
}
381
338
382
339
#[ inline]
383
340
pub fn setuid ( uid : uid_t ) -> Result < ( ) > {
384
- let res = unsafe { ffi :: setuid ( uid) } ;
341
+ let res = unsafe { libc :: setuid ( uid) } ;
385
342
386
343
Errno :: result ( res) . map ( drop)
387
344
}
388
345
389
346
#[ inline]
390
347
pub fn setgid ( gid : gid_t ) -> Result < ( ) > {
391
- let res = unsafe { ffi :: setgid ( gid) } ;
348
+ let res = unsafe { libc :: setgid ( gid) } ;
392
349
393
350
Errno :: result ( res) . map ( drop)
394
351
}
0 commit comments