[英]Does redirecting standard output in a child process do so for the parent process as well?
我正在星期二學習OS考試。 為了准備,我試圖通過C程序模擬命令行管道。
該計划非常簡單。 我制作一個管道,然后分叉一個子進程。
子進程將標准輸出重定向到管道的寫入端,關閉管道的文件描述符,然后執行命令(在本例中為ls
)。
父進程等待子進程退出,將標准輸入重定向到管道的讀取端,關閉管道的文件描述符,然后執行命令(在本例中為grep 'school'
)。
當我使用ls | grep 'school'
通過命令行執行命令時 ls | grep 'school'
有一行說“school”打印到標准輸出,這是有道理的,因為目錄中有一個目錄,我正在運行該命名的程序。
當我運行我創建的程序時,我沒有收到任何錯誤消息,但它不會產生任何輸出。
我唯一可以想到的就是阻止它工作的是,在子進程中重定向標准輸出會以某種方式影響父進程命令的輸出,但我幾乎肯定不應該這樣。
這是代碼:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main() {
int fds[2];
int pipe_val, close_val, write_val, dup_val, status;
pid_t pid;
char *error;
pipe_val = pipe(fds);
if (pipe_val) {
fprintf(stderr, "Failed to prepare pipe.\n");
return -1;
}
pid = fork();
if (pid == -1) {
fprintf(stderr, "Failed to fork a child process.\n");
return -1;
} else if (pid == 0) {
dup_val = dup2(fds[1], STDOUT_FILENO);
if (dup_val) {
error = strerror(errno);
fprintf(stderr, "Failed to redirect standard output in child process because %s\n", error);
exit(1);
}
close_val = close(fds[0]);
if (close_val) {
fprintf(stderr, "Failed to close read-end of pipe in child process.\n");
exit(1);
}
close_val = close(fds[1]);
if (close_val) {
fprintf(stderr, "Failed to close write-end of pipe in child process.\n");
exit(1);
}
execl("/bin/ls", "ls", NULL);
fprintf(stderr, "Failed to execute command in child process.\n");
exit(1);
} else {
wait(&status);
dup_val = dup2(fds[0], STDIN_FILENO);
if (dup_val) {
error = strerror(errno);
fprintf(stderr, "Failed to redirect standard input in parent process because %s.\n", error);
return -1;
}
close_val = close(fds[0]);
if (close_val) {
fprintf(stderr, "Failed to close read-end of the pipe in the parent process.\n");
return -1;
}
close_val = close(fds[1]);
if (close_val) {
fprintf(stderr, "Failed to close write-end of the pipe in the parent process.\n");
return -1;
}
execl("/bin/grep", "grep", "school", NULL);
fprintf(stderr, "Failed to execute the command in the parent process.\n");
return -1;
}
}
您的第一個問題是您沒有為您正在使用的功能包含所有必需的標題。 strerror
需要<string.h>
並且wait
需要<sys/wait.h>
。
如果您正在使用gcc -Wall
進行編譯,請始終使用gcc -Wall
並閱讀警告。 在這種情況下,它會抱怨隱含的strerror
聲明。
因為未聲明strerror
,編譯器會假定它返回一個int
,這是錯誤的。 如果您在64位Linux x86上運行該程序,則int
與strerror
返回的指針的大小不同 。 當你將strerror
的結果以%s
格式傳遞給fprintf
時,這會成為一個致命的問題,因為指針被誤解為int,然后轉換回指針,最后是偽造的值。 fprintf
錯誤,你永遠不會看到你的錯誤信息。
包含正確的標題,您將看到一條錯誤消息,該消息將引導您解決下一個需要解決的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.