我有一个算法,它查看包含多个路径的数组,并检查数组中列出的任何目录中是否存在命令(例如ls,wc,cat ...等)。如果在其中一个目录中找到该文件,则返回完整的目录路径。
char *LookupPath(char **argv, char **dir)
{
/* String Name To Be Returned */
char *result;
char path_name[MAX_PATH_LEN] = {0};
int i;
/* Check To See If File Name Is Already An Absolute Path Name */
if(*argv[0] == '/') {
}
/* Look In Path Directories */
for(i = 0; dir[i] != NULL; i++) {
strncat(path_name, dir[i], sizeof(path_name));
strncat(path_name, "/", sizeof(path_name));
strncat(path_name, argv[0], sizeof(path_name));
printf("pathname: %s\n", path_name);
result = path_name;
if(access(result, F_OK) == 0) {
printf("SUCCESS!\n");
printf("result: %s\n", result);
return result;
}
path_name[0] = '\0';
}
/* File Name Not Found In Any Path Variable */
return NULL;
}
char *LookupPath(char **argv, char **dir)
{
/* String Name To Be Returned */
char *result;
char path_name[MAX_PATH_LEN] = {0};
int i;
/* Check To See If File Name Is Already An Absolute Path Name */
if(*argv[0] == '/') {
}
/* Look In Path Directories */
for(i = 0; dir[i] != NULL; i++) {
strncat(path_name, dir[i], sizeof(path_name));
strncat(path_name, "/", sizeof(path_name));
strncat(path_name, argv[0], sizeof(path_name));
printf("pathname: %s\n", path_name);
result = path_name;
if(access(result, F_OK) == 0) {
printf("SUCCESS!\n");
printf("result: %s\n", result);
return result;
}
path_name[0] = '\0';
}
/* File Name Not Found In Any Path Variable */
return NULL;
}
新问题:当使用诸如ls -l之类的命令或其他任何命令时,结果可以很好地工作,如下面的结果代码所示。
pathname: /usr/lib/lightdm/lightdm/ls
pathname: /usr/local/sbin/ls
pathname: /usr/local/bin/ls
pathname: /usr/sbin/ls
pathname: /usr/bin/ls
pathname: /sbin/ls
pathname: /bin/ls
SUCCESS!
result: /bin/ls
但是,现在当我只使用一个简单的命令如'ls'时...结果是假的...因为某些原因,新的行字符被添加到ls ......?看来:
pathname: /usr/lib/lightdm/lightdm/ls
pathname: /usr/local/sbin/ls
pathname: /usr/local/bin/ls
pathname: /usr/sbin/ls
pathname: /usr/bin/ls
pathname: /sbin/ls
pathname: /bin/ls
SUCCESS!
result: /bin/ls
我不知道为什么。有没有办法把它减少到'ls'。我不知道为什么新的行字符被添加到argv [0]时它只是一个简单的ls命令。 :S
答案 0 :(得分:1)
您不能在循环中调用它,因为您正在修改dir字符串:strcat()通过修改它将源字符串附加到目标(并使用dir字符串作为目标)。此外,由于您没有为扩展字符串长度做任何规定,因此您要写入字符串内存的末尾并破坏其他内存。
您需要创建一个足够长的char数组作为局部变量,并在那里构造要测试的路径名。最好使用snprintf()而不是strcat(),并确保创建的路径适合您的字符串。此外,由于您无法返回本地字符串,因此在成功的情况下,您需要malloc()一个新的结果长度字符串并将结果复制到那里。
至于检查它是否已经绝对,请检查名称的第一个字母是否为“/”。你似乎已经做了。
答案 1 :(得分:0)
我很确定有些库会为你做这件事,但你真正的问题是你每次都要在循环中附加到dir中的路径。
结果是ptr
并且这些行实际上每次都将/ argv [0]附加到路径中的每个元素 你进入循环
result = dir[i];
strcat(result, "/");
strcat(result, argv[0]);
您需要创建一个临时字符缓冲区并使用多个strcats或sprintf来填充内容。 FWIW,你应该养成使用带有长度参数的strncat或类似字符串函数的习惯。像这样的代码是许多安全问题的开始。像这样的东西
char result[PATH_MAX];
strncpy(dir[i],result,length(dir[i))
答案 2 :(得分:0)
是的,strcat
看起来像是问题所在。假设char **dir
是一个标准的字符串数组,当你strcat
加上它时,你可能会跑到最后,这很糟糕。 As I've said myself:
不!不!不是
strcat
!strcat
分配缓冲区溢出,就像太阳分配阳光一样! ......严肃地说, 不 。
你需要在循环中分配某种缓冲区;比方说,
char buf[BUFSIZE] = {0};
result = buf;
其中BUFSIZE
#define
足够大(我的估计值是:尝试300)。
然后尝试以下方法:
strlcpy(buf, dir[i], BUFSIZE);
strlcat(buf, "/", BUFSIZE);
strlcat(buf, argv[0], BUFSIZE);
警告:我现在无法测试;我只是认为它有效。不过应该没问题。