给定C中的文件名,我想确定该文件是否存在并具有执行权限。我目前所拥有的只是:
if( access( filename, X_OK) != 0 ) {
但是这不会在PATH中搜索文件,也会匹配目录(我不想要)。有人可以帮忙吗?
编辑:
作为替代方案,当我在子进程中运行execvp()时,有没有办法检查execvp()的返回值并通过错误消息通知父进程死?
答案 0 :(得分:2)
这段代码不是你想要的,因为它只是盲目地执行它的第一件事。但是您可以修改搜索代码,以便调用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);
}
}
}
答案 1 :(得分:1)
您可以使用以下功能。 喜欢.. 以下代码包含一些伪代码,但应易于实现
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;
}
答案 2 :(得分:0)
结束必须在新管道上设置FD_CLOEXEC标志,并在exec之后通过它写一条错误消息(如果它已经失败)。然后,我可以从父级读取错误消息,并确定exec是否成功。
感谢你们的努力,为了帮助