I'm trying to parse the command-line arguments of another program (which is an emulator) inside my program using system()
command and the emulator's pid
. Unfortunately using both file read and cat
, the output is not well-formatted, so I can not really get the data. cat
on command line shows the file contents with spaces removed, the whole string sticked together, and using ifstream
, it only shows the name of the program (the first argument I guess). Anyone has got any ideas?
The format of the arguments is like this:
sudo ./src/yse6 -w -f tracefiles/capacity.3Mbps_400RTT_PER_0.0001.txt -at=eth1 -an=eth0
and eventually I need to show the same string as formatted above.
Here is what I've done so far: (ExecCommand()
gets a command, runs it in command-line and returns the result as string
. Secondary()
tries to get the file contents using file reader.)
std::string ExeCommand(const char* cmd) {
FILE* pipe = popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[128];
std::string result = "";
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);
return result;
}
void secondary(string addr){
ifstream file(addr.c_str(),ios::in);
if (file.good())
{
string str;
while(getline(file, str))
{
istringstream ss(str);
cout<<str<<endl;
char num[50];
while(ss >> num)
{
cout<<num;
}
}
}else{
cout<<"no file exists."<<endl;
}
}
int main (int argc, char* argv[])
{
if ((string) argv[1] == "-q") {
string pid=ExeCommand("ps -A | grep 'yse6' | awk '{print $1}'");
if(pid==""){
cout<<"No YSE emulator is running."<<endl;
}else{
pid=pid.substr(0,pid.size()-1);
cout<<pid<<endl;
string addr="cat /usr/bin/strings /proc/"+pid+"/cmdline";
cout<<addr<<endl;
// secondary(addr);
const char * c = addr.c_str();
string config=ExeCommand(c);
//get the config
cout << config<<endl;
}//end of else
}
}
Something like this, but with more error checking, should be a good start (this is more C than C++, aside from the cout
bit):
const int BUFSIZE = 4096; // should really get PAGESIZE or something instead...
unsigned char buffer[BUFSIZE]; // dynamic allocation rather than stack/global would be better
int fd = open("/proc/self/cmdline", O_RDONLY);
int nbytesread = read(fd, buffer, BUFSIZE);
unsigned char *end = buffer + nbytesread;
for (unsigned char *p = buffer; p < end; /**/)
{ cout << p << endl;
while (*p++); // skip until start of next 0-terminated section
}
close(fd);
In particular, open()
and read()
should be checked for error conditions, but I haven't shown that part... This may also fail in extreme cases where your command line is > 4096 characters long, or if for some other reason, read()
doesn't read the file in one call, which shouldn't happen in current /proc
implementations, but is not always guaranteed...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With