S
Sooraj S
Hi,
I am very new to C++. In my code i am using readline to get the user
input which is a command and that input will be processed accordingly.
When user enters a command named "setflag", i should set a flag to
TRUE in all the active sessions of my processes.
The code works just fine. I am able to update the flag in all the
processes simultaneously using signals.
Problem:
--------
Please compile the code as: g++ -lreadline -lncurses alex123.cpp -o
alex123
Spawn three processes (am refering to them as P1, P2, P3) by executing
the binary "alex123" on separate terminals. In P1 issue "setflag"
command. You can see that "MYFLAG" is set to TRUE in P1. Also you can
see that P2 and P3 are able to receive the signal. But in P2 and P3
you wont see the command prompt. Only if you press the "enter" key on
P2 and P3, you will get the command prompt back.
I want this in such a way that command prompt should automatically
come. Pls help me.
alex123.cpp
===========
#include "stdio.h"
#include "iostream"
#include "signal.h"
#include "sys/time.h"
#include "string"
#include "stdlib.h"
#include "sstream"
#include "sys/types.h"
#include "unistd.h"
#include "/usr/include/readline/readline.h"
#include "/usr/include/readline/history.h"
using namespace std;
bool myFlag = false;
void updateFlag(int i)
{
cout << "\nGot the signal.";
myFlag= true;
//To give line feed from within the code itself. I need the fix
here.
putc(10,stdout); // This doesn't work.
}
int getOtherPids(string &pidList)
{
char pid[10];
string pidStr;
FILE *stream;
//Command the search the process alex123
std::string cmd = "pgrep -x alex123";
stream = popen(cmd.c_str(),"r");
if (stream == NULL)
{
cout << "\nWhat the hell\n";
return 0;
}
while (fgets(pid, 10, stream) != NULL)
{
for(int i=0;i<10;i++)
{
int p = (int)pid - 48;
if ((p >= 0) && (p <= 9))
pidStr.append(1,pid);
}
pidStr.append(1,' ');
pidList.append(pidStr);
pidStr.clear();
}
int status = pclose(stream);
if (status == -1)
{
cout << "\nWhat the hell!! AGAIN !!\n"; return 0;
}
return 1;
}
void notifyOthers()
{
string pidList;
string notifyCmd;
//Convert pid of type int to a string
int my_pid = getpid();
ostringstream os;
os << my_pid;
string myPid = os.str();
//Get other existing alex123 process list to which notification
has to be sent.
if (!getOtherPids(pidList))
{
cout << "!!WARNING!! Couldn't get active pids\n";
return;
}
size_t pos = pidList.find(myPid.c_str());
if (pos == string::npos)
{
cout << "!!WARNING!! Other Active process list is empty.\n";
return;
}
//Remove current session pid from the pid list string.
pidList.replace(pos,myPid.length()+1,"");
//If there are no other existing alex123 processes, return from
the function.
if(strcmp(pidList.c_str(),"") == 0) return;
pidList.replace(pidList.length()-1,1,"\0");
//Send SIGUSR1 signal to others.
notifyCmd = "kill -SIGUSR1 " + pidList;
system(notifyCmd.c_str());
}
int main()
{
char *foo;
for(;
{
//If SIGUSR1 is caught it means that some other process has set
the myFlag to TRUE by issuing a "setflag" command.
//So it should be set here also.
signal(SIGUSR1, updateFlag);
cout << "\nMYFLAG:"<< myFlag <<endl;
foo = readline("<alex> ");
if(strcmp(foo,"exit") ==0) { return 0; }
if(strcmp(foo,"setflag") == 0)
{
//Set myFlag to TRUE in the current process from where
"setflag" command was issued.
myFlag= true;
//Inform all other processes that myFlag has been updated.
notifyOthers();
}
}
return 0;
}
I am very new to C++. In my code i am using readline to get the user
input which is a command and that input will be processed accordingly.
When user enters a command named "setflag", i should set a flag to
TRUE in all the active sessions of my processes.
The code works just fine. I am able to update the flag in all the
processes simultaneously using signals.
Problem:
--------
Please compile the code as: g++ -lreadline -lncurses alex123.cpp -o
alex123
Spawn three processes (am refering to them as P1, P2, P3) by executing
the binary "alex123" on separate terminals. In P1 issue "setflag"
command. You can see that "MYFLAG" is set to TRUE in P1. Also you can
see that P2 and P3 are able to receive the signal. But in P2 and P3
you wont see the command prompt. Only if you press the "enter" key on
P2 and P3, you will get the command prompt back.
I want this in such a way that command prompt should automatically
come. Pls help me.
alex123.cpp
===========
#include "stdio.h"
#include "iostream"
#include "signal.h"
#include "sys/time.h"
#include "string"
#include "stdlib.h"
#include "sstream"
#include "sys/types.h"
#include "unistd.h"
#include "/usr/include/readline/readline.h"
#include "/usr/include/readline/history.h"
using namespace std;
bool myFlag = false;
void updateFlag(int i)
{
cout << "\nGot the signal.";
myFlag= true;
//To give line feed from within the code itself. I need the fix
here.
putc(10,stdout); // This doesn't work.
}
int getOtherPids(string &pidList)
{
char pid[10];
string pidStr;
FILE *stream;
//Command the search the process alex123
std::string cmd = "pgrep -x alex123";
stream = popen(cmd.c_str(),"r");
if (stream == NULL)
{
cout << "\nWhat the hell\n";
return 0;
}
while (fgets(pid, 10, stream) != NULL)
{
for(int i=0;i<10;i++)
{
int p = (int)pid - 48;
if ((p >= 0) && (p <= 9))
pidStr.append(1,pid);
}
pidStr.append(1,' ');
pidList.append(pidStr);
pidStr.clear();
}
int status = pclose(stream);
if (status == -1)
{
cout << "\nWhat the hell!! AGAIN !!\n"; return 0;
}
return 1;
}
void notifyOthers()
{
string pidList;
string notifyCmd;
//Convert pid of type int to a string
int my_pid = getpid();
ostringstream os;
os << my_pid;
string myPid = os.str();
//Get other existing alex123 process list to which notification
has to be sent.
if (!getOtherPids(pidList))
{
cout << "!!WARNING!! Couldn't get active pids\n";
return;
}
size_t pos = pidList.find(myPid.c_str());
if (pos == string::npos)
{
cout << "!!WARNING!! Other Active process list is empty.\n";
return;
}
//Remove current session pid from the pid list string.
pidList.replace(pos,myPid.length()+1,"");
//If there are no other existing alex123 processes, return from
the function.
if(strcmp(pidList.c_str(),"") == 0) return;
pidList.replace(pidList.length()-1,1,"\0");
//Send SIGUSR1 signal to others.
notifyCmd = "kill -SIGUSR1 " + pidList;
system(notifyCmd.c_str());
}
int main()
{
char *foo;
for(;
{
//If SIGUSR1 is caught it means that some other process has set
the myFlag to TRUE by issuing a "setflag" command.
//So it should be set here also.
signal(SIGUSR1, updateFlag);
cout << "\nMYFLAG:"<< myFlag <<endl;
foo = readline("<alex> ");
if(strcmp(foo,"exit") ==0) { return 0; }
if(strcmp(foo,"setflag") == 0)
{
//Set myFlag to TRUE in the current process from where
"setflag" command was issued.
myFlag= true;
//Inform all other processes that myFlag has been updated.
notifyOthers();
}
}
return 0;
}