Reputation: 11008
I have an app which can be launched multiple times with different parameters and I need a way for one app instance to see what the other ones have for parameters (mainly to ensure that two instances do not run with the same params AND to focus on similar instance). I am currently using pid files but wonder if there is a way to mark running instance in some way visible from the other instances. I change CFBundleName for each instance, but it seems not visible (just the original name, not the changed). Is there a better way than pid files?
Some detail: the main application is a container which runs another internal application which has access to the container (i.e. to change CFBundleName etc.)
Upvotes: 0
Views: 93
Reputation: 419
I assume by "parameters" you mean the command-line arguments? You could run ps using popen, then capture and parse the output for the information you need. If you already know the pids for the other processes, you can look for that, and grep for the name of your app to reduce the output you need to look at.
Here is an example. You can see the arguments.
$ /bin/ps -Axo pid,args|grep TextWrangler|grep -v grep
643 /Applications/TextWrangler.app/Contents/MacOS/TextWrangler
645 /Applications/TextWrangler.app/Contents/Helpers/Crash Reporter.app/Contents/Helpers/crash-catcher -targetPID 643 -targetBundlePath /Applications/TextWrangler.app -showEmailAddressField 1
Here is how to use popen, and pipe the output to grep to look for your command name, pid, and arguments:
std::string cmdline("/bin/ps -Axo pid,args|grep '");
cmdline += appName;
cmdline += "'|grep -v grep";
// The output will look like: "S 428 APPNAME ARGS" with one space between entries.
// popen creates a pipe so we can read the output of the program we are invoking.
FILE *instream = popen(cmdline.c_str(), "r");
if(instream) {
// read the output, one line at a time.
const int MAX_BUFFER = 1024;
char buffer[MAX_BUFFER];
while (!feof(instream)){
if (fgets(buffer, MAX_BUFFER, instream) != NULL) {
std::string temp(buffer);
temp.trim(); // Get rid of leading and trailing whitespace. (Exercise for the reader.)
if(!temp.empty()) {
// First col is the state.
std::string::size_type i = temp.find(" ");
std::string state = temp.substr(0, i);
// Skip zombies.
if("Z" != state) {
// Second col is the pid.
// Advance i to the next char after the space.
++i;
std::string::size_type j = temp.find(" ", i);
std::string pidStr = temp.substr(i, j - i);
// Here we know the pid for APPNAME. You can further parse for the command line arguments here.
}
}
}
}
// close the pipe.
pclose(instream);
Upvotes: 1