Vâng, bạn có thể. Xác định đúng danh sách các hành động tập tin sinh sản posix chắc chắn là cách để đi.
Thí dụ:
#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;
}
Biên dịch và kiểm tra:
$ 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
Lưu ý rằng các posix_spawn
hàm không đặt errno, thay vào đó, không giống như hầu hết các hàm UNIX khác, chúng trả về mã lỗi. Vì vậy, chúng ta không thể sử dụng perror()
mà phải sử dụng một cái gì đó như strerror()
.
Chúng tôi sử dụng hai hành động tập tin sinh sản: addopen và addup2. Addopen tương tự như bình thường open()
nhưng bạn cũng chỉ định một bộ mô tả tệp sẽ tự động đóng nếu đã mở (ở đây 1, tức là thiết bị xuất chuẩn). Addup2 có các hiệu ứng tương tự dup2()
, tức là bộ mô tả tệp đích (ở đây 2, tức là stderr) được đóng nguyên tử trước khi 1 được sao chép thành 2. Các hành động đó chỉ được thực hiện trong con được tạo bởi posix_spawn
, tức là ngay trước khi nó thực thi lệnh được chỉ định.
Thích fork()
, posix_spawn()
và posix_spawnp()
ngay lập tức trở về với cha mẹ. Vì vậy, chúng tôi phải sử dụng waitid()
hoặc waitpid()
chờ đợi một cách rõ ràng về việc child_pid
chấm dứt.
posix_spwan
là một con trỏ kiểuposix_spawn_file_actions_t
(một bạn đã cho làNULL
).posix_spawn
sẽ mở, đóng hoặc sao chép mô tả tệp được kế thừa từ quá trình gọi theo quy định củaposix_spawn_file_actions_t
đối tượng. Cácposix_spawn_file_actions_{addclose,adddup2}
chức năng được sử dụng để chỉ ra những gì xảy ra với fd.