diff --git a/execve_intercept.c b/execve_intercept.c index 2a55b58..a9a4918 100644 --- a/execve_intercept.c +++ b/execve_intercept.c @@ -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]); } diff --git a/intercept.so b/intercept.so index 8913496..e05f950 100755 Binary files a/intercept.so and b/intercept.so differ