我有一个程序,我需要使用/home/hello.t
设置文件的权限(比如chmod
),我必须从文件中读取要设置的权限。为此,我首先将权限读入字符数组,然后尝试修改该文件的权限。但我发现权限设置的方式很奇怪。
我写的一个示例程序:
main()
{
char mode[4]="0777";
char buf[100]="/home/hello.t";
int i;
i = atoi(mode);
if (chmod (buf,i) < 0)
printf("error in chmod");
}
我看到该文件的权限未设置为777.在从字符数组中读取文件后,能否帮我解决如何设置文件权限的问题。
答案 0 :(得分:33)
atoi()
函数仅转换十进制,而不是八进制。
对于八进制转换,使用strtol()
(或Chris Jester-Young指出strtoul()
- 尽管Unix的文件权限模式的有效大小都在16位以内,因此绝不会以0或8作为基数产生负long
。实际上,在这种情况下,指定8是最好的。它允许人们编写777并获得正确的八进制值。如果指定了0,则字符串777为十进制(再次)。
此外:
main()
使用'implicit int'返回类型;根据C99的要求明确并使用int main(void)
或int main(int argc, char **argv)
。不要使用从字符串中删除尾随空值。
char mode[4] = "0777";
这可以防止C存储一个空终端 - 坏!使用:
char mode[] = "0777";
这将使用空终止符分配存储字符串所需的5个字节。
报告stderr
上的错误,而不是stdout
。
<string.h>
标头(适用于strerror()
)和<errno.h>
适用于errno
。此外,当chmod()
操作失败时,程序的退出状态应指示失败。将所有更改放在一起产生:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
int main(int argc, char **argv)
{
char mode[] = "0777";
char buf[100] = "/home/hello.t";
int i;
i = strtol(mode, 0, 8);
if (chmod (buf,i) < 0)
{
fprintf(stderr, "%s: error in chmod(%s, %s) - %d (%s)\n",
argv[0], buf, mode, errno, strerror(errno));
exit(1);
}
return(0);
}
小心errno
;它可以在调用函数时更改。这里很安全,但在许多情况下,最好将errno
捕获到局部变量中,并在打印操作中使用局部变量等。
另请注意,代码不会对strtol()
的结果进行错误检查。在这种情况下,它足够安全;如果用户提供了该值,那么相信它们是正确的将是一个坏主意。
最后一条评论:通常,您不应对文件(或目录)使用777权限。对于文件,这意味着您不介意谁修改您的可执行程序,或者如何。通常情况并非如此;你是否关心(或应该关心)谁修改你的程序。通常,不要让数据文件可执行;当文件可执行时,不要给予公共写访问权并在组写访问时查看。对于目录,公共写入权限意味着您不介意删除目录中的任何文件(或添加文件)。同样,偶尔,这可能是正确的权限设置,但它很少是正确的。 (对于目录,通常也应该使用'sticky bit':1777权限是/tmp
上通常使用的权限,例如 - 但不适用于MacOS X.)