2017-10-11 46 views
0

我必须制作简单的shell来读取命令并按顺序执行它们。条件不改变主函数的形式,并且执行函数应该是递归的。 主要问题是,它似乎waitpid不起作用。但我知道,我的代码中存在很多问题。请让我知道我应该从哪里开始..简单的shell在c: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

+1

可能相关:你必须'NULL'终止你的参数列表。 –

+1

您的令牌循环非常可疑。如果超过2个参数,我认为它可能是无限的。它不会以NULL结尾。 –

+0

Thanl你。我修好了,并成功分开它,但循环永远不会结束。你能告诉我什么是重要的吗?当我尝试打印每个argv时,它可以打印到最后一个参数,但仍然保留在while循环中。 –

回答

1

您标记字符串的方式非常错误。有很多的strtok电话,因为你在初始化字符串的循环中调用strtok,不NULL

你的循环可以无限循环加上你的最后一个参数,这是后不是要设置到NULL通过execv需要知道何时参数已用完(没有大小被传递)

这里的一个独立的实施例和适当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