1 #include "config.h" // IWYU pragma: keep 2 3 #include "redirection.h" 4 5 #include <fcntl.h> 6 7 #include "io.h" 8 #include "wutil.h" 9 10 dup2_list_t::~dup2_list_t() = default; 11 get_target_as_fd() const12maybe_t<int> redirection_spec_t::get_target_as_fd() const { 13 errno = 0; 14 int result = fish_wcstoi(target.c_str()); 15 if (errno || result < 0) return none(); 16 return result; 17 } 18 oflags() const19int redirection_spec_t::oflags() const { 20 switch (mode) { 21 case redirection_mode_t::append: 22 return O_CREAT | O_APPEND | O_WRONLY; 23 case redirection_mode_t::overwrite: 24 return O_CREAT | O_WRONLY | O_TRUNC; 25 case redirection_mode_t::noclob: 26 return O_CREAT | O_EXCL | O_WRONLY; 27 case redirection_mode_t::input: 28 return O_RDONLY; 29 case redirection_mode_t::fd: 30 default: 31 DIE("Not a file redirection"); 32 } 33 } 34 resolve_chain(const io_chain_t & io_chain)35dup2_list_t dup2_list_t::resolve_chain(const io_chain_t &io_chain) { 36 ASSERT_IS_NOT_FORKED_CHILD(); 37 dup2_list_t result; 38 for (const auto &io : io_chain) { 39 if (io->source_fd < 0) { 40 result.add_close(io->fd); 41 } else { 42 result.add_dup2(io->source_fd, io->fd); 43 } 44 } 45 return result; 46 } 47 fd_for_target_fd(int target) const48int dup2_list_t::fd_for_target_fd(int target) const { 49 // Paranoia. 50 if (target < 0) { 51 return target; 52 } 53 // Note we can simply walk our action list backwards, looking for src -> target dups. 54 int cursor = target; 55 for (auto iter = actions_.rbegin(); iter != actions_.rend(); ++iter) { 56 if (iter->target == cursor) { 57 // cursor is replaced by iter->src 58 cursor = iter->src; 59 } else if (iter->src == cursor && iter->target < 0) { 60 // cursor is closed. 61 cursor = -1; 62 break; 63 } 64 } 65 return cursor; 66 } 67