給定一個C文件名,我想確定這個文件是否存在並且對它有執行權限。所有我現在得到的是:檢查文件是否存在,包括路徑上
if(access(filename, X_OK) != 0) {
但是這不會搜索文件的路徑,也將匹配目錄(我不希望)。任何人都可以請幫忙?
編輯:
作爲替代,看到我在一個子進程運行execvp(),有沒有辦法來檢查execvp(返回值)和信號父進程與死錯誤信息?
給定一個C文件名,我想確定這個文件是否存在並且對它有執行權限。所有我現在得到的是:檢查文件是否存在,包括路徑上
if(access(filename, X_OK) != 0) {
但是這不會搜索文件的路徑,也將匹配目錄(我不希望)。任何人都可以請幫忙?
編輯:
作爲替代,看到我在一個子進程運行execvp(),有沒有辦法來檢查execvp(返回值)和信號父進程與死錯誤信息?
最後不得不設置FD_CLOEXEC標誌上一個新的管道,如果它的EXEC後通過它寫一個錯誤信息失敗了。然後,我可以從父級讀取錯誤消息,並確定exec是否成功。
感謝您的努力,雖然傢伙,upvoted的幫助
這段代碼並不完全是你想要的,因爲它只是盲目地執行它的第一件事。但是,您可以修改搜索代碼,以便不要調用execve
,而是調用access
,然後stat
以查明它是否不是目錄。我認爲只有最後一個功能execvepath
必須被替換。
在最好的Unix傳統中,代碼是「自我記錄」(即無證)。
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include "shellpath.h"
static void *malloc_check(const char *what, size_t n) {
void *p = malloc(n);
if (p == NULL) {
fprintf(stderr, "Cannot allocate %zu bytes to %s\n", n, what);
exit(2);
}
return p;
}
static char *strsave(const char *s, const char *lim) {
if (lim == NULL)
lim = s + strlen(s);
char *p = malloc_check("save string", lim - s + 1);
strncpy(p, s, lim-s);
p[lim-s] = '\0';
return p;
}
char ** shellpath(void) {
const char *path = getenv("PATH");
if (!path)
path = "/bin:/usr/bin:/usr/local/bin";
char **vector = // size is overkill
malloc_check("hold path elements", strlen(path) * sizeof(*vector));
const char *p = path;
int next = 0;
while (p) {
char *q = strchr(p, ':');
vector[next++] = strsave(p, q);
p = q ? q + 1 : NULL;
}
vector[next] = NULL;
return vector;
}
void freeshellpath (char *shellpath[]) {
for (int i = 0; shellpath[i]; i++)
free(shellpath[i]);
free(shellpath);
}
unsigned maxpathlen(char *path[], const char *base) {
unsigned blen = strlen(base);
unsigned n = 0;
for (int i = 0; path[i]; i++) {
unsigned pn = strlen(path[i]);
if (pn > n) n = pn;
}
return blen+n+1;
}
void execvepath(char *path[], const char *base, char *const argv[],
char *const envp[])
{
if (strchr(base, '/'))
execve(base, argv, envp);
else {
size_t maxlen = maxpathlen(path, base)+1;
char *buf = malloc_check("hold path", maxlen);
for (int i = 0; path[i]; i++) {
snprintf(buf, maxlen, "%s/%s", path[i], base);
execve(buf, argv, envp);
}
}
}
嘿 - 感謝您的幫助。這似乎比我想象的要複雜得多。如果文件不存在,是否沒有辦法運行exec函數並讓它返回? – Gary 2010-04-27 05:52:43
您可以使用以下功能。 如.. 以下代碼包含一些僞代碼,但應該是很容易實現
if the given path contains the current directory path,
like /root/a or ./abc, then
return access(filename, X_OK) == 0;
Else - if the given path only contains the filename,
{
getenv("PATH");
while(iterate the directories in PATH)
{
if(search(PATH_directory, filename))
{
// create the full path string with strcat, strcpy, and/or etc.
full_path = blabla
if(!is_directory(full_path) && access(filename, X_OK) == 0)
return 1; // Yeah~~ We got it!!!
}
}
return 0; // Nah, I don't think there is any of such a file.
}
int is_directory(const char* path)
{
struct stat file_info;
return (stat(path, &file_info) == 0) ? S_ISDIR(file_info.st_mode) : 0;
}
int search(const char* file_name, const char* path)
{
struct dirent* dptr;
DIR* dirp;
if((dirp = opendir(path)) == NULL)
return 0;
while(dptr = readdir(dirp))
{
if(strcmp(file_name, dptr->d_name) == 0)
{
closedir(dirp);
return 1;
}
}
closedir(dirp);
return 0;
}
@diciu我知道這一點。這就是爲什麼我正在尋找一種方法讓C在這些路徑中以與bash相同的方式搜索文件名。 – Gary 2010-04-27 05:44:30