C语言 WAIT does not wait for child


#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]=''; /*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 %dn", 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: %dn", WEXITSTATUS(rv));
if((WEXITSTATUS(rv))==3){
exit(1);
}
}
}
}
return 0;
}

我对getlinerv进行了更改,并为execvp创建了一个适当的变量。但现在出现的错误是,在我键入例如"ls"之后。上面写着:

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

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

错误似乎在行变量中,但我不明白问题出在哪里!

C 中的字符数组和getline

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

父进程从不获取子进程的pid,因此waitpid不会等待它。waitpid(-1,…)将等待任何子进程完成后再继续。

我还建议对案例进行缩进,并在每个案例陈述的结尾加一个中断;

因此,对于警告:您知道这些数字指的是什么行,我不得不猜测:您可以让这更容易!

int rv=NULL;

初始化使指针中的整数不带强制转换[默认启用]第42行

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

execvp(line[0],line);

传递'execv'的参数1会使指针从不带强制转换的integer(默认情况下启用)变为第64行从不兼容的指针类型[默认启用]第64行传递'execv'的参数2

如果您调用execv,则编译的代码是,而不是发布的代码。然而linechar *,所以line[0]charexecvexecvp的第一个自变量是const char *

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

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

从不兼容的指针类型[默认启用]第29行传递"getline"的参数2

getline需要缓冲区的地址来将字符放入。。。line就是这样一个地址。然而,&line是指针地址。只需取出&即可。


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

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

在开始编写多进程程序之前,您需要了解这一点。用简单的东西来学习,学习阅读文档,并理解编译器警告。

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

您正在将未初始化的变量child_pid传递给waitpid,该变量仅在子进程中设置。你应该通过pid。使用未初始化的变量会导致未定义的行为,因此无法预测会发生什么。另外,如果使用另一个未初始化的变量rv调用WEXITSTATUS,则应该将status传递到那里。

孩子在这里什么都不做,因为

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

传递给getcwd的大小参数是char*的大小,通常是四个或八个字节,对于大多数目录的绝对路径来说太短,path_buffer is set toNULLand the child immediately exits. You should pass the size of the buffer,maxsize。

最新更新