简体   繁体   English

execvp()在我自己的shell中不执行任何命令

[英]execvp() not executing any command in my own shell

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<stdlib.h>
#include<string.h>
#define MAX_LINE 80 /* Maximum  length of command*/
struct node
{
 char commandName[41];
 struct node *next;
}*start=NULL;


void insert_at_beg(char cmd[])
{
 struct node *new_node,*current;

 new_node=(struct node *)malloc(sizeof(struct node));

 if(new_node == NULL)
 printf("nFailed to Allocate Memory");

 strcpy(new_node->commandName, cmd);
 new_node->next=NULL;

 if(start==NULL)
 {
  start=new_node;
  current=new_node;
 }
 else
 {
  new_node->next=start;
  start=new_node;
 }
}
void display()
{
 struct node *temp;
 temp=start;
 while(temp!=NULL)
 {
  printf("\t%s\n",temp->commandName);
  temp=temp->next;
 }
}

The above code is a linked list which is implemented using structure to implement history feature in my own shell. 上面的代码是一个链表,它是使用结构实现的,以在我自己的shell中实现历史记录功能。 insert_at_beg() is used to add commands that we enter on shell as a node into the list and display() is used to display list. insert_at_beg()用于将在节点上作为节点输入的命令添加到列表中,而display()用于显示列表。

Below is the main function. 下面是主要功能。 In this function I have created my own shell 在此功能中,我创建了自己的外壳

int main()
{
 char *args[MAX_LINE/2+1]; /* Command Line Argument*/
 int should_run=1, status, i, num, error;
 pid_t pid;
 char str[41];
 char teststr[10]={"history\0"};
 char temprory[41];
 const char delimiter[2]=" ";
 char *token;

 while(should_run)
 {
i=0;
printf("osh>");
fflush(stdout);

fgets(str, sizeof str, stdin);
str[strlen(str)-1]='\0';
strncpy(temprory, str, sizeof(temprory));

token=strtok(str, " ");

    while(token)
    {
       args[i]=strdup(token);

       i++;
       token=strtok(NULL, " ");
    }

    insert_at_beg(args[0]);

    if((strcmp(args[0],teststr))==0)
    {
        display();
    }
    else
    {
        ;
    }

    pid=fork();
    if(pid<0)   // error in creating child process
    {
       printf("\tError in creating child process\n");
    }       
    else if(pid==0)    //child process will execute this block
    {

       error=execvp(args[0], args);   //execvp() always return -1 for any  
        if(error==-1)             //command I type in i.e. that command
        {                         //is not found and hence not executed.
            printf("bash:command not found\n");
        }
                 exit(1);
    }
    else        //parent process will execute this block
    {
       pid=wait(&status);

    if(!strcmp(args[0], "exit"))
    {
            should_run=0;
    }
    }
    }
   return 0;
 }

How to proceed on this issue and make it work? 如何解决这个问题并使它起作用? I am stuck in this situation since long time. 长期以来,我一直处于这种情况。 Need help here. 在这里需要帮助。

Quoted from man 3 execvp : 引自man 3 execvp

The execv(), execvp(), and execvpe() functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. execv(),execvp()和execvpe()函数提供了一个指向以空字符结尾的字符串的指针的数组,这些字符串表示新程序可用的参数列表。 The first argument, by convention, should point to the filename associated with the file being executed. 按照惯例,第一个参数应指向与正在执行的文件关联的文件名。 The array of pointers must be terminated by a null pointer. 指针数组必须以空指针终止。

While you didn't terminate the array of args with a null pointer. 虽然您没有使用空指针终止args数组。

Adding this line: 添加此行:

args[i] = NULL;

after your loop of: 在循环执行之后:

while(token)
{
   args[i]=strdup(token);
   i++;
   token=strtok(NULL, " ");
}

solves your problem. 解决您的问题。 (At least on my laptop the problem is solved..) (至少在我的笔记本电脑上,问题已解决。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM