2
0

mod.rs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. //! unistd implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/unistd.h.html
  2. use core::{ptr, slice};
  3. use c_str::CStr;
  4. use header::errno;
  5. use header::limits;
  6. use header::stdlib::getenv;
  7. use header::time::timespec;
  8. use platform;
  9. use platform::types::*;
  10. use platform::{Pal, Sys};
  11. pub use self::brk::*;
  12. pub use self::getopt::*;
  13. pub use self::pathconf::*;
  14. mod brk;
  15. mod getopt;
  16. mod pathconf;
  17. pub const F_OK: c_int = 0;
  18. pub const R_OK: c_int = 4;
  19. pub const W_OK: c_int = 2;
  20. pub const X_OK: c_int = 1;
  21. pub const SEEK_SET: c_int = 0;
  22. pub const SEEK_CUR: c_int = 1;
  23. pub const SEEK_END: c_int = 2;
  24. pub const F_ULOCK: c_int = 0;
  25. pub const F_LOCK: c_int = 1;
  26. pub const F_TLOCK: c_int = 2;
  27. pub const F_TEST: c_int = 3;
  28. pub const STDIN_FILENO: c_int = 0;
  29. pub const STDOUT_FILENO: c_int = 1;
  30. pub const STDERR_FILENO: c_int = 2;
  31. #[no_mangle]
  32. pub extern "C" fn _exit(status: c_int) {
  33. Sys::exit(status)
  34. }
  35. #[no_mangle]
  36. pub extern "C" fn access(path: *const c_char, mode: c_int) -> c_int {
  37. let path = unsafe { CStr::from_ptr(path) };
  38. Sys::access(path, mode)
  39. }
  40. #[no_mangle]
  41. pub extern "C" fn alarm(seconds: c_uint) -> c_uint {
  42. // let mut timer = sys_time::itimerval {
  43. // it_value: sys_time::timeval {
  44. // tv_sec: seconds as time_t,
  45. // tv_usec: 0,
  46. // },
  47. // ..Default::default()
  48. // };
  49. // let errno_backup = unsafe { platform::errno };
  50. // let secs = if sys_time::setitimer(sys_time::ITIMER_REAL, &timer, &mut timer) < 0 {
  51. // 0
  52. // } else {
  53. // timer.it_value.tv_sec as c_uint + if timer.it_value.tv_usec > 0 { 1 } else { 0 }
  54. // };
  55. // unsafe {
  56. // platform::errno = errno_backup;
  57. // }
  58. //
  59. // secs
  60. 0
  61. }
  62. #[no_mangle]
  63. pub extern "C" fn chdir(path: *const c_char) -> c_int {
  64. let path = unsafe { CStr::from_ptr(path) };
  65. Sys::chdir(path)
  66. }
  67. // #[no_mangle]
  68. pub extern "C" fn chroot(path: *const c_char) -> c_int {
  69. unimplemented!();
  70. }
  71. #[no_mangle]
  72. pub extern "C" fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
  73. let path = unsafe { CStr::from_ptr(path) };
  74. Sys::chown(path, owner, group)
  75. }
  76. #[no_mangle]
  77. pub extern "C" fn close(fildes: c_int) -> c_int {
  78. Sys::close(fildes)
  79. }
  80. // #[no_mangle]
  81. pub extern "C" fn confstr(name: c_int, buf: *mut c_char, len: size_t) -> size_t {
  82. unimplemented!();
  83. }
  84. // #[no_mangle]
  85. pub extern "C" fn crypt(key: *const c_char, salt: *const c_char) -> *mut c_char {
  86. unimplemented!();
  87. }
  88. #[no_mangle]
  89. pub extern "C" fn dup(fildes: c_int) -> c_int {
  90. Sys::dup(fildes)
  91. }
  92. #[no_mangle]
  93. pub extern "C" fn dup2(fildes: c_int, fildes2: c_int) -> c_int {
  94. Sys::dup2(fildes, fildes2)
  95. }
  96. // #[no_mangle]
  97. pub extern "C" fn encrypt(block: [c_char; 64], edflag: c_int) {
  98. unimplemented!();
  99. }
  100. // #[no_mangle]
  101. // pub extern "C" fn execl(path: *const c_char, args: *const *mut c_char) -> c_int {
  102. // unimplemented!();
  103. // }
  104. // #[no_mangle]
  105. // pub extern "C" fn execle(
  106. // path: *const c_char,
  107. // args: *const *mut c_char,
  108. // envp: *const *mut c_char,
  109. // ) -> c_int {
  110. // unimplemented!();
  111. // }
  112. // #[no_mangle]
  113. // pub extern "C" fn execlp(file: *const c_char, args: *const *mut c_char) -> c_int {
  114. // unimplemented!();
  115. // }
  116. #[no_mangle]
  117. pub unsafe extern "C" fn execv(path: *const c_char, argv: *const *mut c_char) -> c_int {
  118. execve(path, argv, platform::environ)
  119. }
  120. #[no_mangle]
  121. pub unsafe extern "C" fn execve(
  122. path: *const c_char,
  123. argv: *const *mut c_char,
  124. envp: *const *mut c_char,
  125. ) -> c_int {
  126. let path = CStr::from_ptr(path);
  127. Sys::execve(path, argv, envp)
  128. }
  129. #[cfg(target_os = "linux")]
  130. const PATH_SEPARATOR: u8 = b':';
  131. #[cfg(target_os = "redox")]
  132. const PATH_SEPARATOR: u8 = b';';
  133. #[no_mangle]
  134. pub unsafe extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) -> c_int {
  135. let file = CStr::from_ptr(file);
  136. if file.to_bytes().contains(&b'/')
  137. || (cfg!(target_os = "redox") && file.to_bytes().contains(&b':'))
  138. {
  139. execv(file.as_ptr(), argv)
  140. } else {
  141. let mut error = errno::ENOENT;
  142. let path_env = getenv(c_str!("PATH\0").as_ptr());
  143. if !path_env.is_null() {
  144. let path_env = CStr::from_ptr(path_env);
  145. for mut path in path_env.to_bytes().split(|&b| b == PATH_SEPARATOR) {
  146. let mut program = path.to_vec();
  147. program.push(b'/');
  148. program.extend_from_slice(file.to_bytes());
  149. program.push(b'\0');
  150. let program_c = CStr::from_bytes_with_nul(&program).unwrap();
  151. execv(program_c.as_ptr(), argv);
  152. match platform::errno {
  153. errno::ENOENT => (),
  154. other => error = other,
  155. }
  156. }
  157. }
  158. platform::errno = error;
  159. -1
  160. }
  161. }
  162. #[no_mangle]
  163. pub extern "C" fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int {
  164. Sys::fchown(fildes, owner, group)
  165. }
  166. #[no_mangle]
  167. pub extern "C" fn fchdir(fildes: c_int) -> c_int {
  168. Sys::fchdir(fildes)
  169. }
  170. // #[no_mangle]
  171. pub extern "C" fn fdatasync(fildes: c_int) -> c_int {
  172. unimplemented!();
  173. }
  174. #[no_mangle]
  175. pub extern "C" fn fork() -> pid_t {
  176. Sys::fork()
  177. }
  178. #[no_mangle]
  179. pub extern "C" fn fsync(fildes: c_int) -> c_int {
  180. Sys::fsync(fildes)
  181. }
  182. #[no_mangle]
  183. pub extern "C" fn ftruncate(fildes: c_int, length: off_t) -> c_int {
  184. Sys::ftruncate(fildes, length)
  185. }
  186. #[no_mangle]
  187. pub extern "C" fn getcwd(mut buf: *mut c_char, mut size: size_t) -> *mut c_char {
  188. let alloc = buf.is_null();
  189. let mut stack_buf = [0; limits::PATH_MAX];
  190. if alloc {
  191. buf = stack_buf.as_mut_ptr();
  192. size = stack_buf.len();
  193. }
  194. let ret = Sys::getcwd(buf, size);
  195. if ret == ptr::null_mut() {
  196. return ptr::null_mut();
  197. }
  198. if alloc {
  199. let len = stack_buf
  200. .iter()
  201. .position(|b| *b == 0)
  202. .expect("no nul-byte in getcwd string")
  203. + 1;
  204. let heap_buf = unsafe { platform::alloc(len) as *mut c_char };
  205. for i in 0..len {
  206. unsafe {
  207. *heap_buf.offset(i as isize) = stack_buf[i];
  208. }
  209. }
  210. heap_buf
  211. } else {
  212. ret
  213. }
  214. }
  215. // #[no_mangle]
  216. pub extern "C" fn getdtablesize() -> c_int {
  217. unimplemented!();
  218. }
  219. #[no_mangle]
  220. pub extern "C" fn getegid() -> gid_t {
  221. Sys::getegid()
  222. }
  223. #[no_mangle]
  224. pub extern "C" fn geteuid() -> uid_t {
  225. Sys::geteuid()
  226. }
  227. #[no_mangle]
  228. pub extern "C" fn getgid() -> gid_t {
  229. Sys::getgid()
  230. }
  231. // #[no_mangle]
  232. pub extern "C" fn getgroups(gidsetsize: c_int, grouplist: *mut gid_t) -> c_int {
  233. unimplemented!();
  234. }
  235. // #[no_mangle]
  236. pub extern "C" fn gethostid() -> c_long {
  237. unimplemented!();
  238. }
  239. #[no_mangle]
  240. pub unsafe extern "C" fn gethostname(name: *mut c_char, len: size_t) -> c_int {
  241. Sys::gethostname(name, len)
  242. }
  243. // #[no_mangle]
  244. pub extern "C" fn getlogin() -> *mut c_char {
  245. unimplemented!();
  246. }
  247. // #[no_mangle]
  248. pub extern "C" fn getlogin_r(name: *mut c_char, namesize: size_t) -> c_int {
  249. unimplemented!();
  250. }
  251. // #[no_mangle]
  252. pub extern "C" fn getpagesize() -> c_int {
  253. unimplemented!();
  254. }
  255. // #[no_mangle]
  256. pub extern "C" fn getpass(prompt: *const c_char) -> *mut c_char {
  257. unimplemented!();
  258. }
  259. #[no_mangle]
  260. pub extern "C" fn getpgid(pid: pid_t) -> pid_t {
  261. Sys::getpgid(pid)
  262. }
  263. #[no_mangle]
  264. pub extern "C" fn getpgrp() -> pid_t {
  265. Sys::getpgid(Sys::getpid())
  266. }
  267. #[no_mangle]
  268. pub extern "C" fn getpid() -> pid_t {
  269. Sys::getpid()
  270. }
  271. #[no_mangle]
  272. pub extern "C" fn getppid() -> pid_t {
  273. Sys::getppid()
  274. }
  275. // #[no_mangle]
  276. pub extern "C" fn getsid(pid: pid_t) -> pid_t {
  277. unimplemented!();
  278. }
  279. #[no_mangle]
  280. pub extern "C" fn getuid() -> uid_t {
  281. Sys::getuid()
  282. }
  283. #[no_mangle]
  284. pub extern "C" fn getwd(path_name: *mut c_char) -> *mut c_char {
  285. getcwd(path_name, limits::PATH_MAX)
  286. }
  287. #[no_mangle]
  288. pub extern "C" fn isatty(fd: c_int) -> c_int {
  289. Sys::isatty(fd)
  290. }
  291. // #[no_mangle]
  292. pub extern "C" fn lchown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
  293. unimplemented!();
  294. }
  295. #[no_mangle]
  296. pub extern "C" fn link(path1: *const c_char, path2: *const c_char) -> c_int {
  297. let path1 = unsafe { CStr::from_ptr(path1) };
  298. let path2 = unsafe { CStr::from_ptr(path2) };
  299. Sys::link(path1, path2)
  300. }
  301. // #[no_mangle]
  302. pub extern "C" fn lockf(fildes: c_int, function: c_int, size: off_t) -> c_int {
  303. unimplemented!();
  304. }
  305. #[no_mangle]
  306. pub extern "C" fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> off_t {
  307. Sys::lseek(fildes, offset, whence)
  308. }
  309. // #[no_mangle]
  310. pub extern "C" fn nice(incr: c_int) -> c_int {
  311. unimplemented!();
  312. }
  313. // #[no_mangle]
  314. pub extern "C" fn pause() -> c_int {
  315. unimplemented!();
  316. }
  317. #[no_mangle]
  318. pub unsafe extern "C" fn pipe(fildes: *mut c_int) -> c_int {
  319. Sys::pipe(slice::from_raw_parts_mut(fildes, 2))
  320. }
  321. #[no_mangle]
  322. pub extern "C" fn pread(fildes: c_int, buf: *mut c_void, nbyte: size_t, offset: off_t) -> ssize_t {
  323. //TODO: better pread using system calls
  324. let previous = lseek(fildes, offset, SEEK_SET);
  325. if previous == -1 {
  326. return -1;
  327. }
  328. let res = read(fildes, buf, nbyte);
  329. if res < 0 {
  330. return res;
  331. }
  332. if lseek(fildes, previous, SEEK_SET) == -1 {
  333. return -1;
  334. }
  335. res
  336. }
  337. // #[no_mangle]
  338. pub extern "C" fn pthread_atfork(
  339. prepare: Option<extern "C" fn()>,
  340. parent: Option<extern "C" fn()>,
  341. child: Option<extern "C" fn()>,
  342. ) -> c_int {
  343. unimplemented!();
  344. }
  345. #[no_mangle]
  346. pub extern "C" fn pwrite(
  347. fildes: c_int,
  348. buf: *const c_void,
  349. nbyte: size_t,
  350. offset: off_t,
  351. ) -> ssize_t {
  352. //TODO: better pwrite using system calls
  353. let previous = lseek(fildes, offset, SEEK_SET);
  354. if previous == -1 {
  355. return -1;
  356. }
  357. let res = write(fildes, buf, nbyte);
  358. if res < 0 {
  359. return res;
  360. }
  361. if lseek(fildes, previous, SEEK_SET) == -1 {
  362. return -1;
  363. }
  364. res
  365. }
  366. #[no_mangle]
  367. pub extern "C" fn read(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t {
  368. use core::slice;
  369. let buf = unsafe { slice::from_raw_parts_mut(buf as *mut u8, nbyte as usize) };
  370. trace_expr!(
  371. Sys::read(fildes, buf),
  372. "read({}, {:p}, {})",
  373. fildes,
  374. buf,
  375. nbyte
  376. )
  377. }
  378. // #[no_mangle]
  379. pub extern "C" fn readlink(path: *const c_char, buf: *mut c_char, bufsize: size_t) -> c_int {
  380. unimplemented!();
  381. }
  382. #[no_mangle]
  383. pub extern "C" fn rmdir(path: *const c_char) -> c_int {
  384. let path = unsafe { CStr::from_ptr(path) };
  385. Sys::rmdir(path)
  386. }
  387. #[no_mangle]
  388. pub extern "C" fn setgid(gid: gid_t) -> c_int {
  389. Sys::setregid(gid, gid)
  390. }
  391. #[no_mangle]
  392. pub extern "C" fn setpgid(pid: pid_t, pgid: pid_t) -> c_int {
  393. Sys::setpgid(pid, pgid)
  394. }
  395. // #[no_mangle]
  396. pub extern "C" fn setpgrp() -> pid_t {
  397. unimplemented!();
  398. }
  399. #[no_mangle]
  400. pub extern "C" fn setregid(rgid: gid_t, egid: gid_t) -> c_int {
  401. Sys::setregid(rgid, egid)
  402. }
  403. #[no_mangle]
  404. pub extern "C" fn setreuid(ruid: uid_t, euid: uid_t) -> c_int {
  405. Sys::setreuid(ruid, euid)
  406. }
  407. // #[no_mangle]
  408. pub extern "C" fn setsid() -> pid_t {
  409. unimplemented!();
  410. }
  411. #[no_mangle]
  412. pub extern "C" fn setuid(uid: uid_t) -> c_int {
  413. Sys::setreuid(uid, uid)
  414. }
  415. #[no_mangle]
  416. pub extern "C" fn sleep(seconds: c_uint) -> c_uint {
  417. let rqtp = timespec {
  418. tv_sec: seconds as i64,
  419. tv_nsec: 0,
  420. };
  421. let rmtp = ptr::null_mut();
  422. Sys::nanosleep(&rqtp, rmtp);
  423. 0
  424. }
  425. // #[no_mangle]
  426. pub extern "C" fn swab(src: *const c_void, dest: *mut c_void, nbytes: ssize_t) {
  427. unimplemented!();
  428. }
  429. // #[no_mangle]
  430. pub extern "C" fn symlink(path1: *const c_char, path2: *const c_char) -> c_int {
  431. unimplemented!();
  432. }
  433. // #[no_mangle]
  434. pub extern "C" fn sync() {
  435. unimplemented!();
  436. }
  437. // #[no_mangle]
  438. pub extern "C" fn sysconf(name: c_int) -> c_long {
  439. unimplemented!();
  440. }
  441. // #[no_mangle]
  442. pub extern "C" fn tcgetpgrp() -> pid_t {
  443. unimplemented!();
  444. }
  445. // #[no_mangle]
  446. pub extern "C" fn tcsetpgrp(fildes: c_int, pgid_id: pid_t) -> c_int {
  447. unimplemented!();
  448. }
  449. // #[no_mangle]
  450. pub extern "C" fn truncate(path: *const c_char, length: off_t) -> c_int {
  451. unimplemented!();
  452. }
  453. // #[no_mangle]
  454. pub extern "C" fn ttyname(fildes: c_int) -> *mut c_char {
  455. unimplemented!();
  456. }
  457. // #[no_mangle]
  458. pub extern "C" fn ttyname_r(fildes: c_int, name: *mut c_char, namesize: size_t) -> c_int {
  459. unimplemented!();
  460. }
  461. // #[no_mangle]
  462. // pub extern "C" fn ualarm(value: useconds_t, interval: useconds_t) -> useconds_t {
  463. // let mut timer = sys_time::itimerval {
  464. // it_value: sys_time::timeval {
  465. // tv_sec: 0,
  466. // tv_usec: value as suseconds_t,
  467. // },
  468. // it_interval: sys_time::timeval {
  469. // tv_sec: 0,
  470. // tv_usec: interval as suseconds_t,
  471. // },
  472. // };
  473. // let errno_backup = unsafe { platform::errno };
  474. // let usecs = if sys_time::setitimer(sys_time::ITIMER_REAL, &timer, &mut timer) < 0 {
  475. // 0
  476. // } else {
  477. // timer.it_value.tv_sec as useconds_t * 1_000_000 + timer.it_value.tv_usec as useconds_t
  478. // };
  479. // unsafe {
  480. // platform::errno = errno_backup;
  481. // }
  482. //
  483. // usecs
  484. // }
  485. #[no_mangle]
  486. pub extern "C" fn unlink(path: *const c_char) -> c_int {
  487. let path = unsafe { CStr::from_ptr(path) };
  488. Sys::unlink(path)
  489. }
  490. #[no_mangle]
  491. pub extern "C" fn usleep(useconds: useconds_t) -> c_int {
  492. let rqtp = timespec {
  493. tv_sec: (useconds / 1_000_000) as i64,
  494. tv_nsec: ((useconds % 1000) * 1000) as i64,
  495. };
  496. let rmtp = ptr::null_mut();
  497. Sys::nanosleep(&rqtp, rmtp)
  498. }
  499. // #[no_mangle]
  500. pub extern "C" fn vfork() -> pid_t {
  501. unimplemented!();
  502. }
  503. #[no_mangle]
  504. pub extern "C" fn write(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t {
  505. use core::slice;
  506. let buf = unsafe { slice::from_raw_parts(buf as *const u8, nbyte as usize) };
  507. Sys::write(fildes, buf)
  508. }
  509. /*
  510. #[no_mangle]
  511. pub extern "C" fn func(args) -> c_int {
  512. unimplemented!();
  513. }
  514. */