Question

I'm trying to call execv after manually saerching for the program to execute.

In my case, c is a struct which has args as an array of strings having the arguments passed while receiving input. nargs is the number of arguments. c->args[0] would contain "ls","cat" etc.

I tried printing the value of the args[0], fullPath etc. in my child process. They all show values like "/bin/ls","/bin/cat" etc. But when I call execv, it returns -1 with an errno of 2, which I understand is the error for "No such file or directory". But I'm sure the file is there because thats what my PathResolver is returning after checking all permissions. Can anyone point where I might have made a mistake.

//The part happening inside child

  char *fullPath = PathResolver(c->args[0],1,&permission);
  printf("FullPath: %s -- Permission: %d\n",fullPath,permission);
  if(permission==0)
  {
      fprintf(stderr, "%s: Command not found\n",c->args[0]);
  }
  else if(permission==-1)
  {
      fprintf(stderr, "%s: Permission denied\n",c->args[0]);
  }
  else
  {
    char* args[c->nargs+1];
    int m=0;
    for(m=0;m<c->nargs;m++)
    {
          strcpy(args[m],c->args[m]);
    }
    args[c->nargs] = NULL;
    printf("%d\n",execv(args[0], args));
    printf("errno: %d\n",errno);
 }

PathResolver function

   char* PathResolver(char *command, int ResolverMode, int *Permission)
   {
 *Permission = 0;
 char *returnString;
 returnString = malloc((sizeof(char)));
 char *strPath = getenv("PATH");
 char *del = ":";
 char *strToken = strtok(strPath,del);
 FILE *f;
 while(strToken)
 {
    char filePath[100];
    sprintf(filePath,"%s/%s",strToken,command);
    if(access(filePath,F_OK)>=0)
    {
        if(access(filePath,X_OK)>=0)
        {
            *Permission = 1;
            sprintf(returnString,"%s%s ",returnString,filePath);
            if(ResolverMode == 1)
                break;
        }
        else
        {
            *Permission = -1;
        }
    }
    strToken = strtok(NULL,del);
  }
  sprintf(returnString,"%s\b",returnString);
  return returnString;

}

No correct solution

OTHER TIPS

strcpy(args[m],c->args[m]); is undefined behaviour, because args[m] is not a pointer to valid memory.

The following might be simpler:

char * args[c->nargs + 1];

for (size_t m = 0; m != c->nargs; ++m)
{
     args[m] = c->args[m];
}

args[c->nargs] = NULL;

There's no need to copy the strings.

(This may not be your actual problem, but it certainly prevents your program from being correct.)

execv() expects the program name to be prefixed by a full path as 1st parameter.

To have PATH searched instead of providing a path use execvp().


Update:

Also this line

 returnString = malloc((sizeof(char)));

does only allocate 1 byte to returnString, which is way to few for how you use returnString.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top