在C程序中使用chmod

Rag*_*hav 16 c unix

我有一个程序,我需要设置文件的权限(说/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");
}
Run Code Online (Sandbox Code Playgroud)

我看到该文件的权限未设置为777.在从字符数组中读取文件后,能否帮我解决如何设置文件权限的问题.

Jon*_*ler 35

atoi()函数仅转换十进制,而不是八进制.

对于八进制转换,使用strtol()(或者,正如Chris Jester-Young指出的那样strtoul()- 尽管Unix的文件权限模式的有效大小都适合16位,因此long无论如何都不会产生负数),以0或8作为基础.实际上,在这种情况下,指定8是最好的.它允许人们编写777并获得正确的八进制值.如果指定了0,则字符串777为十进制(再次).


另外:

  • 不要使用'implicit int'返回类型main(); 根据C99的要求明确并使用int main(void)int main(int argc, char **argv).
  • 不要使用从字符串中删除尾随空值.

    char mode[4] = "0777";
    
    Run Code Online (Sandbox Code Playgroud)

    这可以防止C存储一个空终端 - 坏!使用:

    char mode[] = "0777";
    
    Run Code Online (Sandbox Code Playgroud)

    这将使用空终止符分配存储字符串所需的5个字节.

  • 报告错误stderr,而不是stdout.

  • 最后用换行符报告错误.
  • 最好在错误消息中包含程序名称和文件名,并且(如CJY指出的那样)在输出中包含系统错误号和相应的字符串.这需要<string.h>标题(for strerror())和<errno.h>for 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);
}
Run Code Online (Sandbox Code Playgroud)

小心errno; 它可以在调用函数时更改.这里很安全,但在许多情况下,捕获errno到局部变量并在打印操作中使用局部变量等是个好主意.

另请注意,代码不会对结果进行错误检查strtol().在这种情况下,它足够安全; 如果用户提供了该值,那么相信它们是正确的将是一个坏主意.


最后一条评论:通常,您不应对文件(或目录)使用777权限.对于文件,这意味着您不介意谁修改您的可执行程序,或者如何.通常情况并非如此; 你是否关心(或应该关心)谁修改你的程序.通常,不要让数据文件可执行; 当文件可执行时,不要给予公共写访问权并在组写访问时查看.对于目录,公共写入权限意味着您不介意删除目录中的任何文件(或添加文件).同样,偶尔,这可能是正确的权限设置,但它很少是正确的.(对于目录,通常也应该使用'sticky bit':/tmp例如,通常使用1777权限- 但不能在MacOS X上使用.)