popen的问题

时间:2011-01-10 12:45:58

标签: c++ linux

我有一个奇怪的问题。我有两个名为cpp的二进制文件,另一个名为mnp_proxy_server。

cpp将通过调用 executeScript 方法启动mnp_proxy_binary。这个方法的代码是

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端口并开始发送消息。

现在出现问题。当我向cpp发送ctr ^ c信号时,信号传播到mnp_proxy_server,如果我杀死了cpp进程,那么cpp正在列出的所有端口现在都成为mnp_proxy_server进程的一部分。

杀死cpp进程后netstat的输出

[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

我知道这与我通过cpp执行mnp_proxy_server的启动脚本的方式有关。

两个二进制文件中都有一个信号处理程序。并且当按下ctr ^ c时退出套接字选择我在select中使用了管道,所以当按下ctr ^ c时,我关闭管道的写入端,以便通知选择并且选择出来并打破运行循环。

它们都是用c ++编写的,我使用的是rhel 任何线索都将极大地帮助我解决这个问题。提前感谢。

1 个答案:

答案 0 :(得分:1)

您应该在cpp的服务器套接字上设置标志CLOEXEC,以便它们在子进程中关闭:

fcntl(fd, F_SETFD, FD_CLOEXEC);

在你的进程中使用套接字时,我建议使用fork和exec而不是popen来关闭或管理fork和exec之间的所有套接字,但是标志CLOEXEC可能足以解决你的问题。