2009-08-21 1 views
2

子プロセスが現在のプロセスのオープンファイル/ポートを継承しないようにOS X上で子プロセスを起動したい。ファイル/ポートを継承しないOSX/Unix上で子プロセスを起動する

これを達成するための提案はありますか?私がsystem()関数を使って呼び出すことのできるシェルコマンドも機能します。これを可能にする良いシェルコマンドはわかりません。

ありがとうございます!

+0

WindowsのCreateProcessには、これを処理するための 'bInheritHandles'フラグがあり、UNIX/Mac OS相当のものを探します。 – psychotik

答えて

0

いくつか試した後、私は、Mac上の「オープン」シェルコマンドは、親ファイル/ポートを継承していないプロセスを作成することがわかりました。システム関数への引数として 'open foo.app'を呼び出すことは、そのトリックを行います。もちろん、これはMacのみです。 Unixでは、ここで示唆されている他のアプローチの1つが非常に意味があります。

+0

openコマンドは、プロセスを起動する(または既存のプロセスにドキュメントを開く)ようにlaunchdに指示します。そのため、あなたはその親ではありません。それがあなたから何かを継承しない理由です。 – mark4o

+0

@ mark4o 'open'を実行すると、結果のプロセスが環境変数を継承します(Finderの代わりにTerminalからアプリケーションを開くと、別の環境になります)。 – jpc

10

はあなたが開発しているどのような言語を指定しませんでしたが、あなたはsystem()を言及したことから、私はあなたがCまたはC++を意味すると仮定します。

通常、これはあなたが継承したくないそれらのファイルディスクリプタにclose-on-execフラグを設定するのfcntl()を使用することによって達成される:

int fd = open("somefile", O_RDONLY); 
fcntl(fd, F_SETFD, FD_CLOEXEC); 

あなたはまた、ブルートフォース行うことができますフォークした後、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

1

のMac OS X上で開いているファイルディスクリプタのセットを決定するためにopendir()/readdir()でディレクトリ/dev/fd/を読んで使用することができます。この情報を使用すると、各オープンファイル記述子にfcntl(FD, F_SETFD, FD_CLOEXEC)を呼び出すことができますいずれか、あるいはあなたはフォーク後に各ファイルディスクリプタにclose(FD)を呼び出すことができます。

Getting the highest allocated file descriptorを参照してください(他のシステムへのアプローチを含む)。

0

@エリックM:あなたの答えは私のところでほとんどの方法を得ましたが、まだいくつかのファイル記述子が開いていることがわかりました。上記のコードのsysconf(OPEN_MAX)getdtablesize()に置き換えました。助けてくれてありがとう!

関連する問題