helpers.rs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. use alloc::boxed::Box;
  2. use fs::File;
  3. use header::errno;
  4. use header::fcntl::*;
  5. use header::string::strchr;
  6. use io::LineWriter;
  7. use mutex::Mutex;
  8. use platform::types::*;
  9. use platform;
  10. use super::constants::*;
  11. use super::{Buffer, FILE};
  12. /// Parse mode flags as a string and output a mode flags integer
  13. pub unsafe fn parse_mode_flags(mode_str: *const c_char) -> i32 {
  14. let mut flags = if !strchr(mode_str, b'+' as i32).is_null() {
  15. O_RDWR
  16. } else if (*mode_str) == b'r' as i8 {
  17. O_RDONLY
  18. } else {
  19. O_WRONLY
  20. };
  21. if !strchr(mode_str, b'x' as i32).is_null() {
  22. flags |= O_EXCL;
  23. }
  24. if !strchr(mode_str, b'e' as i32).is_null() {
  25. flags |= O_CLOEXEC;
  26. }
  27. if (*mode_str) != b'r' as i8 {
  28. flags |= O_CREAT;
  29. }
  30. if (*mode_str) == b'w' as i8 {
  31. flags |= O_TRUNC;
  32. } else if (*mode_str) == b'a' as i8 {
  33. flags |= O_APPEND;
  34. }
  35. flags
  36. }
  37. /// Open a file with the file descriptor `fd` in the mode `mode`
  38. pub unsafe fn _fdopen(fd: c_int, mode: *const c_char) -> Option<*mut FILE> {
  39. if *mode != b'r' as i8 && *mode != b'w' as i8 && *mode != b'a' as i8 {
  40. platform::errno = errno::EINVAL;
  41. return None;
  42. }
  43. let mut flags = 0;
  44. if strchr(mode, b'+' as i32).is_null() {
  45. flags |= if *mode == b'r' as i8 { F_NOWR } else { F_NORD };
  46. }
  47. if !strchr(mode, b'e' as i32).is_null() {
  48. sys_fcntl(fd, F_SETFD, FD_CLOEXEC);
  49. }
  50. if *mode == 'a' as i8 {
  51. let f = sys_fcntl(fd, F_GETFL, 0);
  52. if (f & O_APPEND) == 0 {
  53. sys_fcntl(fd, F_SETFL, f | O_APPEND);
  54. }
  55. flags |= F_APP;
  56. }
  57. let file = File::new(fd);
  58. let writer = LineWriter::new(file.get_ref());
  59. Some(Box::into_raw(Box::new(FILE {
  60. lock: Mutex::new(()),
  61. file,
  62. flags,
  63. read_buf: Buffer::Owned(vec![0; BUFSIZ as usize]),
  64. read_pos: 0,
  65. read_size: 0,
  66. unget: None,
  67. writer
  68. })))
  69. }