2011-01-10 22 views
2

我有一個奇怪的問題。我有兩個名稱爲cpp的二進制文件,另一個名爲mnp_proxy_server。popen問題

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是一旦mnp_proxy_server開始它連接到端口7001,並且開始發送消息上的各種端口7001和7045監聽的服務器。

現在即將出現問題。當我發送ctr^c信號到cpp時,信號被傳播到mnp_proxy_server,如果我殺死了cpp進程,那麼cpp列出的所有端口現在都成爲mnp_proxy_server進程的一部分。殺死CPP處理後的netstat的

輸出

[根@ punith二進制]#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被按下時,我關閉管道的寫入端,以便通知select並選擇出來並中斷運行循環。

他們都是用C++編寫的,我正在使用rhel 任何線索都會大大幫助我解決這個問題。提前感謝。

回答

1

您應該設置在CPP的服務器套接字的標誌CLOEXEC使它們在子進程關閉:

fcntl(fd, F_SETFD, FD_CLOEXEC); 

在使用插座就像在你的過程,我會建議使用fork和exec代替popen能夠關閉或管理fork和exec之間的所有套接字,但CLOEXEC標誌可能足以解決您的問題。

+1

您可能還需要調用setpgrp()。 – vrdhn 2011-01-10 15:56:38