我想在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