2010-09-28 97 views
0

在Linux上,我有一些C++代碼,我想要執行另一個應用程序。該程序輸出一些數據到stderr。因此,我通過調用fredern()與stderr作爲流參數來重定向stderr。問題是,我想將stderr重定向到正在運行的另一個進程。execv調用後打開文件句柄會發生什麼? (C++)

這是我正在使用的場景。我fork()當前進程;在子進程中,我重定向stderr;然後我execv()運行單獨的應用程序。

首先,我有一個Sentry設置爲重定向stderr輸出。下面是代碼:

class StderrSentry { 
public: 
    StderrSentry() { 
    freopen("NUL", "wt", stderr); 
    } 
    ~StderrSentry() { 
    fclose(stderr); 
    } 
}; 

然後在後面的代碼:

pid_t pid = fork(); 
int retval=-1; 

if(pid < 0) { 
    success = false; 
} 
else if(! pid) { // child process 
    StderrSentry stdErrSentry; // REDIRECTING STDERR HERE! 
    pid_t chid = setsid(); 
    if (chid == -1) { 
    exit(-1); 
    } 
    else { 
    // HERE IS THE execv() call: 
    if(execv(command[0].c_str(), const_cast<char**>(&c_args[0])) < 0) { 
     exit(-1); 
    } 
    } 
} 
// ... else etc... 

將標準錯誤重定向其實還是在技術上是有效的,一旦execv()調用與指定的一個替換當前的進程?

這實際上表現得像我的願望,但這是一種僥倖,還是這樣做的方式?

我無法激活在execv中運行的應用程序中的stderr重定向,因爲它不是我的代碼。

感謝您對此的任何信息。

回答

0

重定向非常有效。 execv調用更改過程映像,但文件描述符保持不變。

+0

感謝所有人的答覆 - 他們都可以標記爲'答案'。這有助於我對此代碼充滿信心,因爲它很快就會發布。再次感謝。 – Raymond 2010-09-28 19:13:26

+0

這可能不適用於所有類型的描述符。如果這些標記爲O_CLOEXEC標誌,調用execv將使它們關閉。 – codewarrior 2013-11-06 18:47:11

2

在文件描述符(open,close,dup2)上操作的操作系統基元操作比freopen和朋友操作通常更安全,但是,這應該是可行的,並且shell管道是如何操作的實現。 execve離開全部打開文件,除非它們被標記爲F_CLOEXEC。

1

如果文件描述符沒有O_CLOEXEC標誌(參見man 2打開),它們應該保持在exec之間。此標誌僅在內核2.6.23及更高版本中可用,因此如果您使用的是舊版發行版,則該標誌將不可用。

+1

O_CLOEXEC作爲open(2)標誌是相對較新的,但'fcntl(fd,F_SETFD,FD_CLOEXEC)'已經出現了。 – zwol 2010-09-28 19:02:24

+0

我很確定我們的發行版本是最新的,但是我並沒有使用該標誌,正如我所說的那樣。我只是想確定代碼是否有意義。 – Raymond 2010-09-28 19:15:20

相關問題