проблема с попен - PullRequest
       3

проблема с попен

2 голосов
/ 10 января 2011

У меня странная проблема.У меня есть 2 двоичных файла с именем cpp, а другой называется mnp_proxy_server.

cpp запустит mnp_proxy_binary, вызвав метод executeScript .Код этого метода:

int executeScript(string script, unsigned int scriptTmOut)
{
fd_set readfd;
const int BUFSIZE = 1024;
//stringstream strBuf;
char buf[ BUFSIZE];
time_t startTime = time(NULL);
struct timeval tv;
int ret, ret2 = 0;

FILE * pPipe = popen(script.c_str(), "r");
if (pPipe == NULL)
{
//        cout << "popen() failed:"<< strerror(errno) << endl;
    return -1;
}

while(1)
{
    FD_ZERO(&readfd);
    FD_SET(fileno(pPipe), &readfd);

    /** Select Timeout Hardcode with 1 secs **/
    tv.tv_sec = scriptTmOut;
    tv.tv_usec = 0;

    ret = select(fileno(pPipe)+1, &readfd, NULL, NULL, &tv);
    if(ret < 0)
    {
    //          cout << "select() failed " << strerror(errno) << endl;
    }
    else if (ret == 0)
    {
    //        cout << "select() timeout" << endl;
        break;
    }
    else
    {
        //cout << "Data is available now" <<endl;
        if(FD_ISSET(fileno(pPipe), &readfd))
        {
            if(fgets(buf, sizeof(buf), pPipe) != NULL )
            {
                //cout << buf;
                //strBuf << buf;
            }
            /** No Problem if there is no data ouput by script **/
            #if 1
            else
            {
                //ret2 = -1;
               // cout << "fgets() failed " << strerror(errno) << endl;
                break;
            }
            #endif
        }
        else
        {
            ret2 = -1;
  //          cout << "FD_ISSET() failed " << strerror(errno) << endl;
            break;
        }
    }

    /** Check the Script-timeout **/
    if((startTime + scriptTmOut) < time(NULL))
    {
    //    cout<<"Script Timeout"<<endl;
        break ;
    }
}
pclose(pPipe);

return ret2;

}

cpp - это сервер, который прослушивает различные порты 7001 и 7045. После запуска mnp_proxy_server он подключается к порту 7001 и начинает отправлять сообщения.

Теперь приступим к проблеме.когда я посылаю сигнал ctr ^ c в cpp, сигнал передается в mnp_proxy_server, и если я убиваю процесс cpp, то все порты, на которых cpp регистрировался, теперь становятся частью процесса mnp_proxy_server.процесс

[root @ punith bin] # netstat -alpn |grep mnp_pr

tcp 0 0 0.0.0.0:7045 0.0.0.0:* LISTEN 26186 / mnp_proxy_ser

tcp 0 0 0.0.0.0:7001 0.0.0.0: * LISTEN 26186 / mnp_proxy_ser

Я знаю, что это как-то связано с тем, как я выполняю сценарий запуска mnp_proxy_server через cpp.

В обоих двоичных файлах есть обработчик сигнала.А также для выхода из сокета select при нажатии ctr ^ c я использовал каналы в select, поэтому при нажатии ctr ^ c я закрываю конец записи канала так, что select уведомляется, а select выходит и прерывает цикл выполнения.

Они оба написаны на с ++, и я использую rhel. Любая подсказка очень поможет мне в решении этой проблемы.Заранее спасибо.

1 Ответ

1 голос
/ 10 января 2011

Вы должны установить флаг CLOEXEC на сокетах сервера cpp, чтобы они были закрыты в дочернем процессе:

fcntl(fd, F_SETFD, FD_CLOEXEC);

При использовании сокетов, как в ваших процессах, я бы предложил вместо этого использовать fork и execof popen, чтобы иметь возможность закрыть или управлять всеми сокетами между fork и exec, но флага CLOEXEC может быть достаточно для решения вашей проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...