0

所以代码是这样的:

int main () 
{
  int pid, fd[2], i, j;
  char comanda[1000], comm[100][100], *var, *var2, vect[100][100], text[1000], check[10000];
  if(pipe(fd)<0) 
  {
    perror("pipe error");
    exit(1);
  }
  if((pid = fork()) < 0 ) 
  {
    perror("fork error");
    exit(1);
  }
  j = 0;
  if(pid){ 
      do {
        if( j > 0) fgets (check , 1000 , stdin); //just in case there's still something in the buffer
        printf("enter command: \n");
        scanf("%[^\t\n]", comanda);
        if(var = strtok(comanda, " "))
        {
          i=0;
          while(var != NULL)
          {
            strcpy(vect[i], var);
            var = strtok(NULL, " ");
            i++;
          }
        }
        else
          strcpy(vect[0], comanda);
        if(strcmp(vect[0], "login") == 0)
        {
            write(fd[1], "login ", 6);
            write(fd[1], vect[1], strlen(vect[1]));
            printf("I got login");
        }
        else if(strcmp(vect[0], "quit") == 0)
        {
          exit(1);
        }
        else
          printf("I got the command %s \n", vect[0]);
        j++;
      } while(1);
      close(fd[0]);
      close(fd[1]);
      wait(NULL);
  }
  else
  {
      close(fd[1]); 
      printf("copil? \n");
      int i=0;
      read(fd[0], text, sizeof(text));
      var2 = strtok(text, " ");
      j=0;
      while(var2 != NULL)
      {
        strcpy(comm[j], var2);
        var2 = strtok(NULL, " ");
        j++;
      }
      if( strcmp(comm[0], "login") == 0)
      {
          //comanda e login, deci verificam username-ul. 
          if(login(comm[1]))
          {
            printf("OK, Logged IN! \n");
          }
          else
          {
            printf("Username not in /etc/passwd \n");
          }
      }
      close(fd[0]);
      exit(0);
  }
  return 0;
} 

我想要的是从控制台行读取命令,并且每次我得到一个已知命令时,去孩子那里执行它。现在它可以很好地读取命令,登录工作正常但只有一次。之后,它仍然获得登录,它打印“我得到登录”,但它不会去孩子那里检查它是否正常。

4

3 回答 3

2

我可以看到您有三个主要问题:

  1. 首先是您不会终止从子管道中读取的字符串;
  2. 另一个问题的根源是孩子没有循环,而是执行一次然后退出;
  3. 第三种是如果您将子进程更改为循环,然后退出父进程,则子进程将被放弃,并继续等待永远不会出现的输入。
于 2012-10-23T11:56:48.130 回答
1

我有同样的问题。我的想法是通过管道控制另一个进程,就像它会从键盘/标准输入获得输入一样。这是与不是为它设计的应用程序的进程间通信的经典需求。

问题是,所有示例代码一开始只工作一次,向子进程标准输入发送一些东西。在我看来,管道必须在父母一方关闭,以便孩子一方接收数据。一旦关闭,我就无法“重新打开”它来发送另一个命令。

挽救了我一天的是: http ://www.rkoucha.fr/tech_corner/pty_pdip.html

http://en.wikipedia.org/wiki/Pseudo_terminal

我不知道为什么我花了将近两天的时间才弄明白,因为毕竟这听起来很明显。我在这里发布这个,因为我站在这一边,答案并没有真正解决我的问题。

真诚的,罗伯特

于 2014-10-22T15:17:59.393 回答
1

这是因为您的子进程刚刚退出。似乎首先“read(fd[0], text, sizeof(text));” 阻塞,直到它将从父进程接收到一些数据。然后它执行数据并退出。

顺便说一句,最好调用 waitpid 函数来避免僵尸进程,这可能会给您的应用程序带来一些问题。更重要的是你应该“关闭(fd [0]);” 在父进程的开头不是在“close(fd [1]);”

于 2012-10-23T12:02:55.700 回答