2013-10-19 62 views
2

當我在Linux上創建套接字,有可能在創建時指定的標誌O_CLOEXEC如何在Mac上自動創建「close-on-exec」套接字?

auto fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, 0); 

所以沒有辦法,一些其他線程會做fork() + exec()與此套接字保持開放。

但是在Mac,根據手冊,我不能做同樣的特技:

插座具有所指示的類型,用於指定通信的語義。 目前定義的類型有: SOCK_STREAM SOCK_DGRAM SOCK_RAW SOCK_SEQPACKET SOCK_RDM

標誌O_CLOEXEC只能使用到fcntl()呼叫建立。這不是原子的方式 - 在socket()fcntl()的調用之間,某個線程可能會執行exec()

如何解決此問題?

回答

-1

這裏需要同步。

socket()fork()並創建一個互斥體,其保持了系統的fork()從另一個線程是在critcal部分調用系統的插口()和fcntl()之間執行。

僞代碼:

mutex_t m = mutex_init(...); 

int socket_wrapper(...) 
{ 
    lock(m); 

    int sd = socket(..); 
    fcntl(sd, O_CLOEXEC); 

    unlock(m); 

    return sd; 
} 

pid_t fork_wrapper(void) 
{ 
    lock(m); 

    pid_t pid = fork(); 

    unlock(m) 

    return pid; 
} 
+0

它是由蘋果API文檔推薦的方式,或者是一個API設計孔? –

+0

Downvoted,因爲這絕對不是一個解決方案。 你只是不控制分叉調用。 是的,這是基於unix和不完整的多線程設計的Unix上的許多API設計漏洞之一。並非所有的東西都可以像Linux一樣快速修復。 – Lothar