c: waitpid 系统调用中的简单 shell 不工作

simple shell in c: waitpid system call not working

我必须制作简单的 shell 来读取命令并按顺序执行它们。 condition 不改变 main 函数的形式,execute 函数应该是递归的。 主要问题是 waitpid 似乎不起作用。但我知道,我的代码中有很多问题。请让我知道我应该从哪里开始..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define MAX 10

char cmmd[MAX][256];
int sp;
char *argv[10];
int size;

void ClearLineFromReadBuffer(void){
    while(getchar() != '\n');
}
void printCommands(){
    size = sp+1;
    //print by moving stack pointer
    while(1){
        if (sp==-1) break;
        printf("Command line : %s\n", cmmd[sp]);
        sp--;
    }
    printf("print end\n");
}



void readCommandLines(){
    int a = 0; //return of scanf
    while (1){ //write commends to cmmd untill get ctrl+d
        printf(">");
        a = (scanf("%[^\n]s", cmmd[sp])); //take input to str untill get enter(scanf returns -1)
        if (a==-1) {sp--; break;}
        if (a==1) ClearLineFromReadBuffer();
        if (a==0) {printf("error"); break;}
        sp++;
    }
    printf("\n");
}

void readACommand(char *line){ //line takes string's name.
    int i=0;

    argv[i]=strtok(line," "); //i==0
    while(strtok(line," ")!=NULL){
        i++;
        argv[i]=strtok(NULL," ");
    }
    printf("%s",argv[0]);
    printf("%s",argv[1]);
}

void executeCommands(){ //Recursive function
    int n = sp;
    n++;
    printf("%d",n);
    printf("%s",cmmd[n]);
    char *cmd_line = cmmd[n]; //command line which child process will execute

    unsigned int child_pid; //fork() returns process id of child in parents process
    int status; //status takes return of child's exit()
    child_pid=fork();
    if (child_pid != 0){ // Parents process
        printf("parents access");
        waitpid(child_pid,&status,0);
        printf("***Process %d Child process %d DONE with status %x\n\n",getpid(),child_pid,status);

        sp++;
        if(sp<size)
            executeCommands();
    }
    else if (child_pid == 0){ //fork() returns 0 in child process
        printf("***Process %d Executing Command %s",getpid(),cmd_line);
        readACommand(cmmd[n]);
        execve(argv[0],argv,NULL);
        printf("ERROR - not executing command \"%s\"\n",argv[0]); //can be printed because exec() failed
    }
}

int main(){
    readCommandLines();
    printCommands();
    executeCommands();
    return(0);
}

这是结果。 enter image description here

您对字符串进行标记的方式非常错误。有很多 strtok 调用,你的循环可以是一个无限循环,因为你在循环中使用初始化字符串调用 strtok,而不是 NULL

此外,您没有在最后一个参数之后设置为 NULLexecv 需要这样做才能知道参数何时 运行 结束(未传递大小)

这是一个独立示例和一个正确的 readACommand 例程:

#include <stdio.h>
#include <string.h>

char *argv[100];

void readACommand(char *line){ //line takes string's name.
    int i=0;

    argv[i]=strtok(line," "); //i==0
    while(argv[i]!=NULL){
        argv[++i]=strtok(NULL," ");
    }
}

int main()
{
   char line[] = "this is a command";
   char **ptr=argv;

   readACommand(line);
   while(*ptr != NULL)
   {
      printf("Arg: %s\n",*ptr);
      ptr++;
   }
   return 0;
}

正在执行(最后检测到NULL指针):

Arg: this
Arg: is
Arg: a
Arg: command