// =======================================
// 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 (...)