libmoost
|
00001 #include <unistd.h> 00002 00003 detail::posix_stream_stealer::posix_stream_stealer(bool restore, bool close_pipe) 00004 : m_handle(0) 00005 , m_pipe_fd(-1) 00006 , m_backup_fd(-1) 00007 , m_restore(restore) 00008 , m_close_pipe(close_pipe) 00009 { 00010 } 00011 00012 detail::posix_stream_stealer::~posix_stream_stealer() 00013 { 00014 if (m_restore) 00015 { 00016 restore(m_close_pipe); 00017 } 00018 } 00019 00020 bool detail::posix_stream_stealer::steal(FILE *handle) 00021 { 00022 int fd = fileno(handle); 00023 00024 if (fd < 0) 00025 { 00026 return false; 00027 } 00028 00029 int backup = dup(fd); 00030 00031 if (backup < 0) 00032 { 00033 return false; 00034 } 00035 00036 int pfd[2]; 00037 00038 if (pipe(pfd) != 0) 00039 { 00040 goto fail1; 00041 } 00042 00043 if (dup2(pfd[1], fd) < 0) 00044 { 00045 goto fail2; 00046 } 00047 00048 m_handle = handle; 00049 m_backup_fd = backup; 00050 m_pipe_fd = pfd[0]; 00051 00052 return true; 00053 00054 fail2: 00055 (void) close(pfd[0]); 00056 (void) close(pfd[1]); 00057 00058 fail1: 00059 (void) close(backup); 00060 return false; 00061 } 00062 00063 bool detail::posix_stream_stealer::restore(bool close_pipe) 00064 { 00065 if (m_handle == 0) 00066 { 00067 return true; 00068 } 00069 00070 int fd = fileno(m_handle); 00071 00072 m_handle = 0; 00073 00074 if (fd < 0) 00075 { 00076 return false; 00077 } 00078 00079 if (dup2(m_backup_fd, fd) < 0) 00080 { 00081 return false; 00082 } 00083 00084 if (close(m_backup_fd) < 0) 00085 { 00086 return false; 00087 } 00088 00089 if (close_pipe) 00090 { 00091 if (close(m_pipe_fd) < 0) 00092 { 00093 return false; 00094 } 00095 } 00096 00097 return true; 00098 }