我正在制作一个基本上模仿的程序
find $1 -name '*'.[ch] | xargs grep -c $2 | sort -t : +1.0 -2.0 --numeric --reverse | head --lines=$3
该程序将分为4个子进程,第一个的输出是下一个的输入。现在它说我的pipe12和pipe23没有声明。他们显然是,但我不确定他们是否可能在错误的地方或其他事情正在发生。任何帮助是极大的赞赏。对不起所有奇怪的注释块。
[cs@cycle2 ipc]$ make clean
rm -f finder pipe tmp1 tmp2
[cs@cycle2 ipc]$ make build
gcc -Wall -g finder.c -o finder
finder.c: In function ‘main’:
finder.c:45:15: error: ‘pipe12’ undeclared (first use in this function)
if ((dup2(pipe12[1], 1)) < 0){
^
finder.c:45:15: note: each undeclared identifier is reported only once for each function it appears in
finder.c:95:15: error: ‘pipe23’ undeclared (first use in this function)
if ((dup2(pipe23[1], 1)) < 0){
^
finder.c:73:11: warning: unused variable ‘count’ [-Wunused-variable]
ssize_t count;
^
make: *** [build] Error 1
[cs@cycle2 ipc]$ vim finder.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <errno.h>
#include <sys/wait.h>
#define BSIZE 256
#define BASH_EXEC "/bin/bash"
#define FIND_EXEC "/bin/find"
#define XARGS_EXEC "/usr/bin/xargs"
#define GREP_EXEC "/bin/grep"
#define SORT_EXEC "/bin/sort"
#define HEAD_EXEC "/usr/bin/head"
int main(int argc, char *argv[]){
int status;
pid_t pid_1, pid_2, pid_3, pid_4;
// int pipe(int pipe12[2]),pipe(int pipe23[2]),pipe(int pipe34[2]);
int pipe(int pipe12[2]);
int pipe(int pipe23[2]);
if (argc != 4) {
printf("usage: finder DIR STR NUM_FILES\n");
exit(0);
}
pid_1 = fork();
if (pid_1 == 0) {
/* First Child */
char cmdbuf[BSIZE];
bzero(cmdbuf, BSIZE);
sprintf(cmdbuf, "%s %s -name \'*\'.[ch]",FIND_EXEC, argv[1]);
if ((dup2(pipe12[1], 1)) < 0){
perror("pipe12 broke in process 1");
exit(-1);
}
close(pipe12[1]);
close(pipe12[0]);
if ( (execl(BASH_EXEC, BASH_EXEC, "-c", cmdbuf, (char *) 0)) < 0) {
fprintf(stderr, "\nError execing find. ERROR#%d\n", errno);
return EXIT_FAILURE;
}
/*
if((execl("/usr/bin/find","find","-name","*.[ch]", (char *)NULL)) < 0){
perror("execl 1 didn't work. child 1");
exit(-1);
}
*/
exit(0);
}
//----------------------------------------------------------------------
char buffer;
ssize_t count;
pid_2 = fork();
if (pid_2 == 0) {
/* Second Child */
if ( (read(pipe12[0], &buffer, 1))< 0){
perror("read broke in pipe12 process 2");
exit(-1);
}
if ((dup2(pipe12[0],0)) < 0){
perror("");
exit(-1);
}
close(pipe12[1]);
close(pipe12[0]);
char cmdbuf[BSIZE];
bzero(cmdbuf, BSIZE);
sprintf(cmdbuf, "%s %s -c %s ",XARGS_EXEC, GREP_EXEC, argv[1]);
if ((dup2(pipe23[1], 1)) < 0){
perror("pipe23 broke in process 2");
exit(-1);
}
close(pipe23[1]);
close(pipe23[0]);
if((execl(BASH_EXEC, BASH_EXEC, "-c", cmdbuf, (char *) 0)) < 0){
fprintf(stderr, "\nError execing find. ERROR#%d\n", errno);
return EXIT_FAILURE;
}
/*
if((execl("/usr/bin/xargs","grep","-c",argv[1], (char *)NULL))< 0){
perror("execl 2 didn't work. child 2");
exit(-1);
}
*/
exit(0);
}
//----------------------------------------------------------------------
pid_3 = fork();
if (pid_3 == 0) {
/* Third Child */
exit(0);
}
//----------------------------------------------------------------------
pid_4 = fork();
if (pid_4 == 0) {
/* Fourth Child */
exit(0);
}
//----------------------------------------------------------------------
if ((waitpid(pid_1, &status, 0)) == -1) {
fprintf(stderr, "Process 1 encountered an error. ERROR%d", errno);
return EXIT_FAILURE;
}
if ((waitpid(pid_2, &status, 0)) == -1) {
fprintf(stderr, "Process 2 encountered an error. ERROR%d", errno);
return EXIT_FAILURE;
}
if ((waitpid(pid_3, &status, 0)) == -1) {
fprintf(stderr, "Process 3 encountered an error. ERROR%d", errno);
return EXIT_FAILURE;
}
if ((waitpid(pid_4, &status, 0)) == -1) {
fprintf(stderr, "Process 4 encountered an error. ERROR%d", errno);
return EXIT_FAILURE;
}
return 0;
}
答案 0 :(得分:1)
这一点:
int pipe(int pipe12[2]);
int pipe(int pipe23[2]);
声明两次函数pipe
接受一个包含两个整数的数组。 1 相反,我假设您要声明两个int
的两个数组并调用{{1}用它们作为参数。如果用
pipe
它编译,这部分程序将起作用。我没有检查过程序的其余部分。
1 实际上是一个函数// declare two arrays of two ints each called pipe12 and pipe23
int pipe12[2];
int pipe23[2];
// call pipe with them.
pipe(pipe12);
pipe(pipe23);
,它接受指向pipe
的指针,原因对此并不十分重要。如果你感兴趣:数组不能是函数参数,但指向它们的元素的指针可以,并且因此在标准中有一个特殊的规则,即函数的参数列表中的数组声明符具有含义指向声明的数组类型的元素的指针。长话短说:int
相当于int pipe(int foo[2]);
。