我正在C中实现一个Unix shell,我正在处理相对path的问题。 值得一提的是input命令。 现在我必须每次input可执行文件的完整path,当时我宁愿简单地放上“ls”或“cat”。
我设法得到$ PATH envvariables。 我的想法是将variables分割为“:”字符,然后将每个新string附加到命令名称,并检查文件是否存在并且是可执行的。
例如,如果我的PATH是“/ bin:/ usr / bin”,并且input了“ls”,我想程序首先检查“/ bin / ls”是否存在并且是可执行的,如果不是, USR /斌/”。
两个问题:
1)这是一个好方法吗? (它不一定是最好的,我只是想确保它能工作。
2)更重要的是, 如何检查C,如果文件存在并且可执行?
我希望我已经清楚了,而且……非常感谢:)
别。 执行此检查是错误的; 它固有地受到竞争条件的影响。 相反, 尝试执行适当的exec
家庭调用。 如果它不可执行,你会得到一个错误。
还要注意,你不需要自己搜索PATH
; execvp
可以为你做这个。
使用stat
函数: http : //linux.die.net/man/2/stat
例如:
struct stat sb; if(!stat(path, &sb)) { if(IS_REG(sb.st_mode) && sb.st_mode & 0111) printf("%s is executable\n", path); }
调用完整的路径名stat
,如果它返回0(成功),目标存在。 在这种情况下,您可以使用返回结构中的st_mode
字段来测试目标是目录,设备,命名管道还是普通文件。 如果它是一个文件, st_mode
也将包含权限位。 (如果是目录,可能会设置一些“可执行”位,但这意味着“可搜索”而不是“可执行”)。
编辑:正如其他人已经指出,这是受到竞争条件,并有更好的方法来完成你想要在这个特定的情况下做什么。
stat
? PSH。 比你需要的方式。
检查access()
系统调用。
if (access(filename, F_OK|X_OK) == 0) { /* You can execute this file. */ }
请注意,任何检查文件访问或文件的存在都有一个固有的竞争条件 。 你不能保证你的电话execve
有人没有删除可执行位,改变文件的所有权,删除文件等,在你的检查发生的时间。 在编写代码时请记住这一点,并决定如何处理错误情况。
你是如何创建过程?
使用execlp或execvp。
access()
答案是唯一明智的答案。 如果使用stat,则必须解析/ etc / group以找出您在BESIDE
getgid()
所有组, BESIDE
它们与组可执行位一起测试。