mod.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. //! unistd implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/unistd.h.html
  2. use core::convert::TryFrom;
  3. use core::{mem, ptr, slice};
  4. use alloc::collections::LinkedList;
  5. use crate::c_str::CStr;
  6. use crate::header::errno;
  7. use crate::header::limits;
  8. use crate::header::stdlib::getenv;
  9. use crate::header::sys_ioctl;
  10. use crate::header::sys_time;
  11. use crate::header::termios;
  12. use crate::header::time::timespec;
  13. use crate::platform;
  14. use crate::platform::types::*;
  15. use crate::platform::{Pal, Sys};
  16. pub use self::brk::*;
  17. pub use self::getopt::*;
  18. pub use self::pathconf::*;
  19. pub use self::sysconf::*;
  20. mod brk;
  21. mod getopt;
  22. mod pathconf;
  23. mod sysconf;
  24. pub const F_OK: c_int = 0;
  25. pub const R_OK: c_int = 4;
  26. pub const W_OK: c_int = 2;
  27. pub const X_OK: c_int = 1;
  28. pub const SEEK_SET: c_int = 0;
  29. pub const SEEK_CUR: c_int = 1;
  30. pub const SEEK_END: c_int = 2;
  31. pub const F_ULOCK: c_int = 0;
  32. pub const F_LOCK: c_int = 1;
  33. pub const F_TLOCK: c_int = 2;
  34. pub const F_TEST: c_int = 3;
  35. pub const STDIN_FILENO: c_int = 0;
  36. pub const STDOUT_FILENO: c_int = 1;
  37. pub const STDERR_FILENO: c_int = 2;
  38. #[thread_local]
  39. pub static mut fork_hooks_static: Option<[LinkedList<extern "C" fn()>; 3]> = None;
  40. unsafe fn init_fork_hooks<'a>() -> &'a mut [LinkedList<extern "C" fn()>; 3] {
  41. // Transmute the lifetime so we can return here. Should be safe as
  42. // long as one does not access the original fork_hooks.
  43. mem::transmute(
  44. fork_hooks_static
  45. .get_or_insert_with(|| [LinkedList::new(), LinkedList::new(), LinkedList::new()]),
  46. )
  47. }
  48. #[no_mangle]
  49. pub extern "C" fn _exit(status: c_int) {
  50. Sys::exit(status)
  51. }
  52. #[no_mangle]
  53. pub unsafe extern "C" fn access(path: *const c_char, mode: c_int) -> c_int {
  54. let path = CStr::from_ptr(path);
  55. Sys::access(path, mode)
  56. }
  57. #[no_mangle]
  58. pub extern "C" fn alarm(seconds: c_uint) -> c_uint {
  59. let mut timer = sys_time::itimerval {
  60. it_value: sys_time::timeval {
  61. tv_sec: seconds as time_t,
  62. tv_usec: 0,
  63. },
  64. ..Default::default()
  65. };
  66. let errno_backup = unsafe { platform::errno };
  67. let secs = if sys_time::setitimer(sys_time::ITIMER_REAL, &timer, &mut timer) < 0 {
  68. 0
  69. } else {
  70. timer.it_value.tv_sec as c_uint + if timer.it_value.tv_usec > 0 { 1 } else { 0 }
  71. };
  72. unsafe {
  73. platform::errno = errno_backup;
  74. }
  75. secs
  76. }
  77. #[no_mangle]
  78. pub unsafe extern "C" fn chdir(path: *const c_char) -> c_int {
  79. let path = CStr::from_ptr(path);
  80. Sys::chdir(path)
  81. }
  82. // #[no_mangle]
  83. pub extern "C" fn chroot(path: *const c_char) -> c_int {
  84. unimplemented!();
  85. }
  86. #[no_mangle]
  87. pub unsafe extern "C" fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
  88. let path = CStr::from_ptr(path);
  89. Sys::chown(path, owner, group)
  90. }
  91. #[no_mangle]
  92. pub extern "C" fn close(fildes: c_int) -> c_int {
  93. Sys::close(fildes)
  94. }
  95. // #[no_mangle]
  96. pub extern "C" fn confstr(name: c_int, buf: *mut c_char, len: size_t) -> size_t {
  97. unimplemented!();
  98. }
  99. // #[no_mangle]
  100. pub extern "C" fn crypt(key: *const c_char, salt: *const c_char) -> *mut c_char {
  101. unimplemented!();
  102. }
  103. #[no_mangle]
  104. pub extern "C" fn dup(fildes: c_int) -> c_int {
  105. Sys::dup(fildes)
  106. }
  107. #[no_mangle]
  108. pub extern "C" fn dup2(fildes: c_int, fildes2: c_int) -> c_int {
  109. Sys::dup2(fildes, fildes2)
  110. }
  111. // #[no_mangle]
  112. pub extern "C" fn encrypt(block: [c_char; 64], edflag: c_int) {
  113. unimplemented!();
  114. }
  115. // #[no_mangle]
  116. // pub extern "C" fn execl(path: *const c_char, args: *const *mut c_char) -> c_int {
  117. // unimplemented!();
  118. // }
  119. // #[no_mangle]
  120. // pub extern "C" fn execle(
  121. // path: *const c_char,
  122. // args: *const *mut c_char,
  123. // envp: *const *mut c_char,
  124. // ) -> c_int {
  125. // unimplemented!();
  126. // }
  127. // #[no_mangle]
  128. // pub extern "C" fn execlp(file: *const c_char, args: *const *mut c_char) -> c_int {
  129. // unimplemented!();
  130. // }
  131. #[no_mangle]
  132. pub unsafe extern "C" fn execv(path: *const c_char, argv: *const *mut c_char) -> c_int {
  133. execve(path, argv, platform::environ)
  134. }
  135. #[no_mangle]
  136. pub unsafe extern "C" fn execve(
  137. path: *const c_char,
  138. argv: *const *mut c_char,
  139. envp: *const *mut c_char,
  140. ) -> c_int {
  141. let path = CStr::from_ptr(path);
  142. Sys::execve(path, argv, envp)
  143. }
  144. #[cfg(target_os = "linux")]
  145. const PATH_SEPARATOR: u8 = b':';
  146. #[cfg(target_os = "redox")]
  147. const PATH_SEPARATOR: u8 = b';';
  148. #[no_mangle]
  149. pub unsafe extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) -> c_int {
  150. let file = CStr::from_ptr(file);
  151. if file.to_bytes().contains(&b'/')
  152. || (cfg!(target_os = "redox") && file.to_bytes().contains(&b':'))
  153. {
  154. execv(file.as_ptr(), argv)
  155. } else {
  156. let mut error = errno::ENOENT;
  157. let path_env = getenv(c_str!("PATH\0").as_ptr());
  158. if !path_env.is_null() {
  159. let path_env = CStr::from_ptr(path_env);
  160. for path in path_env.to_bytes().split(|&b| b == PATH_SEPARATOR) {
  161. let mut program = path.to_vec();
  162. program.push(b'/');
  163. program.extend_from_slice(file.to_bytes());
  164. program.push(b'\0');
  165. let program_c = CStr::from_bytes_with_nul(&program).unwrap();
  166. execv(program_c.as_ptr(), argv);
  167. match platform::errno {
  168. errno::ENOENT => (),
  169. other => error = other,
  170. }
  171. }
  172. }
  173. platform::errno = error;
  174. -1
  175. }
  176. }
  177. #[no_mangle]
  178. pub extern "C" fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int {
  179. Sys::fchown(fildes, owner, group)
  180. }
  181. #[no_mangle]
  182. pub extern "C" fn fchdir(fildes: c_int) -> c_int {
  183. Sys::fchdir(fildes)
  184. }
  185. // #[no_mangle]
  186. pub extern "C" fn fdatasync(fildes: c_int) -> c_int {
  187. unimplemented!();
  188. }
  189. #[no_mangle]
  190. pub extern "C" fn fork() -> pid_t {
  191. let fork_hooks = unsafe { init_fork_hooks() };
  192. for prepare in &fork_hooks[0] {
  193. prepare();
  194. }
  195. let pid = Sys::fork();
  196. if pid == 0 {
  197. for child in &fork_hooks[2] {
  198. child();
  199. }
  200. } else if pid != -1 {
  201. for parent in &fork_hooks[1] {
  202. parent();
  203. }
  204. }
  205. pid
  206. }
  207. #[no_mangle]
  208. pub extern "C" fn fsync(fildes: c_int) -> c_int {
  209. Sys::fsync(fildes)
  210. }
  211. #[no_mangle]
  212. pub extern "C" fn ftruncate(fildes: c_int, length: off_t) -> c_int {
  213. Sys::ftruncate(fildes, length)
  214. }
  215. #[no_mangle]
  216. pub extern "C" fn getcwd(mut buf: *mut c_char, mut size: size_t) -> *mut c_char {
  217. let alloc = buf.is_null();
  218. let mut stack_buf = [0; limits::PATH_MAX];
  219. if alloc {
  220. buf = stack_buf.as_mut_ptr();
  221. size = stack_buf.len();
  222. }
  223. let ret = Sys::getcwd(buf, size);
  224. if ret.is_null() {
  225. return ptr::null_mut();
  226. }
  227. if alloc {
  228. let len = stack_buf
  229. .iter()
  230. .position(|b| *b == 0)
  231. .expect("no nul-byte in getcwd string")
  232. + 1;
  233. let heap_buf = unsafe { platform::alloc(len) as *mut c_char };
  234. for i in 0..len {
  235. unsafe {
  236. *heap_buf.add(i) = stack_buf[i];
  237. }
  238. }
  239. heap_buf
  240. } else {
  241. ret
  242. }
  243. }
  244. // #[no_mangle]
  245. pub extern "C" fn getdtablesize() -> c_int {
  246. unimplemented!();
  247. }
  248. #[no_mangle]
  249. pub extern "C" fn getegid() -> gid_t {
  250. Sys::getegid()
  251. }
  252. #[no_mangle]
  253. pub extern "C" fn geteuid() -> uid_t {
  254. Sys::geteuid()
  255. }
  256. #[no_mangle]
  257. pub extern "C" fn getgid() -> gid_t {
  258. Sys::getgid()
  259. }
  260. // #[no_mangle]
  261. pub extern "C" fn getgroups(gidsetsize: c_int, grouplist: *mut gid_t) -> c_int {
  262. unimplemented!();
  263. }
  264. // #[no_mangle]
  265. pub extern "C" fn gethostid() -> c_long {
  266. unimplemented!();
  267. }
  268. #[no_mangle]
  269. pub unsafe extern "C" fn gethostname(mut name: *mut c_char, mut len: size_t) -> c_int {
  270. let mut uts = mem::uninitialized();
  271. let err = Sys::uname(&mut uts);
  272. if err < 0 {
  273. mem::forget(uts);
  274. return err;
  275. }
  276. for c in uts.nodename.iter() {
  277. if len == 0 {
  278. break;
  279. }
  280. len -= 1;
  281. *name = *c;
  282. if *name == 0 {
  283. // We do want to copy the zero also, so we check this after the copying.
  284. break;
  285. }
  286. name = name.offset(1);
  287. }
  288. 0
  289. }
  290. #[no_mangle]
  291. pub unsafe extern "C" fn getlogin() -> *mut c_char {
  292. static mut LOGIN: [c_char; 256] = [0; 256];
  293. if getlogin_r(LOGIN.as_mut_ptr(), LOGIN.len()) == 0 {
  294. LOGIN.as_mut_ptr()
  295. } else {
  296. ptr::null_mut()
  297. }
  298. }
  299. #[no_mangle]
  300. pub extern "C" fn getlogin_r(name: *mut c_char, namesize: size_t) -> c_int {
  301. //TODO: Determine correct getlogin result on Redox
  302. unsafe { platform::errno = errno::ENOENT };
  303. -1
  304. }
  305. #[no_mangle]
  306. pub extern "C" fn getpagesize() -> c_int {
  307. match c_int::try_from(sysconf(_SC_PAGESIZE)) {
  308. Ok(page_size) => page_size,
  309. Err(_) => {
  310. /* Behavior not specified by POSIX for this case. The -1
  311. * value mimics sysconf()'s behavior, though.
  312. *
  313. * As specified for the limits.h header, the minimum
  314. * acceptable value for {PAGESIZE} is 1. The -1 value thus
  315. * cannot be mistaken for an acceptable value.
  316. *
  317. * POSIX does not specify any possible errors for this
  318. * function, hence no errno setting. */
  319. -1
  320. }
  321. }
  322. }
  323. // #[no_mangle]
  324. pub extern "C" fn getpass(prompt: *const c_char) -> *mut c_char {
  325. unimplemented!();
  326. }
  327. #[no_mangle]
  328. pub extern "C" fn getpgid(pid: pid_t) -> pid_t {
  329. Sys::getpgid(pid)
  330. }
  331. #[no_mangle]
  332. pub extern "C" fn getpgrp() -> pid_t {
  333. Sys::getpgid(Sys::getpid())
  334. }
  335. #[no_mangle]
  336. pub extern "C" fn getpid() -> pid_t {
  337. Sys::getpid()
  338. }
  339. #[no_mangle]
  340. pub extern "C" fn getppid() -> pid_t {
  341. Sys::getppid()
  342. }
  343. // #[no_mangle]
  344. pub extern "C" fn getsid(pid: pid_t) -> pid_t {
  345. unimplemented!();
  346. }
  347. #[no_mangle]
  348. pub extern "C" fn getuid() -> uid_t {
  349. Sys::getuid()
  350. }
  351. #[no_mangle]
  352. pub extern "C" fn getwd(path_name: *mut c_char) -> *mut c_char {
  353. getcwd(path_name, limits::PATH_MAX)
  354. }
  355. #[no_mangle]
  356. pub extern "C" fn isatty(fd: c_int) -> c_int {
  357. let mut t = termios::termios::default();
  358. if unsafe { termios::tcgetattr(fd, &mut t as *mut termios::termios) == 0 } {
  359. 1
  360. } else {
  361. 0
  362. }
  363. }
  364. // #[no_mangle]
  365. pub extern "C" fn lchown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
  366. unimplemented!();
  367. }
  368. #[no_mangle]
  369. pub unsafe extern "C" fn link(path1: *const c_char, path2: *const c_char) -> c_int {
  370. let path1 = CStr::from_ptr(path1);
  371. let path2 = CStr::from_ptr(path2);
  372. Sys::link(path1, path2)
  373. }
  374. // #[no_mangle]
  375. pub extern "C" fn lockf(fildes: c_int, function: c_int, size: off_t) -> c_int {
  376. unimplemented!();
  377. }
  378. #[no_mangle]
  379. pub extern "C" fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> off_t {
  380. Sys::lseek(fildes, offset, whence)
  381. }
  382. // #[no_mangle]
  383. pub extern "C" fn nice(incr: c_int) -> c_int {
  384. unimplemented!();
  385. }
  386. // #[no_mangle]
  387. pub extern "C" fn pause() -> c_int {
  388. unimplemented!();
  389. }
  390. #[no_mangle]
  391. pub unsafe extern "C" fn pipe(fildes: *mut c_int) -> c_int {
  392. pipe2(fildes, 0)
  393. }
  394. #[no_mangle]
  395. pub unsafe extern "C" fn pipe2(fildes: *mut c_int, flags: c_int) -> c_int {
  396. Sys::pipe2(slice::from_raw_parts_mut(fildes, 2), flags)
  397. }
  398. #[no_mangle]
  399. pub extern "C" fn pread(fildes: c_int, buf: *mut c_void, nbyte: size_t, offset: off_t) -> ssize_t {
  400. //TODO: better pread using system calls
  401. let previous = lseek(fildes, offset, SEEK_SET);
  402. if previous == -1 {
  403. return -1;
  404. }
  405. let res = read(fildes, buf, nbyte);
  406. if res < 0 {
  407. return res;
  408. }
  409. if lseek(fildes, previous, SEEK_SET) == -1 {
  410. return -1;
  411. }
  412. res
  413. }
  414. #[no_mangle]
  415. pub extern "C" fn pthread_atfork(
  416. prepare: Option<extern "C" fn()>,
  417. parent: Option<extern "C" fn()>,
  418. child: Option<extern "C" fn()>,
  419. ) -> c_int {
  420. let fork_hooks = unsafe { init_fork_hooks() };
  421. if let Some(prepare) = prepare {
  422. fork_hooks[0].push_back(prepare);
  423. }
  424. if let Some(parent) = parent {
  425. fork_hooks[1].push_back(parent);
  426. }
  427. if let Some(child) = child {
  428. fork_hooks[2].push_back(child);
  429. }
  430. 0
  431. }
  432. #[no_mangle]
  433. pub extern "C" fn pwrite(
  434. fildes: c_int,
  435. buf: *const c_void,
  436. nbyte: size_t,
  437. offset: off_t,
  438. ) -> ssize_t {
  439. //TODO: better pwrite using system calls
  440. let previous = lseek(fildes, offset, SEEK_SET);
  441. if previous == -1 {
  442. return -1;
  443. }
  444. let res = write(fildes, buf, nbyte);
  445. if res < 0 {
  446. return res;
  447. }
  448. if lseek(fildes, previous, SEEK_SET) == -1 {
  449. return -1;
  450. }
  451. res
  452. }
  453. #[no_mangle]
  454. pub extern "C" fn read(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t {
  455. let buf = unsafe { slice::from_raw_parts_mut(buf as *mut u8, nbyte as usize) };
  456. trace_expr!(
  457. Sys::read(fildes, buf),
  458. "read({}, {:p}, {})",
  459. fildes,
  460. buf,
  461. nbyte
  462. )
  463. }
  464. #[no_mangle]
  465. pub unsafe extern "C" fn readlink(
  466. path: *const c_char,
  467. buf: *mut c_char,
  468. bufsize: size_t,
  469. ) -> ssize_t {
  470. let path = CStr::from_ptr(path);
  471. let buf = slice::from_raw_parts_mut(buf as *mut u8, bufsize as usize);
  472. Sys::readlink(path, buf)
  473. }
  474. #[no_mangle]
  475. pub unsafe extern "C" fn rmdir(path: *const c_char) -> c_int {
  476. let path = CStr::from_ptr(path);
  477. Sys::rmdir(path)
  478. }
  479. #[no_mangle]
  480. pub extern "C" fn setgid(gid: gid_t) -> c_int {
  481. Sys::setregid(gid, gid)
  482. }
  483. #[no_mangle]
  484. pub extern "C" fn setpgid(pid: pid_t, pgid: pid_t) -> c_int {
  485. Sys::setpgid(pid, pgid)
  486. }
  487. #[no_mangle]
  488. pub extern "C" fn setpgrp() -> pid_t {
  489. setpgid(0, 0)
  490. }
  491. #[no_mangle]
  492. pub extern "C" fn setregid(rgid: gid_t, egid: gid_t) -> c_int {
  493. Sys::setregid(rgid, egid)
  494. }
  495. #[no_mangle]
  496. pub extern "C" fn setreuid(ruid: uid_t, euid: uid_t) -> c_int {
  497. Sys::setreuid(ruid, euid)
  498. }
  499. // #[no_mangle]
  500. pub extern "C" fn setsid() -> pid_t {
  501. unimplemented!();
  502. }
  503. #[no_mangle]
  504. pub extern "C" fn setuid(uid: uid_t) -> c_int {
  505. Sys::setreuid(uid, uid)
  506. }
  507. #[no_mangle]
  508. pub extern "C" fn sleep(seconds: c_uint) -> c_uint {
  509. let rqtp = timespec {
  510. tv_sec: seconds as i64,
  511. tv_nsec: 0,
  512. };
  513. let rmtp = ptr::null_mut();
  514. Sys::nanosleep(&rqtp, rmtp);
  515. 0
  516. }
  517. #[no_mangle]
  518. pub extern "C" fn swab(src: *const c_void, dest: *mut c_void, nbytes: ssize_t) {
  519. if nbytes <= 0 {
  520. return;
  521. }
  522. let number_of_swaps = nbytes / 2;
  523. let mut offset = 0;
  524. for i in 0..number_of_swaps {
  525. unsafe {
  526. src.offset(offset).copy_to(dest.offset(offset + 1), 1);
  527. src.offset(offset + 1).copy_to(dest.offset(offset), 1);
  528. }
  529. offset += 2;
  530. }
  531. }
  532. #[no_mangle]
  533. pub unsafe extern "C" fn symlink(path1: *const c_char, path2: *const c_char) -> c_int {
  534. let path1 = CStr::from_ptr(path1);
  535. let path2 = CStr::from_ptr(path2);
  536. Sys::symlink(path1, path2)
  537. }
  538. // #[no_mangle]
  539. pub extern "C" fn sync() {
  540. unimplemented!();
  541. }
  542. #[no_mangle]
  543. pub extern "C" fn tcgetpgrp(fd: c_int) -> pid_t {
  544. let mut pgrp = 0;
  545. if unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCGPGRP, &mut pgrp as *mut pid_t as _) } < 0 {
  546. return -1;
  547. }
  548. pgrp
  549. }
  550. #[no_mangle]
  551. pub extern "C" fn tcsetpgrp(fd: c_int, pgrp: pid_t) -> c_int {
  552. if unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCSPGRP, &pgrp as *const pid_t as _) } < 0 {
  553. return -1;
  554. }
  555. pgrp
  556. }
  557. // #[no_mangle]
  558. pub extern "C" fn truncate(path: *const c_char, length: off_t) -> c_int {
  559. unimplemented!();
  560. }
  561. #[no_mangle]
  562. pub unsafe extern "C" fn ttyname(fildes: c_int) -> *mut c_char {
  563. static mut TTYNAME: [c_char; 4096] = [0; 4096];
  564. if ttyname_r(fildes, TTYNAME.as_mut_ptr(), TTYNAME.len()) == 0 {
  565. TTYNAME.as_mut_ptr()
  566. } else {
  567. ptr::null_mut()
  568. }
  569. }
  570. #[no_mangle]
  571. pub extern "C" fn ttyname_r(fildes: c_int, name: *mut c_char, namesize: size_t) -> c_int {
  572. let name = unsafe { slice::from_raw_parts_mut(name as *mut u8, namesize) };
  573. if name.is_empty() {
  574. return errno::ERANGE;
  575. }
  576. let len = Sys::fpath(fildes, &mut name[..namesize - 1]);
  577. if len < 0 {
  578. return unsafe { -platform::errno };
  579. }
  580. name[len as usize] = 0;
  581. 0
  582. }
  583. #[no_mangle]
  584. pub extern "C" fn ualarm(usecs: useconds_t, interval: useconds_t) -> useconds_t {
  585. let mut timer = sys_time::itimerval {
  586. it_value: sys_time::timeval {
  587. tv_sec: 0,
  588. tv_usec: usecs as suseconds_t,
  589. },
  590. it_interval: sys_time::timeval {
  591. tv_sec: 0,
  592. tv_usec: interval as suseconds_t,
  593. },
  594. };
  595. let errno_backup = unsafe { platform::errno };
  596. let ret = if sys_time::setitimer(sys_time::ITIMER_REAL, &timer, &mut timer) < 0 {
  597. 0
  598. } else {
  599. timer.it_value.tv_sec as useconds_t * 1_000_000 + timer.it_value.tv_usec as useconds_t
  600. };
  601. unsafe {
  602. platform::errno = errno_backup;
  603. }
  604. ret
  605. }
  606. #[no_mangle]
  607. pub unsafe extern "C" fn unlink(path: *const c_char) -> c_int {
  608. let path = CStr::from_ptr(path);
  609. Sys::unlink(path)
  610. }
  611. #[no_mangle]
  612. pub extern "C" fn usleep(useconds: useconds_t) -> c_int {
  613. let rqtp = timespec {
  614. tv_sec: (useconds / 1_000_000) as i64,
  615. tv_nsec: ((useconds % 1_000_000) * 1000) as i64,
  616. };
  617. let rmtp = ptr::null_mut();
  618. Sys::nanosleep(&rqtp, rmtp)
  619. }
  620. // #[no_mangle]
  621. pub extern "C" fn vfork() -> pid_t {
  622. unimplemented!();
  623. }
  624. #[no_mangle]
  625. pub extern "C" fn write(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t {
  626. let buf = unsafe { slice::from_raw_parts(buf as *const u8, nbyte as usize) };
  627. Sys::write(fildes, buf)
  628. }