私はトムの答えをテストしました
それには多くの問題が含まれていました。ここでそれらを修正し、テスト プログラムを提供しました。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
int is_file(const char* path) {
struct stat buf;
stat(path, &buf);
return S_ISREG(buf.st_mode);
}
/*
* returns non-zero if the file is a file in the system path, and executable
*/
int is_executable_in_path(char *name)
{
char *path = getenv("PATH");
char *item = NULL;
int found = 0;
if (!path)
return 0;
path = strdup(path);
char real_path[4096]; // or PATH_MAX or something smarter
for (item = strtok(path, ":"); (!found) && item; item = strtok(NULL, ":"))
{
sprintf(real_path, "%s/%s", item, name);
// printf("Testing %s\n", real_path);
if ( is_file(real_path) && !(
access(real_path, F_OK)
|| access(real_path, X_OK))) // check if the file exists and is executable
{
found = 1;
}
}
free(path);
return found;
}
int main()
{
if (is_executable_in_path("."))
puts(". is executable");
if (is_executable_in_path("echo"))
puts("echo is executable");
}
ノート
- 戻り値のテスト
access
が逆になった
- 2 番目の strtok 呼び出しの区切り文字が間違っていました
- strtok は
path
引数を変更しました。私のサンプルはコピーを使用しています
- 連結されたパス区切り文字が適切であることを保証するものは何もありませんでした。
real_path
- 一致したファイルが実際にファイルであるかどうかのチェックはありませんでした (ディレクトリも「実行可能」になる可能性があります)。
.
これは、外部バイナリとして認識されるなどの奇妙なことにつながります