helpers.rs 2.0 KB

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