WAIT不等孩子

时间:2012-09-17 19:32:25

标签: c fork wait pid

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>

char *getdir()  /*find working directory*/
{
  char *buffer;/*buffer is going to be used in getcwd function to get the current directory*/
  char *path_buffer;//path_buffer is going to contain the directory//
  long maxsize = pathconf(".", _PC_PATH_MAX);/* we set maxsize as the maximum pathname length*/
  if((buffer=(char*) malloc((size_t)maxsize))!=NULL)
    {
      path_buffer=getcwd(buffer,maxsize); /*get the current directory*/
      printf("\nMy working directory = %s",path_buffer);
      return path_buffer;
    }
  else{
    exit(-1);
  }
}

char * getcmline() /*get command from stdin by the user*/
{
  int bytes_read;
  int nchars=200;/*max possible number for the input of the user*/
  int nbytes=(sizeof(char))*nchars; /*size of chars in bytes*/
  char *line=(char*) malloc(nbytes+1);
  bytes_read=getline(line,&nbytes,stdin);/*read line from stdin*/
  if(bytes_read == -1){
    printf("Read line error");
    exit(-1);
  } /*error handling for bytes_read*/
  else{
    if(line[strlen(line)-1]=='\n')
      {
        line[strlen(line)-1]='\0'; /*change new line character in the end of the line of stdin*/
      }
  }
  return line;
}

int main(void)
{
  pid_t pid,child_pid;
  int rv=0;
  char* exit_string="exit";
  char *path_buffer=NULL;
  int nchars=200;
  int nbytes=(sizeof(char))*nchars;
  char *line=malloc(nbytes+1);
  char *commands[2];
  while(1){
    switch(pid = fork())
      {
      case -1:
        perror("fork"); /* something went wrong */
        exit(1);
      case 0:
        printf(" CHILD: This is the child process!\n");
        child_pid=getpid();
        printf(" CHILD: My PID is %d\n", child_pid);
        path_buffer=getdir();/*get the directory path*/
        line=getcmline();/*get a command by the user*/
        if(strcmp(line,exit_string)==0)
          {
            rv=3;
            exit(rv);
          }
        commands[0]=line;
        commands[1]=NULL;
        execvp(commands[0],commands);
        perror("Execution error");
        exit(-1);



      default:
        waitpid(-1, &rv, 0);
        if(WIFEXITED(rv)){
          printf("Child exited normally and child's exit status is: %d\n", WEXITSTATUS(rv));
          if((WEXITSTATUS(rv))==3){
            exit(1);
          }
        }
      }
  }
  return 0;
}

我在getlinerv中进行了更改,并为execvp创建了一个适当的变量。但现在发生的错误是在我键入例如“ls”之后。它说:

  

执行错误:没有这样的文件或目录。

再次感谢帮助和我缺乏知识。

错误似乎在行变量中,但我无法理解该问题是什么!

Char Array and getline in C

这里给出了解决方案。它应该是行[(strlen)-1]而不是行[(strlen-1)]

3 个答案:

答案 0 :(得分:4)

父母永远不会得到孩子的pid,因此waitpid没有等待它。 waitpid(-1,...)将等待任何子进程完成后再继续。

我还建议缩进案例并以休息结束每个案例陈述;

答案 1 :(得分:1)

所以,对于警告:你知道这些数字引用的行,我不得不猜测:你可以让这更容易!

int rv=NULL;
  

初始化从指针生成整数而没有强制转换[默认情况下启用]第42行

NULL是指针值,rv是整数。如果这就是你的意思,请将其设置为0

execvp(line[0],line);
  

传递'execv'的参数1使整数指针没有强制转换[默认情况下启用]第64行   从不兼容的指针类型[默认启用]第64行

传递'execv'的参数2

如果您正在调用execv,则您编译的代码您发布的内容。但是...... linechar *,因此line[0]charexecvexecvp的第一个参数是const char *

execv试图完成什么?它需要一个程序名来运行(第一个参数,const char *)和一个参数数组(这些将形成传递给新程序的argv[]函数的main数组,以及数组中的最后一项必须为NULL)。

char *line=(char*) malloc(nbytes+1);
bytes_read=getline(&line,&nbytes,stdin);/*read line from stdin*/
  

从不兼容的指针类型[默认启用]第29行

传递'getline'的参数2

getline需要缓冲区的地址才能将字符放入... line 这样的地址。但是,&line是指针的地址。只需取出&


您的代码中存在更多问题,但这些警告都有一些共同点:

  • 您似乎不了解函数期望的类型,
  • 您的变量是什么类型,
  • 你实际传递的是什么类型,
  • 或者当抱怨你的类型不匹配时编译器意味着什么

在开始尝试编写多进程程序之前,您需要了解此。通过 easy 学习它,学习阅读文档并理解编译器警告。

答案 2 :(得分:0)

default:
waitpid(child_pid, &status, 0);
//wait(&rv);
printf("PARENT:My child's exit status is: %d\n", WEXITSTATUS(rv));
if((WEXITSTATUS(rv))==3){exit(1);}

您将未初始化的变量child_pid传递给waitpid,该变量仅在子进程中设置。你应该通过pid。使用未初始化的变量会导致未定义的行为,因此无法预测会发生什么。您也可以使用其他未初始化的变量WEXITSTATUS来调用rv,您应该在那里传递status

孩子在这里做的不多,因为

path_buffer=getcwd(buffer,sizeof(buffer));

传递给getcwd的size参数是char*的大小,通常为4或8个字节,对于大多数目录的绝对路径来说太短,path_buffer is set to NULL {{ 1}} maxsize`那里。