2013-10-05 76 views
0

我正在嘗試在手動執行saerching程序後調用execv。甚至當命令可用時,Execv仍然失敗

在我的情況下, c是一個結構,args是一個字符串數組,它具有在接收輸入時傳遞的參數。 nargs是參數的數量。 c-> args [0]會包含「ls」,「cat」等。

我嘗試在我的子進程中打印args [0],fullPath等的值。它們都顯示「/ bin/ls」,「/ bin/cat」等值。但是當我調用execv時,它會返回-1,錯誤號爲2,我知道這是「No such file or directory」 。但我確定該文件存在,因爲這是我的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()希望通過完整路徑作爲第一個參數爲前綴的程序名。

要搜索PATH而不是提供路徑使用execvp()


更新

而且這條線

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

也只分配1字節returnString,這是對的方式爲一些你如何使用returnString

+0

例如,它必須是'/ bin/ls',對吧?這就是我從PathResolver函數中獲得並將其作爲第一個參數分配的內容。但它不起作用。 – Torpedo

+0

@Torpedo:我看不到你指定給'args'的什麼東西,然後從'c-> args'賦值。 – alk