通过C中的管道向bc写一个术语

我遇到了这个C练习的问题。 任务是创建两个进程。 这两个管道连接两个管道,终止于孩子的stdin和stdout。 然后用bc替换子进程。 然后我应该从父进程到子进程(bc)写一个术语(例如1 + 2)。

管道正在做他们应该做的事情,但是,bc似乎不喜欢输入。 当我写入管道时,bc会响应以下多行:

(standard_in) 1: illegal character: ^@ 

到目前为止这是我的解决方案:

 #include  #include  #include  #include  int main(int argc, char *argv[]) { /*Create two pipes: One from parent to child (pipe_pc) and one from child to parent (pipe_cp). */ int pipe_pc[2], pipe_cp[2]; int cid; if (pipe(pipe_pc) == -1 || pipe(pipe_cp) == -1) { printf("Could not pipe\n"); exit(EXIT_FAILURE); } // Create child process cid = fork(); if (cid == -1) { printf("Could not fork.\n"); exit(EXIT_FAILURE); } // Child process if (cid == 0) { // Redirect pipes close(STDOUT_FILENO); close(STDIN_FILENO); close(pipe_pc[1]); // Close writing end close(pipe_cp[0]); // Close reading end dup2(pipe_pc[0], STDIN_FILENO); // Take stdin from parent dup2(pipe_cp[1], STDOUT_FILENO); // Give stdout to parent int err; // Replace child with bc err = execl("/usr/bin/bc", "bc --quiet", (char*) NULL); printf("%s %d\n", "Could not start bc:", err); exit(err); } // Parent Process else { char input[128] = ""; char buffer[128] = ""; printf("%s\n", "Parent process running"); // Copy argv to a single string for(int i=1; i < argc; i++) { strcat(input, argv[i]); } // Write the input to the child's stdin write(pipe_pc[1], input, sizeof(input); // Read the child's stdout read(pipe_cp[0], buffer, sizeof(buffer)); printf("Result: %s\n", buffer); return 0; } } 

非常感谢提示和帮助,提前感谢!

问题是你没有在管道中正确写入,所以bc收到了错误的输入。

我改写了else分支。

如果您不确定在管道中发送了什么,请使用0(i / o fd)临时替换管道描述符,并直观地检查您的操作。

 #include  #include  #include  #include  int main(int argc, char *argv[]) { /* Create two pipes: One from parent to child (pipe_pc) and one from child to parent (pipe_cp). */ int pipe_pc[2], pipe_cp[2]; int cid; if (pipe(pipe_pc) == -1 || pipe(pipe_cp) == -1) { printf("Could not pipe\n"); exit(EXIT_FAILURE); } // Create child process cid = fork(); if (cid == -1) { printf("Could not fork.\n"); exit(EXIT_FAILURE); } // Child process if (cid == 0) { // Redirect pipes close(STDOUT_FILENO); close(STDIN_FILENO); close(pipe_pc[1]); // Close writing end close(pipe_cp[0]); // Close reading end dup2(pipe_pc[0], STDIN_FILENO); // Take stdin from parent dup2(pipe_cp[1], STDOUT_FILENO); // Give stdout to parent int err; // Replace child with bc err = execl("/usr/bin/bc", "bc --quiet", (char*) NULL); printf("%s %d\n", "Could not start bc:", err); exit(err); } // Parent Process else { char buffer[128] = ""; // printf("%s\n", "Parent process running"); for(int i=1; i < argc; i++) write(pipe_pc[1], argv[i], strlen(argv[i])); write(pipe_pc[1], "\n", 1); read(pipe_cp[0], buffer, sizeof(buffer)); printf("Result: %s\n", buffer); return 0; } } 

您的代码有很多未定义的行为。


 write(pipe_pc[1], input, sizeof(input); 

你编写所有输入数组。 但是你只需要用strcat()编写你复制的东西。 使用strlen。

 write(pipe_pc[1], input, strlen(input)); 

 strcat(input, argv[i]); 

在这里你应该validation你不超过128个八位字节。

 if (strlen(input) + strlen(argv[i]) + 1 > 128) { break; } strcat(input, argv[i]); 

 read(pipe_cp[0], buffer, sizeof(buffer)); 

在这里,您不validation缓冲区是否是有效的c字符串。

 ssize_t ret = read(pipe_cp[0], buffer, sizeof(buffer) - 1); if (ret < 0) return 1; buffer[ret] = '\0'; 

你忘了关闭父管道

 close(pipe_pc[0]); close(pipe_cp[1]); 

在你的读/写之后

 close(pipe_pc[1]); close(pipe_cp[0]); 

你忘了在dup2()之后关闭孩子的管道

 close(pipe_pc[1]); close(pipe_cp[0]); 

在dup2之前你不需要关闭旧的fd,他会为你做。 你不检查dup2()错误

Interesting Posts