mod.rs 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150
  1. //! sys/socket implementation, following http://pubs.opengroup.org/onlinepubs/009696699/basedefs/sys/socket.h.html
  2. use alloc::collections::BTreeMap;
  3. use cbitset::BitSet;
  4. use core::result::Result as CoreResult;
  5. use core::{mem, ptr, slice};
  6. use spin::{Mutex, MutexGuard, Once};
  7. use syscall::data::Stat as redox_stat;
  8. use syscall::data::TimeSpec as redox_timespec;
  9. use syscall::{self, Result};
  10. use c_str::{CStr, CString};
  11. use fs::File;
  12. use header::dirent::dirent;
  13. use header::errno::{EINVAL, EIO, EPERM};
  14. use header::fcntl;
  15. use header::poll::{self, nfds_t, pollfd};
  16. use header::sys_select::fd_set;
  17. use header::sys_stat::stat;
  18. use header::sys_time::{timeval, timezone};
  19. use header::sys_utsname::{utsname, UTSLENGTH};
  20. use header::termios::termios;
  21. use header::time::timespec;
  22. use header::unistd::{F_OK, R_OK, W_OK, X_OK};
  23. use io::prelude::*;
  24. use io::{self, BufReader, SeekFrom};
  25. use super::types::*;
  26. use super::{errno, Pal, Read};
  27. mod signal;
  28. mod socket;
  29. const MAP_ANON: c_int = 1;
  30. static ANONYMOUS_MAPS: Once<Mutex<BTreeMap<usize, usize>>> = Once::new();
  31. fn anonymous_maps() -> MutexGuard<'static, BTreeMap<usize, usize>> {
  32. ANONYMOUS_MAPS
  33. .call_once(|| Mutex::new(BTreeMap::new()))
  34. .lock()
  35. }
  36. fn e(sys: Result<usize>) -> usize {
  37. match sys {
  38. Ok(ok) => ok,
  39. Err(err) => {
  40. unsafe {
  41. errno = err.errno as c_int;
  42. }
  43. !0
  44. }
  45. }
  46. }
  47. pub struct Sys;
  48. impl Pal for Sys {
  49. fn access(path: &CStr, mode: c_int) -> c_int {
  50. let fd = match File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC) {
  51. Ok(fd) => fd,
  52. Err(_) => return -1,
  53. };
  54. if mode == F_OK {
  55. return 0;
  56. }
  57. let mut stat = syscall::Stat::default();
  58. if e(syscall::fstat(*fd as usize, &mut stat)) == !0 {
  59. return -1;
  60. }
  61. let uid = e(syscall::getuid());
  62. if uid == !0 {
  63. return -1;
  64. }
  65. let gid = e(syscall::getgid());
  66. if gid == !0 {
  67. return -1;
  68. }
  69. let perms = if stat.st_uid as usize == uid {
  70. stat.st_mode >> (3 * 2 & 0o7)
  71. } else if stat.st_gid as usize == gid {
  72. stat.st_mode >> (3 * 1 & 0o7)
  73. } else {
  74. stat.st_mode & 0o7
  75. };
  76. if (mode & R_OK == R_OK && perms & 0o4 != 0o4)
  77. || (mode & W_OK == W_OK && perms & 0o2 != 0o2)
  78. || (mode & X_OK == X_OK && perms & 0o1 != 0o1)
  79. {
  80. unsafe {
  81. errno = EINVAL;
  82. }
  83. return -1;
  84. }
  85. 0
  86. }
  87. fn brk(addr: *mut c_void) -> *mut c_void {
  88. unsafe { syscall::brk(addr as usize).unwrap_or(0) as *mut c_void }
  89. }
  90. fn chdir(path: &CStr) -> c_int {
  91. e(syscall::chdir(path.to_bytes())) as c_int
  92. }
  93. fn chmod(path: &CStr, mode: mode_t) -> c_int {
  94. match File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC) {
  95. Ok(file) => Self::fchmod(*file, mode),
  96. Err(_) => -1,
  97. }
  98. }
  99. fn chown(path: &CStr, owner: uid_t, group: gid_t) -> c_int {
  100. match File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC) {
  101. Ok(file) => Self::fchown(*file, owner, group),
  102. Err(_) => -1,
  103. }
  104. }
  105. fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int {
  106. let mut redox_tp = unsafe { redox_timespec::from(&*tp) };
  107. match e(syscall::clock_gettime(clk_id as usize, &mut redox_tp)) as c_int {
  108. -1 => -1,
  109. _ => {
  110. unsafe {
  111. (*tp).tv_sec = redox_tp.tv_sec;
  112. (*tp).tv_nsec = redox_tp.tv_nsec as i64;
  113. };
  114. 0
  115. }
  116. }
  117. }
  118. fn close(fd: c_int) -> c_int {
  119. e(syscall::close(fd as usize)) as c_int
  120. }
  121. fn dup(fd: c_int) -> c_int {
  122. e(syscall::dup(fd as usize, &[])) as c_int
  123. }
  124. fn dup2(fd1: c_int, fd2: c_int) -> c_int {
  125. e(syscall::dup2(fd1 as usize, fd2 as usize, &[])) as c_int
  126. }
  127. fn exit(status: c_int) -> ! {
  128. let _ = syscall::exit(status as usize);
  129. loop {}
  130. }
  131. unsafe fn execve(
  132. path: &CStr,
  133. mut argv: *const *mut c_char,
  134. mut envp: *const *mut c_char,
  135. ) -> c_int {
  136. use alloc::vec::Vec;
  137. let mut file = match File::open(path, fcntl::O_RDONLY | fcntl::O_CLOEXEC) {
  138. Ok(file) => file,
  139. Err(_) => return -1,
  140. };
  141. let fd = *file as usize;
  142. // Count arguments
  143. let mut len = 0;
  144. while !(*argv.offset(len)).is_null() {
  145. len += 1;
  146. }
  147. let mut args: Vec<[usize; 2]> = Vec::with_capacity(len as usize);
  148. // Read shebang (for example #!/bin/sh)
  149. let interpreter = {
  150. let mut reader = BufReader::new(&mut file);
  151. let mut shebang = [0; 2];
  152. let mut read = 0;
  153. while read < 2 {
  154. match reader.read(&mut shebang) {
  155. Ok(0) => break,
  156. Ok(i) => read += i,
  157. Err(_) => return -1,
  158. }
  159. }
  160. if &shebang == b"#!" {
  161. // So, this file is interpreted.
  162. // That means the actual file descriptor passed to `fexec` won't be this file.
  163. // So we need to check ourselves that this file is actually be executable.
  164. let mut stat = redox_stat::default();
  165. if e(syscall::fstat(fd, &mut stat)) == !0 {
  166. return -1;
  167. }
  168. let uid = e(syscall::getuid());
  169. if uid == !0 {
  170. return -1;
  171. }
  172. let gid = e(syscall::getuid());
  173. if gid == !0 {
  174. return -1;
  175. }
  176. let mode = if uid == stat.st_uid as usize {
  177. (stat.st_mode >> 3 * 2) & 0o7
  178. } else if gid == stat.st_gid as usize {
  179. (stat.st_mode >> 3 * 1) & 0o7
  180. } else {
  181. stat.st_mode & 0o7
  182. };
  183. if mode & 0o1 == 0o0 {
  184. errno = EPERM;
  185. return -1;
  186. }
  187. // Then, read the actual interpreter:
  188. let mut interpreter = Vec::new();
  189. match reader.read_until(b'\n', &mut interpreter) {
  190. Err(_) => return -1,
  191. Ok(_) => {
  192. if interpreter.ends_with(&[b'\n']) {
  193. interpreter.pop().unwrap();
  194. }
  195. // TODO: Returning the interpreter here is actually a
  196. // hack. Preferrably we should reassign `file =`
  197. // directly from here. Just wait until NLL comes
  198. // around...
  199. Some(interpreter)
  200. }
  201. }
  202. } else {
  203. None
  204. }
  205. };
  206. let mut _interpreter_path = None;
  207. if let Some(interpreter) = interpreter {
  208. let mut cstring = match CString::new(interpreter) {
  209. Ok(cstring) => cstring,
  210. Err(_) => return -1,
  211. };
  212. file = match File::open(&cstring, fcntl::O_RDONLY | fcntl::O_CLOEXEC) {
  213. Ok(file) => file,
  214. Err(_) => return -1,
  215. };
  216. // Make sure path is kept alive long enough, and push it to the arguments
  217. _interpreter_path = Some(cstring);
  218. let path_ref = _interpreter_path.as_ref().unwrap();
  219. args.push([path_ref.as_ptr() as usize, path_ref.to_bytes().len()]);
  220. } else {
  221. if file.seek(SeekFrom::Start(0)).is_err() {
  222. return -1;
  223. }
  224. }
  225. // Arguments
  226. while !(*argv).is_null() {
  227. let arg = *argv;
  228. let mut len = 0;
  229. while *arg.offset(len) != 0 {
  230. len += 1;
  231. }
  232. args.push([arg as usize, len as usize]);
  233. argv = argv.offset(1);
  234. }
  235. // Environment variables
  236. let mut len = 0;
  237. while !(*envp.offset(len)).is_null() {
  238. len += 1;
  239. }
  240. let mut envs: Vec<[usize; 2]> = Vec::with_capacity(len as usize);
  241. while !(*envp).is_null() {
  242. let env = *envp;
  243. let mut len = 0;
  244. while *env.offset(len) != 0 {
  245. len += 1;
  246. }
  247. envs.push([env as usize, len as usize]);
  248. envp = envp.offset(1);
  249. }
  250. e(syscall::fexec(*file as usize, &args, &envs)) as c_int
  251. }
  252. fn fchdir(fd: c_int) -> c_int {
  253. let path: &mut [u8] = &mut [0; 4096];
  254. if e(syscall::fpath(fd as usize, path)) == !0 {
  255. !0
  256. } else {
  257. e(syscall::chdir(path)) as c_int
  258. }
  259. }
  260. fn fchmod(fd: c_int, mode: mode_t) -> c_int {
  261. e(syscall::fchmod(fd as usize, mode as u16)) as c_int
  262. }
  263. fn fchown(fd: c_int, owner: uid_t, group: gid_t) -> c_int {
  264. e(syscall::fchown(fd as usize, owner as u32, group as u32)) as c_int
  265. }
  266. fn fcntl(fd: c_int, cmd: c_int, args: c_int) -> c_int {
  267. e(syscall::fcntl(fd as usize, cmd as usize, args as usize)) as c_int
  268. }
  269. fn flock(_fd: c_int, _operation: c_int) -> c_int {
  270. // TODO: Redox does not have file locking yet
  271. 0
  272. }
  273. fn fork() -> pid_t {
  274. e(unsafe { syscall::clone(0) }) as pid_t
  275. }
  276. fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
  277. let mut redox_buf: redox_stat = redox_stat::default();
  278. match e(syscall::fstat(fildes as usize, &mut redox_buf)) {
  279. 0 => {
  280. unsafe {
  281. if !buf.is_null() {
  282. (*buf).st_dev = redox_buf.st_dev as dev_t;
  283. (*buf).st_ino = redox_buf.st_ino as ino_t;
  284. (*buf).st_nlink = redox_buf.st_nlink as nlink_t;
  285. (*buf).st_mode = redox_buf.st_mode as mode_t;
  286. (*buf).st_uid = redox_buf.st_uid as uid_t;
  287. (*buf).st_gid = redox_buf.st_gid as gid_t;
  288. // TODO st_rdev
  289. (*buf).st_rdev = 0;
  290. (*buf).st_size = redox_buf.st_size as off_t;
  291. (*buf).st_blksize = redox_buf.st_blksize as blksize_t;
  292. (*buf).st_atim = timespec {
  293. tv_sec: redox_buf.st_atime as time_t,
  294. tv_nsec: redox_buf.st_atime_nsec as c_long,
  295. };
  296. (*buf).st_mtim = timespec {
  297. tv_sec: redox_buf.st_mtime as time_t,
  298. tv_nsec: redox_buf.st_mtime_nsec as c_long,
  299. };
  300. (*buf).st_ctim = timespec {
  301. tv_sec: redox_buf.st_ctime as time_t,
  302. tv_nsec: redox_buf.st_ctime_nsec as c_long,
  303. };
  304. }
  305. }
  306. 0
  307. }
  308. _ => -1,
  309. }
  310. }
  311. fn fsync(fd: c_int) -> c_int {
  312. e(syscall::fsync(fd as usize)) as c_int
  313. }
  314. fn ftruncate(fd: c_int, len: off_t) -> c_int {
  315. e(syscall::ftruncate(fd as usize, len as usize)) as c_int
  316. }
  317. fn futex(addr: *mut c_int, op: c_int, val: c_int) -> c_int {
  318. match unsafe {
  319. syscall::futex(
  320. addr as *mut i32,
  321. op as usize,
  322. val as i32,
  323. 0,
  324. ptr::null_mut(),
  325. )
  326. } {
  327. Ok(success) => success as c_int,
  328. Err(err) => -(err.errno as c_int),
  329. }
  330. }
  331. fn futimens(fd: c_int, times: *const timespec) -> c_int {
  332. let times = [unsafe { redox_timespec::from(&*times) }, unsafe {
  333. redox_timespec::from(&*times.offset(1))
  334. }];
  335. e(syscall::futimens(fd as usize, &times)) as c_int
  336. }
  337. fn utimens(path: &CStr, times: *const timespec) -> c_int {
  338. match File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC) {
  339. Ok(file) => Self::futimens(*file, times),
  340. Err(_) => -1,
  341. }
  342. }
  343. fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
  344. let buf_slice = unsafe { slice::from_raw_parts_mut(buf as *mut u8, size as usize - 1) };
  345. let read = e(syscall::getcwd(buf_slice));
  346. if read == !0 {
  347. ptr::null_mut()
  348. } else {
  349. unsafe {
  350. *buf.offset(read as isize + 1) = 0;
  351. }
  352. buf
  353. }
  354. }
  355. fn getdents(fd: c_int, mut dirents: *mut dirent, max_bytes: usize) -> c_int {
  356. // Get initial reading position
  357. let mut read = match syscall::lseek(fd as usize, 0, syscall::SEEK_CUR) {
  358. Ok(pos) => pos as isize,
  359. Err(err) => return -err.errno,
  360. };
  361. let mut written = 0;
  362. let mut buf = [0; 1024];
  363. let mut name = [0; 256];
  364. let mut i = 0;
  365. let mut flush = |written: &mut usize, i: &mut usize, name: &mut [c_char; 256]| {
  366. if *i < name.len() {
  367. // Set NUL byte
  368. name[*i] = 0;
  369. }
  370. // Get size: full size - unused bytes
  371. let size = mem::size_of::<dirent>() - name.len().saturating_sub(*i + 1);
  372. if *written + size > max_bytes {
  373. // Seek back to after last read entry and return
  374. match syscall::lseek(fd as usize, read, syscall::SEEK_SET) {
  375. Ok(_) => return Some(*written as c_int),
  376. Err(err) => return Some(-err.errno),
  377. }
  378. }
  379. unsafe {
  380. *dirents = dirent {
  381. d_ino: 0,
  382. d_off: read as off_t,
  383. d_reclen: size as c_ushort,
  384. d_type: 0,
  385. d_name: *name,
  386. };
  387. dirents = (dirents as *mut u8).offset(size as isize) as *mut dirent;
  388. }
  389. read += *i as isize + /* newline */ 1;
  390. *written += size;
  391. *i = 0;
  392. None
  393. };
  394. loop {
  395. // Read a chunk from the directory
  396. let len = match syscall::read(fd as usize, &mut buf) {
  397. Ok(0) => {
  398. if i > 0 {
  399. if let Some(value) = flush(&mut written, &mut i, &mut name) {
  400. return value;
  401. }
  402. }
  403. return written as c_int;
  404. }
  405. Ok(n) => n,
  406. Err(err) => return -err.errno,
  407. };
  408. // Handle everything
  409. let mut start = 0;
  410. while start < len {
  411. let buf = &buf[start..len];
  412. // Copy everything up until a newline
  413. let newline = buf.iter().position(|&c| c == b'\n');
  414. let pre_len = newline.unwrap_or(buf.len());
  415. let post_len = newline.map(|i| i + 1).unwrap_or(buf.len());
  416. if i < pre_len {
  417. // Reserve space for NUL byte
  418. let name_len = name.len() - 1;
  419. let name = &mut name[i..name_len];
  420. let copy = pre_len.min(name.len());
  421. let buf = unsafe { slice::from_raw_parts(buf.as_ptr() as *const c_char, copy) };
  422. name[..copy].copy_from_slice(buf);
  423. }
  424. i += pre_len;
  425. start += post_len;
  426. // Write the directory entry
  427. if newline.is_some() {
  428. if let Some(value) = flush(&mut written, &mut i, &mut name) {
  429. return value;
  430. }
  431. }
  432. }
  433. }
  434. }
  435. fn getegid() -> gid_t {
  436. e(syscall::getegid()) as gid_t
  437. }
  438. fn geteuid() -> uid_t {
  439. e(syscall::geteuid()) as uid_t
  440. }
  441. fn getgid() -> gid_t {
  442. e(syscall::getgid()) as gid_t
  443. }
  444. fn getpgid(pid: pid_t) -> pid_t {
  445. e(syscall::getpgid(pid as usize)) as pid_t
  446. }
  447. fn getpid() -> pid_t {
  448. e(syscall::getpid()) as pid_t
  449. }
  450. fn getppid() -> pid_t {
  451. e(syscall::getppid()) as pid_t
  452. }
  453. fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int {
  454. let mut redox_tp = redox_timespec::default();
  455. let err = e(syscall::clock_gettime(
  456. syscall::CLOCK_REALTIME,
  457. &mut redox_tp,
  458. )) as c_int;
  459. if err < 0 {
  460. return err;
  461. }
  462. unsafe {
  463. (*tp).tv_sec = redox_tp.tv_sec as time_t;
  464. (*tp).tv_usec = (redox_tp.tv_nsec / 1000) as suseconds_t;
  465. if !tzp.is_null() {
  466. (*tzp).tz_minuteswest = 0;
  467. (*tzp).tz_dsttime = 0;
  468. }
  469. }
  470. 0
  471. }
  472. fn getuid() -> uid_t {
  473. e(syscall::getuid()) as pid_t
  474. }
  475. fn isatty(fd: c_int) -> c_int {
  476. syscall::dup(fd as usize, b"termios")
  477. .map(|fd| {
  478. let _ = syscall::close(fd);
  479. 1
  480. })
  481. .unwrap_or(0)
  482. }
  483. fn link(path1: &CStr, path2: &CStr) -> c_int {
  484. e(unsafe { syscall::link(path1.as_ptr() as *const u8, path2.as_ptr() as *const u8) })
  485. as c_int
  486. }
  487. fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t {
  488. e(syscall::lseek(
  489. fd as usize,
  490. offset as isize,
  491. whence as usize,
  492. )) as off_t
  493. }
  494. fn mkdir(path: &CStr, mode: mode_t) -> c_int {
  495. match File::create(path, fcntl::O_DIRECTORY | fcntl::O_EXCL | fcntl::O_CLOEXEC, 0o777) {
  496. Ok(_fd) => 0,
  497. Err(_) => -1,
  498. }
  499. }
  500. fn mkfifo(path: &CStr, mode: mode_t) -> c_int {
  501. match File::create(path, fcntl::O_CREAT | fcntl::O_CLOEXEC, syscall::MODE_FIFO as mode_t | (mode & 0o777)) {
  502. Ok(fd) => 0,
  503. Err(_) => -1,
  504. }
  505. }
  506. unsafe fn mmap(
  507. _addr: *mut c_void,
  508. len: usize,
  509. _prot: c_int,
  510. flags: c_int,
  511. fildes: c_int,
  512. off: off_t,
  513. ) -> *mut c_void {
  514. if flags & MAP_ANON == MAP_ANON {
  515. let fd = e(syscall::open("memory:", syscall::O_STAT | syscall::O_CLOEXEC)); // flags don't matter currently
  516. if fd == !0 {
  517. return !0 as *mut c_void;
  518. }
  519. let addr = e(syscall::fmap(fd, off as usize, len as usize));
  520. if addr == !0 {
  521. let _ = syscall::close(fd);
  522. return !0 as *mut c_void;
  523. }
  524. anonymous_maps().insert(addr as usize, fd);
  525. addr as *mut c_void
  526. } else {
  527. e(syscall::fmap(fildes as usize, off as usize, len as usize)) as *mut c_void
  528. }
  529. }
  530. unsafe fn munmap(addr: *mut c_void, _len: usize) -> c_int {
  531. if e(syscall::funmap(addr as usize)) == !0 {
  532. return !0;
  533. }
  534. if let Some(fd) = anonymous_maps().remove(&(addr as usize)) {
  535. let _ = syscall::close(fd);
  536. }
  537. 0
  538. }
  539. fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int {
  540. let redox_rqtp = unsafe { redox_timespec::from(&*rqtp) };
  541. let mut redox_rmtp: redox_timespec;
  542. if rmtp.is_null() {
  543. redox_rmtp = redox_timespec::default();
  544. } else {
  545. redox_rmtp = unsafe { redox_timespec::from(&*rmtp) };
  546. }
  547. match e(syscall::nanosleep(&redox_rqtp, &mut redox_rmtp)) as c_int {
  548. -1 => -1,
  549. _ => {
  550. unsafe {
  551. if !rmtp.is_null() {
  552. (*rmtp).tv_sec = redox_rmtp.tv_sec;
  553. (*rmtp).tv_nsec = redox_rmtp.tv_nsec as i64;
  554. }
  555. }
  556. 0
  557. }
  558. }
  559. }
  560. fn open(path: &CStr, oflag: c_int, mode: mode_t) -> c_int {
  561. e(syscall::open(
  562. path.to_bytes(),
  563. ((oflag as usize) << 16) | ((mode as usize) & 0xFFFF),
  564. )) as c_int
  565. }
  566. fn pipe(fds: &mut [c_int]) -> c_int {
  567. let mut usize_fds: [usize; 2] = [0; 2];
  568. let res = e(syscall::pipe2(&mut usize_fds, 0));
  569. fds[0] = usize_fds[0] as c_int;
  570. fds[1] = usize_fds[1] as c_int;
  571. res as c_int
  572. }
  573. fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) -> c_int {
  574. let fds = unsafe { slice::from_raw_parts_mut(fds, nfds as usize) };
  575. let event_path = c_str!("event:");
  576. let mut event_file = match File::open(event_path, fcntl::O_RDWR | fcntl::O_CLOEXEC) {
  577. Ok(file) => file,
  578. Err(_) => return -1,
  579. };
  580. for fd in fds.iter_mut() {
  581. let mut flags = 0;
  582. if fd.events & poll::POLLIN > 0 {
  583. flags |= syscall::EVENT_READ;
  584. }
  585. if fd.events & poll::POLLOUT > 0 {
  586. flags |= syscall::EVENT_WRITE;
  587. }
  588. fd.revents = 0;
  589. if fd.fd >= 0 && flags > 0 {
  590. if event_file
  591. .write(&syscall::Event {
  592. id: fd.fd as usize,
  593. flags: flags,
  594. data: 0,
  595. })
  596. .is_err()
  597. {
  598. return -1;
  599. }
  600. }
  601. }
  602. const TIMEOUT_TOKEN: usize = 1;
  603. let timeout_file = if timeout < 0 {
  604. None
  605. } else {
  606. let timeout_path = unsafe {
  607. CString::from_vec_unchecked(
  608. format!("time:{}", syscall::CLOCK_MONOTONIC).into_bytes(),
  609. )
  610. };
  611. let mut timeout_file = match File::open(&timeout_path, fcntl::O_RDWR | fcntl::O_CLOEXEC)
  612. {
  613. Ok(file) => file,
  614. Err(_) => return -1,
  615. };
  616. if event_file
  617. .write(&syscall::Event {
  618. id: *timeout_file as usize,
  619. flags: syscall::EVENT_READ,
  620. data: TIMEOUT_TOKEN,
  621. })
  622. .is_err()
  623. {
  624. return -1;
  625. }
  626. let mut time = syscall::TimeSpec::default();
  627. if timeout_file.read(&mut time).is_err() {
  628. return -1;
  629. }
  630. time.tv_nsec += timeout * 1000000;
  631. while time.tv_nsec >= 1000000000 {
  632. time.tv_sec += 1;
  633. time.tv_nsec -= 1000000000;
  634. }
  635. if timeout_file.write(&time).is_err() {
  636. return -1;
  637. }
  638. Some(timeout_file)
  639. };
  640. let mut events = [syscall::Event::default(); 32];
  641. let read = {
  642. let mut events = unsafe {
  643. slice::from_raw_parts_mut(
  644. &mut events as *mut _ as *mut u8,
  645. mem::size_of::<syscall::Event>() * events.len(),
  646. )
  647. };
  648. match event_file.read(&mut events) {
  649. Ok(i) => i / mem::size_of::<syscall::Event>(),
  650. Err(_) => return -1,
  651. }
  652. };
  653. for event in &events[..read] {
  654. if event.data == TIMEOUT_TOKEN {
  655. continue;
  656. }
  657. for fd in fds.iter_mut() {
  658. if event.id == fd.fd as usize {
  659. if event.flags & syscall::EVENT_READ > 0 {
  660. fd.revents |= poll::POLLIN;
  661. }
  662. if event.flags & syscall::EVENT_WRITE > 0 {
  663. fd.revents |= poll::POLLOUT;
  664. }
  665. }
  666. }
  667. }
  668. let mut total = 0;
  669. for fd in fds.iter_mut() {
  670. if fd.revents > 0 {
  671. total += 1;
  672. }
  673. }
  674. total
  675. }
  676. fn read(fd: c_int, buf: &mut [u8]) -> ssize_t {
  677. e(syscall::read(fd as usize, buf)) as ssize_t
  678. }
  679. fn readlink(pathname: &CStr, out: &mut [u8]) -> ssize_t {
  680. let file = match File::open(pathname, fcntl::O_PATH | fcntl::O_SYMLINK | fcntl::O_CLOEXEC) {
  681. Ok(ok) => ok,
  682. Err(_) => return -1,
  683. };
  684. if out.is_empty() {
  685. return 0;
  686. }
  687. let len = out.len();
  688. let read = e(syscall::fpath(*file as usize, &mut out[..len - 1]));
  689. if (read as c_int) < 0 {
  690. return -1;
  691. }
  692. out[read as usize] = 0;
  693. 0
  694. }
  695. fn realpath(pathname: &CStr, out: &mut [u8]) -> c_int {
  696. let file = match File::open(pathname, fcntl::O_PATH | fcntl::O_CLOEXEC) {
  697. Ok(ok) => ok,
  698. Err(_) => return -1,
  699. };
  700. if out.is_empty() {
  701. return 0;
  702. }
  703. let len = out.len();
  704. let read = e(syscall::fpath(*file as usize, &mut out[..len - 1]));
  705. if (read as c_int) < 0 {
  706. return -1;
  707. }
  708. out[read as usize] = 0;
  709. 0
  710. }
  711. fn rename(oldpath: &CStr, newpath: &CStr) -> c_int {
  712. match File::open(oldpath, fcntl::O_WRONLY | fcntl::O_CLOEXEC) {
  713. Ok(file) => e(syscall::frename(*file as usize, newpath.to_bytes())) as c_int,
  714. Err(_) => -1,
  715. }
  716. }
  717. fn rmdir(path: &CStr) -> c_int {
  718. e(syscall::rmdir(path.to_bytes())) as c_int
  719. }
  720. fn select(
  721. nfds: c_int,
  722. readfds: *mut fd_set,
  723. writefds: *mut fd_set,
  724. exceptfds: *mut fd_set,
  725. timeout: *mut timeval,
  726. ) -> c_int {
  727. let mut readfds = unsafe { readfds.as_mut() }.map(|s| BitSet::from_ref(&mut s.fds_bits));
  728. let mut writefds = unsafe { writefds.as_mut() }.map(|s| BitSet::from_ref(&mut s.fds_bits));
  729. let mut exceptfds =
  730. unsafe { exceptfds.as_mut() }.map(|s| BitSet::from_ref(&mut s.fds_bits));
  731. let event_path = c_str!("event:");
  732. let mut event_file = match File::open(event_path, fcntl::O_RDWR | fcntl::O_CLOEXEC) {
  733. Ok(file) => file,
  734. Err(_) => return -1,
  735. };
  736. for fd in 0..nfds as usize {
  737. macro_rules! register {
  738. ($fd:expr, $flags:expr) => {
  739. if event_file
  740. .write(&syscall::Event {
  741. id: $fd,
  742. flags: $flags,
  743. data: 0,
  744. })
  745. .is_err()
  746. {
  747. return -1;
  748. }
  749. };
  750. }
  751. if readfds.as_mut().map(|s| s.contains(fd)).unwrap_or(false) {
  752. register!(fd, syscall::EVENT_READ);
  753. }
  754. if writefds.as_mut().map(|s| s.contains(fd)).unwrap_or(false) {
  755. register!(fd, syscall::EVENT_WRITE);
  756. }
  757. }
  758. const TIMEOUT_TOKEN: usize = 1;
  759. let timeout_file = if timeout.is_null() {
  760. None
  761. } else {
  762. let timeout = unsafe { &*timeout };
  763. let timeout_path = unsafe {
  764. CString::from_vec_unchecked(
  765. format!("time:{}", syscall::CLOCK_MONOTONIC).into_bytes(),
  766. )
  767. };
  768. let mut timeout_file = match File::open(&timeout_path, fcntl::O_RDWR | fcntl::O_CLOEXEC)
  769. {
  770. Ok(file) => file,
  771. Err(_) => return -1,
  772. };
  773. if event_file
  774. .write(&syscall::Event {
  775. id: *timeout_file as usize,
  776. flags: syscall::EVENT_READ,
  777. data: TIMEOUT_TOKEN,
  778. })
  779. .is_err()
  780. {
  781. return -1;
  782. }
  783. let mut time = syscall::TimeSpec::default();
  784. if timeout_file.read(&mut time).is_err() {
  785. return -1;
  786. }
  787. time.tv_sec += timeout.tv_sec;
  788. time.tv_nsec += timeout.tv_usec * 1000;
  789. while time.tv_nsec >= 1000000000 {
  790. time.tv_sec += 1;
  791. time.tv_nsec -= 1000000000;
  792. }
  793. if timeout_file.write(&time).is_err() {
  794. return -1;
  795. }
  796. Some(timeout_file)
  797. };
  798. let mut events = [syscall::Event::default(); 32];
  799. let read = {
  800. let mut events = unsafe {
  801. slice::from_raw_parts_mut(
  802. &mut events as *mut _ as *mut u8,
  803. mem::size_of::<syscall::Event>() * events.len(),
  804. )
  805. };
  806. match event_file.read(&mut events) {
  807. Ok(i) => i / mem::size_of::<syscall::Event>(),
  808. Err(_) => return -1,
  809. }
  810. };
  811. let mut total = 0;
  812. if let Some(ref mut set) = readfds {
  813. set.clear();
  814. }
  815. if let Some(ref mut set) = writefds {
  816. set.clear();
  817. }
  818. if let Some(ref mut set) = exceptfds {
  819. set.clear();
  820. }
  821. for event in &events[..read] {
  822. if event.data == TIMEOUT_TOKEN {
  823. continue;
  824. }
  825. if event.flags & syscall::EVENT_READ == syscall::EVENT_READ {
  826. if let Some(ref mut set) = readfds {
  827. set.insert(event.id);
  828. }
  829. total += 1;
  830. }
  831. if event.flags & syscall::EVENT_WRITE == syscall::EVENT_WRITE {
  832. if let Some(ref mut set) = writefds {
  833. set.insert(event.id);
  834. }
  835. total += 1;
  836. }
  837. }
  838. total
  839. }
  840. fn setpgid(pid: pid_t, pgid: pid_t) -> c_int {
  841. e(syscall::setpgid(pid as usize, pgid as usize)) as c_int
  842. }
  843. fn setregid(rgid: gid_t, egid: gid_t) -> c_int {
  844. e(syscall::setregid(rgid as usize, egid as usize)) as c_int
  845. }
  846. fn setreuid(ruid: uid_t, euid: uid_t) -> c_int {
  847. e(syscall::setreuid(ruid as usize, euid as usize)) as c_int
  848. }
  849. fn symlink(path1: &CStr, path2: &CStr) -> c_int {
  850. let mut file = match File::create(
  851. path2,
  852. fcntl::O_WRONLY | fcntl::O_SYMLINK | fcntl::O_CLOEXEC,
  853. 0o777,
  854. ) {
  855. Ok(ok) => ok,
  856. Err(_) => return -1,
  857. };
  858. if file.write(path1.to_bytes()).is_err() {
  859. return -1;
  860. }
  861. 0
  862. }
  863. fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
  864. let dup = e(syscall::dup(fd as usize, b"termios"));
  865. if dup == !0 {
  866. return -1;
  867. }
  868. let read = e(syscall::read(dup, unsafe {
  869. slice::from_raw_parts_mut(out as *mut u8, mem::size_of::<termios>())
  870. }));
  871. let _ = syscall::close(dup);
  872. if read == !0 {
  873. return -1;
  874. }
  875. 0
  876. }
  877. fn tcsetattr(fd: c_int, _act: c_int, value: *const termios) -> c_int {
  878. let dup = e(syscall::dup(fd as usize, b"termios"));
  879. if dup == !0 {
  880. return -1;
  881. }
  882. let write = e(syscall::write(dup, unsafe {
  883. slice::from_raw_parts(value as *const u8, mem::size_of::<termios>())
  884. }));
  885. let _ = syscall::close(dup);
  886. if write == !0 {
  887. return -1;
  888. }
  889. 0
  890. }
  891. fn umask(mask: mode_t) -> mode_t {
  892. e(syscall::umask(mask as usize)) as mode_t
  893. }
  894. fn uname(utsname: *mut utsname) -> c_int {
  895. fn gethostname(name: &mut [u8]) -> io::Result<()> {
  896. if name.is_empty() {
  897. return Ok(())
  898. }
  899. let mut file = File::open(
  900. &CString::new("/etc/hostname").unwrap(),
  901. fcntl::O_RDONLY | fcntl::O_CLOEXEC,
  902. )?;
  903. let mut read = 0;
  904. let name_len = name.len();
  905. loop {
  906. match file.read(&mut name[read..name_len - 1])? {
  907. 0 => break,
  908. n => read += n,
  909. }
  910. }
  911. name[read] = 0;
  912. Ok(())
  913. }
  914. fn inner(utsname: *mut utsname) -> CoreResult<(), i32> {
  915. match gethostname(unsafe {
  916. slice::from_raw_parts_mut(
  917. (*utsname).nodename.as_mut_ptr() as *mut u8,
  918. (*utsname).nodename.len()
  919. )
  920. }) {
  921. Ok(_) => (),
  922. Err(_) => return Err(EIO),
  923. }
  924. let file_path = c_str!("sys:uname");
  925. let mut file = match File::open(file_path, fcntl::O_RDONLY | fcntl::O_CLOEXEC) {
  926. Ok(ok) => ok,
  927. Err(_) => return Err(EIO),
  928. };
  929. let mut lines = BufReader::new(&mut file).lines();
  930. let mut read_line = |dst: &mut [c_char]| {
  931. let line = match lines.next() {
  932. Some(Ok(l)) => match CString::new(l) {
  933. Ok(l) => l,
  934. Err(_) => return Err(EIO),
  935. },
  936. None | Some(Err(_)) => return Err(EIO),
  937. };
  938. let line_slice: &[c_char] = unsafe { mem::transmute(line.as_bytes_with_nul()) };
  939. if line_slice.len() <= UTSLENGTH {
  940. dst[..line_slice.len()].copy_from_slice(line_slice);
  941. Ok(())
  942. } else {
  943. Err(EIO)
  944. }
  945. };
  946. unsafe {
  947. read_line(&mut (*utsname).sysname)?;
  948. read_line(&mut (*utsname).release)?;
  949. read_line(&mut (*utsname).machine)?;
  950. // Version is not provided
  951. ptr::write_bytes((*utsname).version.as_mut_ptr(), 0, UTSLENGTH);
  952. // Redox doesn't provide domainname in sys:uname
  953. //read_line(&mut (*utsname).domainname)?;
  954. ptr::write_bytes((*utsname).domainname.as_mut_ptr(), 0, UTSLENGTH);
  955. }
  956. Ok(())
  957. }
  958. match inner(utsname) {
  959. Ok(()) => 0,
  960. Err(err) => unsafe {
  961. errno = err;
  962. -1
  963. },
  964. }
  965. }
  966. fn unlink(path: &CStr) -> c_int {
  967. e(syscall::unlink(path.to_bytes())) as c_int
  968. }
  969. fn waitpid(mut pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t {
  970. if pid == !0 {
  971. pid = 0;
  972. }
  973. unsafe {
  974. let mut temp: usize = 0;
  975. let res = e(syscall::waitpid(pid as usize, &mut temp, options as usize));
  976. if !stat_loc.is_null() {
  977. *stat_loc = temp as c_int;
  978. }
  979. res as pid_t
  980. }
  981. }
  982. fn write(fd: c_int, buf: &[u8]) -> ssize_t {
  983. e(syscall::write(fd as usize, buf)) as ssize_t
  984. }
  985. }