【问题标题】:C - WHILE Loop with fork() / pipe() insideC - 内部带有 fork() / pipe() 的 WHILE 循环
【发布时间】:2013-05-11 12:25:05
【问题描述】:

我有一个问题,我必须在课堂上制作的 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 :: ");
  }
}

这里是简单的receive.c,它获取输入的标准输入并显示它。该文件只是一个传递参数的测试。

/* 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;
}

现在,这对我来说只是第一次运行时,它获取输入,将其发送到 stdout,子调用接收,打印出输入,然后整个父程序退出,while 循环被忽略,一切才刚刚结束。我对叉子和管道很陌生,所以处理起来非常令人沮丧!甚至让我第一次在这里发布问题!非常感谢您提前。

【问题讨论】:

    标签: c exec fork pipe parent-child


    【解决方案1】:

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

    #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 :: ");
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2015-07-16
      • 2015-11-08
      • 2021-12-28
      • 1970-01-01
      • 2018-10-04
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 2014-08-06
      相关资源
      最近更新 更多