This commit is contained in:
Pan Qiancheng 2025-03-26 16:02:52 +08:00
parent 4f81d28174
commit 3139e359a8
2 changed files with 63 additions and 20 deletions

View File

@ -114,29 +114,72 @@ void write_log(const char *filename, char *const argv[]) {
// 复制标准输出和错误输出到日志文件
void duplicate_output_to_log() {
int log_fd = open(LOG_OUT_FILE, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (log_fd < 0) return;
int stdout_pipe[2], stderr_pipe[2];
int stdout_copy = dup(STDOUT_FILENO);
int stderr_copy = dup(STDERR_FILENO);
dup2(log_fd, STDOUT_FILENO);
dup2(log_fd, STDERR_FILENO);
close(log_fd);
// 让 stdout 和 stderr 同时输出到日志文件和控制台
FILE *log_file = fdopen(log_fd, "a");
if (log_file) {
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(stderr, NULL, _IOLBF, 0);
stdout = log_file;
stderr = log_file;
// 创建 stdout 和 stderr 的管道
if (pipe(stdout_pipe) < 0 || pipe(stderr_pipe) < 0) {
perror("pipe");
return;
}
dup2(stdout_copy, STDOUT_FILENO);
dup2(stderr_copy, STDERR_FILENO);
close(stdout_copy);
close(stderr_copy);
pid_t pid = fork();
if (pid < 0) {
perror("fork");
return;
}
if (pid == 0) { // 子进程
close(stdout_pipe[1]); // 关闭 stdout 写端
close(stderr_pipe[1]); // 关闭 stderr 写端
// 打开日志文件(追加模式)
int log_fd = open(LOG_OUT_FILE, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (log_fd < 0) {
perror("open log file");
exit(1);
}
// 让 tee 进程读取 stdout_pipe[0] 并写入日志和终端
dup2(stdout_pipe[0], STDIN_FILENO);
dup2(log_fd, STDOUT_FILENO);
execlp("tee", "tee", "/dev/tty", NULL);
perror("execlp tee stdout");
exit(1);
}
pid_t pid_err = fork();
if (pid_err < 0) {
perror("fork");
return;
}
if (pid_err == 0) { // 另一个子进程
close(stderr_pipe[1]); // 关闭 stderr 写端
int log_fd = open(LOG_OUT_FILE, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (log_fd < 0) {
perror("open log file");
exit(1);
}
// 让 tee 进程读取 stderr_pipe[0] 并写入日志和终端
dup2(stderr_pipe[0], STDIN_FILENO);
dup2(log_fd, STDOUT_FILENO);
execlp("tee", "tee", "/dev/tty", NULL);
perror("execlp tee stderr");
exit(1);
}
// 父进程
close(stdout_pipe[0]); // 关闭 stdout 读端
close(stderr_pipe[0]); // 关闭 stderr 读端
// 让标准输出、错误输出流向管道
dup2(stdout_pipe[1], STDOUT_FILENO);
dup2(stderr_pipe[1], STDERR_FILENO);
close(stdout_pipe[1]); // 关闭写端(子进程 tee 负责处理)
close(stderr_pipe[1]);
}

Binary file not shown.