はい、できます。posix spawn fileアクションの正しいリストを定義することは、間違いなく進むべき道です。
例:
#include <errno.h>
#include <fcntl.h>
#include <spawn.h>
#include <stdio.h>
#include <string.h>
#define CHECK_ERROR(R, MSG) do { if (R) { fprintf(stderr, "%s: %s\n",
(MSG), strerror(R)); return 1; } } while (0)
extern char **environ;
int main(int argc, char **argv)
{
if (argc < 3) {
fprintf(stderr, "Call: %s OUTFILE COMMAND [ARG]...\n", argv[0]);
return 2;
}
const char *out_filename = argv[1];
char **child_argv = argv+2;
posix_spawn_file_actions_t as;
int r = posix_spawn_file_actions_init(&as);
CHECK_ERROR(r, "actions init");
r = posix_spawn_file_actions_addopen(&as, 1, out_filename,
O_CREAT | O_TRUNC | O_WRONLY, 0644);
CHECK_ERROR(r, "addopen");
r = posix_spawn_file_actions_adddup2(&as, 1, 2);
CHECK_ERROR(r, "adddup2");
pid_t child_pid;
r = posix_spawnp(&child_pid, child_argv[0], &as, NULL,
child_argv, environ);
CHECK_ERROR(r, "spawnp");
r = posix_spawn_file_actions_destroy(&as);
CHECK_ERROR(r, "actions destroy");
return 0;
}
コンパイルとテスト:
$ cc -Wall -g -o spawnp spawnp.c
$ ./spawnp log date -I
$ cat log
2018-11-03
$ ./a.out log dat
spawnp: No such file or directory
posix_spawn
関数はerrnoを設定しないことに注意してください。代わりに、他のほとんどのUNIX関数とは異なり、エラーコードを返します。したがって、使用できませんperror()
が、などを使用する必要がありstrerror()
ます。
2つのspawn fileアクションを使用します:addopenとaddup2。addopenは通常と似てopen()
いますが、すでに開いている場合は自動的に閉じられるファイル記述子(ここでは1、つまりstdout)も指定します。addup2はと同様の効果がありますdup2()
。つまり、ターゲットファイル記述子(ここでは2、つまりstderr)は、1が2に複製される前にアトミックに閉じられます。これらのアクションはposix_spawn
、によって作成された子でのみ実行されます。つまり、指定されたコマンドを実行する直前です。
のようfork()
にposix_spawn()
、posix_spawnp()
すぐに親に戻ります。したがって、を使用するwaitid()
かwaitpid()
、child_pid
の終了を明示的に待機する必要があります。
posix_spwan
は、型のポインターposix_spawn_file_actions_t
(として指定したものNULL
)です。オブジェクトposix_spawn
によって指定された呼び出しプロセスから継承されたファイル記述子を開く、閉じる、または複製しますposix_spawn_file_actions_t
。posix_spawn_file_actions_{addclose,adddup2}
関数がどのFDに何が起こるかを示すために使用されています。