2012-12-06 11 views
3

現在,我正在開發一個項目,在該項目中,我需要啓動子進程以使用C++在Linux中執行新程序,並且需要重定向標準輸入和輸出(如在C++ ,它們是cincout)到一個文件。這意味着在子進程中,標準輸入和輸出都是文件。子進程將從文件(其名稱將爲input.txt)讀取輸入,並輸出到文件(其名稱將爲output.txt)。在子進程中更改iostreams

通過使用cin.rdbuf()cout.rdbuf(),我實際上可以將cincout重定向到父進程中。但是當子進程啓動一個execl()命令時它不起作用。看來,在子進程執行execl()命令後,標準輸入輸出恢復正常。

任何人都可以幫助我解決這個問題嗎?過去幾天我一直困惑,找不到出路。

代碼如下:

//main.cpp

#include<sys/types.h> 
#include<sys/time.h> 
#include<sys/wait.h> 
#include<sys/ptrace.h> 
#include<sys/syscall.h> 
#include<string> 
#include"executor.cpp" 
int main(int argc, char*argv[]) 
{ 
executor ex; 
ex.set_path("/home/test"); 
ex.run_program(); 
} 

//executor.cpp

#include<sys/types.h> 
#include<sys/time.h> 
#include<sys/wait.h> 
#include<sys/ptrace.h> 
#include<sys/syscall.h> 
#include<string.h> 
#include<unistd.h> 
#include<iostream> 
#include<fstream> 

using namespace std; 
class executor{ 
public: 
void run_program() 
{ 
    char p[50]; 
    strcpy(p,path.c_str()); 
    cpid = fork(); 
    if(cpid == 0) 
    { 
        ifstream file("/home/openjudge/data.txt"); 
      if(!file) cout<<"file open failed\n"; 
      streambuf* x = cin.rdbuf(file.rdbuf()); 
     ptrace(PTRACE_TRACEME,0,NULL,NULL); 
     execl(p,"test","NULL); 
     cin.rdbuf(x); 
     cout<<"execute failed!\n"; 
    } 
    else if(cpid > 0) 
    { 
     wait(NULL); 
     cout<<"i'm a father\n"; 
    } 
} 
void set_path(string p) 
{ 
    path = p; 
} 
private: 
int cpid; 
string path; 
}; 

P.S. /home/test是一個簡單的程序,它從cin讀取並輸出到cout;

回答

1

您需要後fork()你的孩子的文件描述符0(標準輸入)和1(標準輸出)重定向:

switch (fork()) { 
case 0: { 
    close(0); 
    if (open(name, O_RDONLY) < 0) { 
     deal_with_error(); 
    } 
    ... 

你可能想打開父進程指向的文件。讓文件輕鬆打開可能會使錯誤處理更容易。在這種情況下,您可以使用dup2()將正確的文件描述符與文件相關聯。

+2

非常感謝! dup2()確實有效!並且我還發現freopen()也可以重定向標準輸入和輸出。但是,我仍然有一個問題。這些函數(dup2()和freopen())都在C庫中,有沒有辦法在C++中做到這一點? – lsc0825

相關問題