2013-10-05 1 views
0

Я пытаюсь вызвать execv после ручного saerching для исполняемой программы.Ошибка Execv, даже когда команда доступна

В моем случае c является структурой, которая имеет args как массив строк, имеющих аргументы, переданные при приеме ввода. nargs - количество аргументов. c-> args [0] будет содержать «ls», «cat» и т. Д.

Я попытался напечатать значение аргументов args [0], fullPath и т. Д. В моем дочернем процессе. Все они показывают такие значения, как «/ bin/ls», «/ bin/cat» и т. Д. Но когда я вызываю execv, он возвращает -1 с errno из 2, что я понимаю, это ошибка для «Нет такого файла или каталога», , Но я уверен, что файл есть, потому что это то, что возвращает PathResolver после проверки всех разрешений. Может ли кто-нибудь указать, где я, возможно, допустил ошибку.

// Часть происходит внутри ребенка

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

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; 

}

ответ

1

strcpy(args[m],c->args[m]); не определено поведение, потому что args[m] не является указателем на действительной памяти.

Следующая может быть проще:

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

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

args[c->nargs] = NULL; 

Там нет необходимости копировать строки.

(Это не может быть вашей актуальной проблемой, но это, безусловно, мешает вашей программе быть правильным.)

+0

Но я все еще могу напечатать значения args [m] и подтвердить, что это правильное значение. Может быть, мне повезло. Я бы выполнил его в любом случае. Я также попытался напрямую передать c-> args [0], но это тоже не сработало. Вот почему я подумал, что я продублирую массив строк и попробую. В любом случае это полезно. Я обязательно проверю его. – Torpedo

0

execv() ожидает название программы предваряться полным пути в качестве 1-го параметра.

Для поиска PATH вместо обеспечения использования пути execvp().


Update:

Также эта линия

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

делает только выделить 1 байт в returnString, который способ мало для того, как вы используете returnString.

+0

Например, это должно быть что-то вроде «/ bin/ls», верно? Это то, что я получаю от функции PathResolvera и назначая ее как первый аргумент. Но это не работает. – Torpedo

+0

@Torpedo: Я не вижу, где вы назначаете «args» что-то еще, а затем значение из 'c-> args'. – alk

 Смежные вопросы

  • Нет связанных вопросов^_^