0

プログラムを実行するために手動で検索した後、execvを呼び出そうとしています。

私の場合、 c は、入力の受信中に渡された引数を持つ文字列の配列として args を持つ構造体です。nargs は引数の数です。c->args[0] には、「ls」、「cat」などが含まれます。

子プロセスでargs [0]、fullPathなどの値を出力してみました。それらはすべて「/bin/ls」、「/bin/cat」などの値を示します。しかし、execv を呼び出すと、errno が 2 の -1 が返されます。これは、「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;

}

4

2 に答える 2

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;

文字列をコピーする必要はありません。

(これは実際の問題ではないかもしれませんが、プログラムが正しく動作しないことは確かです。)

于 2013-10-05T10:17:11.567 に答える
0

execv()は、プログラム名の前にフルパスを第 1 パラメーターとして付けることを想定しています。

パスを提供する代わりにPATH検索するには、 を使用しますexecvp()


更新

このラインも

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

1はバイトのみを に割り当てますreturnString。これは、使用方法が少ないためですreturnString

于 2013-10-05T10:19:35.677 に答える