mod.rs 35 KB

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