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