[英]C Unix Pipes Example
試圖實現一個shell,主要是管道。 我已經編寫了這個測試用例,我希望將其簡單地傳遞給wc ......它肯定不能按預期工作。 它將ls打印到終端然后打印耗盡的內存。 我很失落如何解決這個問題並讓它發揮作用。 find_path適用於我的所有測試。
編輯 - 我必須使用execv為項目,它是一個類的東西,但我已經嘗試使用execvp以防萬一,它完全相同的事情。 這也只是一個例子,一個測試,看看為什么它不起作用,我為fork和waitpid調用fork兩次,因為我沒有別的事可做。
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
int find_path(char* execname, char** dst)
{
char *path = getenv("PATH");
path = strdup(path);
char *pos;
path = strtok_r(path, ":", &pos);
char *originalpath = path;
do
{
char* test = (char*)calloc(strlen(path) + strlen(execname) + 2, sizeof(char));
test = strcpy(test, path);
int testlen = strlen(test);
(*(test+testlen)) = '/';
strcpy(test + testlen + 1,execname);
struct stat buf;
int result = stat(test, &buf);
if (result == 0)
{
*dst = test;
free (originalpath);
return 1;
}
else
{
free(test);
}
} while ((path = strtok_r(NULL, ":", &pos)) != NULL);
free(originalpath);
return 0;
}
int main()
{
char *cmd1 = "ls";
char *cmd2 = "wc";
int filedes[2];
pipe(filedes);
char** argv = (char**)calloc(1, sizeof(char*));
argv[0] = (char*)malloc(sizeof(char*));
argv[0] = NULL;
pid_t pid = fork();
if (pid == 0)
{
char *path;
find_path(cmd1, &path);
dup2(filedes[1],stdout);
execv(path,argv);
}
pid = fork();
if (pid == 0)
{
dup2(filedes[0], stdin);
char *path;
find_path(cmd2, &path);
execv(path, argv);
}
else
waitpid(pid);
}
通常,當調試程序很困難時,最好將其簡化一點以消除錯誤來源。 這是你的程序,簡化為刪除find_path
作為錯誤來源:
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
int main(void)
{
int filedes[2];
pipe(filedes);
/* Run LS. */
pid_t pid = fork();
if (pid == 0) {
/* Set stdout to the input side of the pipe, and run 'ls'. */
dup2(filedes[1], 1);
char *argv[] = {"ls", NULL};
execv("/bin/ls", argv);
} else {
/* Close the input side of the pipe, to prevent it staying open. */
close(filedes[1]);
}
/* Run WC. */
pid = fork();
if (pid == 0) {
dup2(filedes[0], 0);
char *argv[] = {"wc", NULL};
execv("/usr/bin/wc", argv);
}
/* Wait for WC to finish. */
waitpid(pid);
}
這應該像你期望的那樣。
在簡化過程中,出現了一些錯誤:
argv[]
沒有正確設置,特別是argv [0]被設置為NULL; ls
的管道輸入端。 當ls
完成時,管道沒有被關閉(因為wc
過程仍然打開它),防止wc
完成。 stdout
和stdin
(類型為FILE*
)與文件描述符號0
和1
(由dup
, pipe
等使用)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.