我想在OS X上啓動子進程,以便子進程不會繼承當前進程的打開文件/端口。在OSX/Unix上啓動不繼承文件/端口的子進程
有關如何完成此任務的任何建議?我可以使用system()函數調用的Shell命令也可以工作 - 我只是不知道有一個很好的shell命令來啓用它。
謝謝!
我想在OS X上啓動子進程,以便子進程不會繼承當前進程的打開文件/端口。在OSX/Unix上啓動不繼承文件/端口的子進程
有關如何完成此任務的任何建議?我可以使用system()函數調用的Shell命令也可以工作 - 我只是不知道有一個很好的shell命令來啓用它。
謝謝!
經過一番試驗後,我發現Mac上的'open'shell命令創建了一個不會繼承父文件/端口的進程。將「open foo.app」作爲參數調用到系統函數中會有訣竅。當然,這只是mac。對於Unix,這裏提出的其他方法之一很有意義。
您沒有指定您正在開發的語言,但自從您提到system()
以後,我假設您的意思是C或C++。
這通常是通過使用的fcntl()來設置,你不希望這些文件描述符的close-on-exec標誌完成,以繼承:
int fd = open("somefile", O_RDONLY);
fcntl(fd, F_SETFD, FD_CLOEXEC);
你也可以做它的蠻力在fork之後但在exec之前迭代子進程中所有可能的fd。這有點棘手,因爲它要求你知道最大可能的fd值是多少,並且效率也不高,因爲你最終會迭代並「關閉」一堆未使用的fd。事情是這樣的:
pid_t pid = fork();
switch (pid) {
case 0:
// In the child process. Iterate through all possible file descriptors
// and explicitly close them.
long maxfd = sysconf(OPEN_MAX);
for (long i = 0; i < maxfd; ++i) {
close(i);
}
// Now exec the new program, file-handle free.
execlp("someprogram", "arg1", "arg2");
break;
case -1:
// TODO: handle errors.
break;
default:
// Parent process.
int status;
pid_t finished = waitpid(pid, &status, 0);
break;
}
希望幫助,
埃裏克Melski
在Mac OS X中,可以使用讀取目錄/dev/fd/
與opendir()
/readdir()
來確定一套開放的文件描述符。有了這些信息,您可以調用fcntl(
FD, F_SETFD, FD_CLOEXEC)
每個打開的文件描述符,或者你可以分叉後調用每個文件描述符close(
FD)
。
請參閱Getting the highest allocated file descriptor瞭解一些其他詳細信息,包括其他系統的方法。
@Eric M:你的回答讓我瞭解了大部分的途徑,但是我發現它仍然留下了一些文件描述符。我用getdtablesize()
替換了上面代碼中的sysconf(OPEN_MAX)
,它效果很好。謝謝您的幫助!
Windows中的CreateProcess具有'bInheritHandles'標誌來處理這個問題 - 尋找UNIX/Mac OS等價物。 – psychotik 2009-08-21 00:30:22