anraevlus18 0 Newbie Poster

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[i] - 48;
            if ((p >= 0) && (p <= 9))
                pidStr.append(1,pid[i]);
        }
        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;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.