Free Web Hosting Provider - Web Hosting - E-commerce - High Speed Internet - Free Web Page
Search the Web



// =======================================
// C++Wrapper around popen
// that recognizes invalid command_line.
// =======================================

#include "popen.h"

// ==================
// =====================================
#define FATAL_MSG(msg) \
        cout << msg \
             << " : " \
             << (strerror (errno)) \
             << " [ " \
             << __FILE__ \
             << ", #" \
             << __LINE__ \
             << " ]" \
             << endl

#define ERROR_MSG(msg) \
        cout << msg \
             << " : " \
             << " [ " \
             << __FILE__ \
             << ", #" \
             << __LINE__ \
             << " ]" \
             << endl


// =====================================
bool popen_cplusplus_wrapper (
                const string&   command_line_i,
                vector<string>& out_result_o,
                vector<string>& err_result_o
                )
{
bool            ret_boolValue = true;

FILE*           fp_outfile;
FILE*           fp_errfile;

const int       SIZEBUF = 1234;
char            buf [SIZEBUF];

const int       FD_STDERR = 2;
int             fd_errfile;
int             fd_new_errfile;
int             fd_save_error;

string          cur_string;


  // ################################################
  // ######## Redirection : stderr to errfile #######
  // ################################################
  // ======================
  if ((fp_errfile = tmpfile ()) == NULL)
  {
    FATAL_MSG ("Cannot execute tmpfile ()");
  }
  fd_errfile = fileno (fp_errfile);
  // ======================

  // ======================
  // redirect error to file
  if ((fd_save_error = dup (FD_STDERR)) == -1)
  {
    FATAL_MSG ("Cannot execute dup");
  }
  // Now fd_save_error and 2 are descriptors of the screen
  // ======================


  // ======================
  // Close screen
  if (close (FD_STDERR) == -1)
  {
    FATAL_MSG ("Cannot close descriptor");
  }
  // Now descriptor 2 (FD_STDERR) is vacant
  // ======================

  // ======================
  if ((fd_new_errfile = dup (fd_errfile)) == -1)
  {
    FATAL_MSG ("Cannot execute dup");
  }
  // Now fd_errfile and 2 are descriptors of the errfile
  // ======================


  // ##########################
  /* This is in comment
  // ======================
  if (close (fd_errfile) == -1)
  {
    FATAL_MSG ("Cannot close descriptor");
  }
  // Now only descriptor 2 (FD_STDERR) is descriptor of the errfile
  // ======================
  */
  // ##########################


  // ################################################
  // ################# popen ########################
  // ################################################
  if ((fp_outfile = popen(command_line_i.c_str (), "r")) == NULL)
  {
    FATAL_MSG ("Files or processes cannot be created");
    ret_boolValue = false;
  }


  // ################################################
  // ### Get out stream ############################
  // ################################################
  // ================================
  out_result_o = vector<string> ();
  // ================================
  if (ret_boolValue)
  {
    while (fgets(buf, sizeof (buf), fp_outfile))
    {
      cur_string = buf;
      if (cur_string [cur_string.size () - 1] != '\n')
      {
        ERROR_MSG ("SIZEBUF too small ("
                 << SIZEBUF
                 << ") or missing '\\n'"
                 );
        out_result_o.push_back ("!!! Cannot get this out_line !!!");
        ret_boolValue = false;
        break;
      }

     // ------------------------------------
     assert (cur_string [cur_string.size () - 1] =='\n');
     cur_string = cur_string.substr (0, cur_string.size () - 1);
     out_result_o.push_back (cur_string);
     // ------------------------------------
    } // while (fgets(buf, sizeof (buf), fp_outfile))

    // ================================
    if (pclose(fp_outfile) == -1)
    {
      FATAL_MSG ("Cannot execute pclose");
      ret_boolValue = false;
    }
  } // if (ret_boolValue)

  // ======================
  // Close screen
  if (close (FD_STDERR) == -1)
  {
    FATAL_MSG ("Cannot close descriptor");
  }
  // Now descriptor 2 (FD_STDERR) is vacant
  // ======================

  // ======================
  if ((fd_new_errfile = dup (fd_errfile)) == -1)
  {
    FATAL_MSG ("Cannot execute dup");
  }
  // Now fd_errfile and 2 are descriptors of the errfile
  // ======================



  // ################################################
  // ### Restore : error stream to screen ###########
  // ################################################
  // ======================
  // redirect (restore) error to screen
  // Close screen
  if (close (FD_STDERR) == -1)
  {
    FATAL_MSG ("Cannot close descriptor");
  }
  // Now descriptor 2 (FD_STDERR) is vacant
  // ======================

  // ======================
  if (dup (fd_save_error) == -1)
  {
    FATAL_MSG ("Cannot execute dup");
  }
  // Now fd_save_error and 2 are descriptors of the screen
  // ======================

  // ======================
  if (close (fd_save_error) == -1)
  {
    FATAL_MSG ("Cannot close descriptor");
  }
  // Now only descriptor 2 (FD_STDERR) is descriptor of the screen

  // ======================


  // ################################################
  // ### Get error stream ###########################
  // ################################################
  // ================================
  err_result_o = vector<string> ();
  // ================================
  rewind (fp_errfile);
  while (fgets(buf, sizeof (buf), fp_errfile))
  {
    cur_string = buf;
    if (cur_string [cur_string.size () - 1] != '\n')
    {
      ERROR_MSG ("SIZEBUF too small ("
               << SIZEBUF
               << ") or missing '\\n'"
               );
      err_result_o.push_back ("!!! Cannot get this error-line !!!");
      ret_boolValue = false;
      break;
    }

    // ------------------------------------
    assert (cur_string [cur_string.size () - 1] == '\n');
    err_result_o.push_back (cur_string.substr (0, cur_string.size () - 1));
    // ------------------------------------
  } // while (fgets(buf, sizeof (buf), fp_errfile))

  if (!err_result_o.empty ())
  {
    ret_boolValue = false;
  }

  // ===================
  return ret_boolValue;
  // ===================

} // bool popen_cplusplus_wrapper (...)