libmoost
/home/mhx/git/github/libmoost/src/service/impl/posix_stream_stealer.ipp
Go to the documentation of this file.
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 }