2010-07-05 71 views
5

我有以下的情況(僞代碼):防止叉()從複製插座

function f: 
    pid = fork() 
    if pid == 0: 
     exec to another long-running executable (no communication needed to that process) 
    else: 
     return "something" 

f暴露在XmlRpc++服務器。當函數通過XML-RPC調用時,父進程在函數返回「something」後打印「done closing socket」。但是,只要子進程仍在運行,XML-RPC客戶端就會掛起。當我終止子進程時,XML-RPC客戶端正確地完成RPC調用。

在我看來,我在fork()將子套接字描述符複製到子進程(父進程名爲closesocket,但子進程仍然擁有引用 - >連接仍然建立)時出現問題。我怎樣才能繞過這個?

編輯:我讀到FD_CLOEXEC了,但我不能所有描述要在exec關閉?

回答

5

不,您不能強制所有文件描述符在exec上關閉。您需要在fork()後面的子節點中循環遍歷所有不需要的文件描述符並關閉它們。不幸的是,這不是一種簡單便捷的方法 - 通常的做法是使用getrlimit()獲取當前值RLIMIT_NOFILE並從3循環到該數字,嘗試close()對每個候選人。

如果您很高興成爲僅限於Linux的用戶,您可以閱讀/proc/self/fd/目錄以確定打開的文件描述符並關閉它們(0,1和2除外 - 應單獨保留或重新打開爲/dev/null)。

+2

或者是可移植的,只需在'exec(2)'之前不需要的描述符上設置'FD_CLOEXEC'。 – 2010-07-05 15:36:15

+0

我現在用proc文件系統實現了它,如果需要的話(如果/ proc/self/fd不存在),可以回到'getrlimit'解決方案。只有一個問題:getrlimit(RLIMIT_NOFILE,...) - 1'和'sysconf(_SC_OPEN_MAX)'有區別嗎? – AndiDog 2010-07-05 16:14:47

+0

@Nikolai:當然,或者只是'close()'它們 - 但是假設你知道哪些文件描述符是打開的,並且從上下文看起來並非如此(因爲它們被第三個第四方軟件)。 – caf 2010-07-05 23:45:08