#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;
}
我在getline
,rv
中进行了更改,并为execvp
创建了一个适当的变量。但现在发生的错误是在我键入例如“ls”之后。它说:
执行错误:没有这样的文件或目录。
再次感谢帮助和我缺乏知识。
错误似乎在行变量中,但我无法理解该问题是什么!
这里给出了解决方案。它应该是行[(strlen)-1]而不是行[(strlen-1)]
答案 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
,则您编译的代码不您发布的内容。但是...... line
是char *
,因此line[0]
是char
。 execv
或execvp
的第一个参数是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`那里。