Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-内部带有fork()/pipe()的WHILE循环_C_Exec_Fork_Pipe_Parent Child - Fatal编程技术网

C-内部带有fork()/pipe()的WHILE循环

C-内部带有fork()/pipe()的WHILE循环,c,exec,fork,pipe,parent-child,C,Exec,Fork,Pipe,Parent Child,我有一个问题,我必须实现一个键盘记录器到我们在课堂上制作的shell中。在创建子进程并运行execlp()后,在while循环中使程序流继续循环时遇到问题 这是一个简单的程序,我已经做了工作的一部分,我有麻烦。。我的主程序pipe.c包含一个带有while循环的父/子进程,该循环“应该”使用fgets()继续从用户处获取输入,创建一个子进程,使用dup2(),写入stdout,然后子进程调用receive.c可执行文件,该可执行文件将从stdin获取输入并显示它 /* file: pipe.c

我有一个问题,我必须实现一个键盘记录器到我们在课堂上制作的shell中。在创建子进程并运行execlp()后,在while循环中使程序流继续循环时遇到问题

这是一个简单的程序,我已经做了工作的一部分,我有麻烦。。我的主程序pipe.c包含一个带有while循环的父/子进程,该循环“应该”使用fgets()继续从用户处获取输入,创建一个子进程,使用dup2(),写入stdout,然后子进程调用receive.c可执行文件,该可执行文件将从stdin获取输入并显示它

/* file: pipe.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main() {
  int key_logger_on = 0;
  int p[2];
  pid_t pid;
  char str[256];
  char input[1024];
  int status;
  char * file = "test.txt";

  printf("Input :: ");
  while(fgets(input, sizeof(input), stdin)) {

    if (pipe(p)==-1) {
      perror("Pipe create error");
      exit(1);
    }

    if ((pid=fork())==-1) {
      perror("Fork create error");
      exit(1);
    }

    if (pid==0) {
      close(p[1]);  // Close write
      dup2(p[0],0);
      close(p[0]);
      execlp("receive",file,NULL);
   }

    else {
      close(p[0]);  // Close read
      fflush(stdout);
      dup2(p[1],1);
      close(p[1]);
      write(1, input, strlen(input)+1);
      waitpid(pid, NULL, 0);
    }
    printf("Input :: ");
  }
}
/*文件:pipe.c*/
#包括
#包括
#包括
#包括
#包括
#包括
int main(){
int key_logger_on=0;
int p[2];
pid_t pid;
char-str[256];
字符输入[1024];
智力状态;
char*file=“test.txt”;
printf(“输入::”);
while(fgets(input,sizeof(input),stdin)){
如果(管道(p)=-1){
perror(“管道创建错误”);
出口(1);
}
如果((pid=fork())=-1){
perror(“Fork创建错误”);
出口(1);
}
如果(pid==0){
关闭(p[1]);//关闭写入
dup2(p[0],0);
接近(p[0]);
execlp(“接收”,文件,空);
}
否则{
关闭(p[0]);//关闭读取
fflush(stdout);
dup2(p[1],1);
关闭(p[1]);
写入(1,输入,strlen(输入)+1);
waitpid(pid,NULL,0);
}
printf(“输入::”);
}
}
下面是简单的receive.c,它获取输入的stdin并显示它。该文件只是传递参数的测试

/* file: receive.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  char input[256];
  fgets(input, sizeof(input), stdin);
  printf("FILE: %s  RECEIVE: %s", argv[0],input);
  return 0;
}
/*文件:receive.c*/
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
字符输入[256];
fgets(输入,sizeof(输入),标准输入);
printf(“文件:%s接收:%s”,argv[0],输入);
返回0;
}

现在,所有这些对我来说都是第一次运行时,它获取输入,将其发送到stdout,子调用receive,打印出输入,然后整个父程序退出,while循环被忽略,一切都结束了。我对叉子和管子很陌生,所以处理这件事很令人沮丧!甚至让我第一次在这里发帖!事先非常感谢

今天做这件事是作为我的重复任务。检查此代码。我也用你的接收机测试过:

#define PREAD 0
#define PWRITE 1

/*
 * 
 */

    int main(int argc, char** argv) {

        int key_logger_on = 0;
        int pIn[2];
        int pOut[2]; 
        pid_t pid;
        char str[256];
        char input[1024] = "";
        int status;

        char file[] = "test.txt";
        char buf;
        printf("Input :: ");
        while (fgets(input,sizeof(input),stdin)) {

            char nChar;
            int nResult;

            if (pipe(pIn) < 0) {
                perror("allocating pipe for child input redirect");
                return -1;
            }
            if (pipe(pOut) < 0) {
                close(pIn[PREAD]);
                close(pIn[PWRITE]);
                perror("allocating pipe for child output redirect");
                return -1;
            }

            pid = fork();
            if ( pid==0) {
                // child continues here

                // redirect stdin
                if (dup2(pIn[PREAD], 0) == -1) {
                    perror("stdin");
                    return -1;
                }

                // redirect stdout
                if (dup2(pOut[PWRITE], 1) == -1) {
                    perror("stdout");
                    return -1;
                }

                // redirect stderr
                if (dup2(pOut[PWRITE], 2) == -1) {
                    perror("stderr");
                    return -1;
                }

                // all these are for use by parent only
                close(pIn[PREAD]);
                close(pIn[PWRITE]);
                close(pOut[PREAD]);
                close(pOut[PWRITE]);

                // run child process image
                nResult = execl("receive",file,NULL);

                exit(nResult);
            } else if (pid > 0) {
                // parent continues here

                // close unused file descriptors, these are for child only
                close(pIn[PREAD]);
                close(pOut[PWRITE]);

                write(pIn[PWRITE], input, strlen(input));

                // char by char reading
                while (read(pOut[PREAD], &nChar, 1) == 1) {
                    write(STDOUT_FILENO, &nChar, 1);
                }

                // close we done
                close(pIn[PWRITE]);
                close(pOut[PREAD]);
            }
            printf("Input :: ");
        }
    }
