大多数的IDE环境都具备这样一种功能,加载编译器编译好程序并执行,执行结果显示于IDE环境中的结果信息窗口,那么它是如何捕获程序运行结果的呢?其实简单地用dup/dup2重定位输出并通过管道获取该输出就可以达到这种效果。#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
int
main(int argc, char **argv) { int fd[2]; pid_t childpid;
if (pipe(fd) == -1) { printf("%s: %d -- Create pipe error: %s\n", __FILE__, __LINE__, strerror(errno)); exit(errno); }
childpid = fork();
if (childpid == -1) { printf("%s: %d -- fork error: %s\n", __FILE__, __LINE__, strerror(errno)); exit(errno); }
if (childpid == 0) { close(fd[0]);
if (dup2(fd[1], STDOUT_FILENO) == -1) { printf("%s: %d -- dup2 error: %s\n", __FILE__, __LINE__, strerror(errno)); exit(errno); }
if (execlp("ls", "ls", "/", NULL) == -1) { printf("%s: %d -- execlp error: %s\n", __FILE__, __LINE__, strerror(errno)); exit(errno); }
exit(0); } else
{
char buff[4096];
close(fd[1]); memset(buff, sizeof(buff), 0);
printf("read %d bytes\n", read(fd[0], buff, sizeof(buff))); printf("output: %s\n", buff);
exit(0); } }
以下代码则相反,重定向输入:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
int
main(int argc, char **argv) { int fd[2]; pid_t childpid;
if (pipe(fd) == -1) { printf("%s: %d -- Create pipe error: %s\n", __FILE__, __LINE__, strerror(errno)); exit(errno); }
childpid = fork();
if (childpid == -1) { printf("%s: %d -- fork error: %s\n", __FILE__, __LINE__, strerror(errno)); exit(errno); }
if (childpid == 0) { close(fd[1]); if (dup2(fd[0], STDIN_FILENO) == -1) { printf("%s: %d -- dup2 error: %s\n", __FILE__, __LINE__, strerror(errno)); exit(errno); }
if (execlp("xargs", "xargs", "ls", NULL) == -1) { printf("%s: %d -- execlp error: %s\n", __FILE__, __LINE__, strerror(errno)); exit(errno); }
exit(0); } else
{
int status;
close(fd[0]); write(fd[1], "/", 1);
printf("waitpid result: %d\n", waitpid(childpid, &status, WNOHANG)); printf("status value: %d\n", status);
if (WIFEXITED(status)) printf("child process was terminated normally by calling exit or _exit\n"); else if (WEXITSTATUS(status)) printf("returns the exit status of the child by exit or _exit\n"); else if (WIFSIGNALED(status)) printf("child process was terminated by a signal\n"); else if (WTERMSIG(status)) printf("returns the number of the signal that caused the child process to terminate\n"); else if (WCOREDUMP(status)) printf("child produced a core dump\n"); else if (WIFSTOPPED(status)) printf("child process was stopped by delivery of a signal\n"); else if (WSTOPSIG(status)) printf("retuns the number of the signal which caused the child to stop\n"); else if (WIFCONTINUED(status)) printf("child process was resumed by delivery of SIGCONT\n"); exit(0); } }
|