#定义序言0
#定义PWRITE 1
/*
* 
*/
int main(int argc,字符**argv){
int key_logger_on=0;
int引脚[2];
int pOut[2];
pid_t pid;
char-str[256];
字符输入[1024]=“”;
智力状态;
字符文件[]=“test.txt”;
焦炉;
printf(“输入::”);
while(fgets(input,sizeof(input),stdin)){
查恩查尔;
结果;
如果(管道(销)<0){
perror(“为子输入重定向分配管道”);
返回-1;
}
如果(管道(撅嘴)<0){
关闭(引脚[PREAD]);
关闭(引脚[PWRITE]);
perror(“为子输出重定向分配管道”);
返回-1;
}
pid=fork();
如果(pid==0){
//孩子继续在这里
//重定向标准
如果(dup2(引脚[PREAD],0)=-1){
佩罗尔(“标准数据”);
返回-1;
}
//重定向标准输出
if(dup2(pOut[PWRITE],1)=-1){
佩罗尔(“stdout”);
返回-1;
}
//重定向标准
if(dup2(pOut[PWRITE],2)=-1){
佩罗尔(“stderr”);
返回-1;
}
//所有这些仅供家长使用
关闭(引脚[PREAD]);
关闭(引脚[PWRITE]);
关闭(撅嘴[前置]);
关闭(撅嘴[PWRITE]);
//运行子进程映像
nResult=execl(“接收”,文件,空);
退出(nResult);
}否则,如果(pid>0){
//家长继续在这里
//关闭未使用的文件描述符,这些描述符仅适用于儿童
关闭(引脚[PREAD]);
关闭(撅嘴[PWRITE]);
写入(引脚[PWRITE],输入,strlen(输入));
//逐字符读取
while(读取(pOut[PREAD],&nChar,1)==1){
写入(标准文件号和nChar,1);
}
//接近完成
关闭(引脚[PWRITE]);
关闭(撅嘴[前置]);
}
printf(“输入::”);
}
}

今天我把它作为重复任务来做。检查此代码。我也用你的接收机测试过:

#define PREAD 0
#define PWRITE 1

/*
 * 
 */

    int main(int argc, char** argv) {

        int key_logger_on = 0;
        int pIn[2];
        int pOut[2]; 
        pid_t pid;
        char str[256];
        char input[1024] = "";
        int status;

        char file[] = "test.txt";
        char buf;
        printf("Input :: ");
        while (fgets(input,sizeof(input),stdin)) {

            char nChar;
            int nResult;

            if (pipe(pIn) < 0) {
                perror("allocating pipe for child input redirect");
                return -1;
            }
            if (pipe(pOut) < 0) {
                close(pIn[PREAD]);
                close(pIn[PWRITE]);
                perror("allocating pipe for child output redirect");
                return -1;
            }

            pid = fork();
            if ( pid==0) {
                // child continues here

                // redirect stdin
                if (dup2(pIn[PREAD], 0) == -1) {
                    perror("stdin");
                    return -1;
                }

                // redirect stdout
                if (dup2(pOut[PWRITE], 1) == -1) {
                    perror("stdout");
                    return -1;
                }

                // redirect stderr
                if (dup2(pOut[PWRITE], 2) == -1) {
                    perror("stderr");
                    return -1;
                }

                // all these are for use by parent only
                close(pIn[PREAD]);
                close(pIn[PWRITE]);
                close(pOut[PREAD]);
                close(pOut[PWRITE]);

                // run child process image
                nResult = execl("receive",file,NULL);

                exit(nResult);
            } else if (pid > 0) {
                // parent continues here

                // close unused file descriptors, these are for child only
                close(pIn[PREAD]);
                close(pOut[PWRITE]);

                write(pIn[PWRITE], input, strlen(input));

                // char by char reading
                while (read(pOut[PREAD], &nChar, 1) == 1) {
                    write(STDOUT_FILENO, &nChar, 1);
                }

                // close we done
                close(pIn[PWRITE]);
                close(pOut[PREAD]);
            }
            printf("Input :: ");
        }
    }
#定义序言0
#定义PWRITE 1
/*
* 
*/
int main(int argc,字符**argv){
int key_logger_on=0;
int引脚[2];
int pOut[2];
pid_t pid;
char-str[256];
字符输入[1024]=“”;
智力状态;
字符文件[]=“test.txt”;
焦炉;
printf(“输入::”);
while(fgets(input,sizeof(input),stdin)){
查恩查尔;
结果;
如果(管道(销)<0){
perror(“为子输入重定向分配管道”);
返回-1;
}
如果(管道(撅嘴)<0){
关闭(引脚[PREAD]);
关闭(引脚[PWRITE]);
perror(“为子输出重定向分配管道”);
返回-1;
}
pid=fork();
如果(pid==0){
//孩子继续在这里
//重定向标准
如果(dup2(引脚[PREAD],0)=-1){
佩罗尔(“标准数据”);
返回-1;
}
//重定向标准输出
if(dup2(pOut[PWRITE],1)=-1){
佩罗尔(“stdout”