【问题标题】:Using chmod in a C program在 C 程序中使用 chmod
【发布时间】:2010-12-31 07:04:54
【问题描述】:

我有一个程序,我需要使用chmod 设置文件的权限(比如/home/hello.t),并且我必须从文件中读取要设置的权限。为此,我首先将权限读入字符数组,然后尝试修改文件的权限。但我看到权限以一种奇怪的方式设置。

我写的一个示例程序:

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。请你帮我从字符数组中读取文件后如何设置文件的权限。

【问题讨论】:

    标签: c unix


    【解决方案1】:

    atoi() 函数只翻译十进制,而不是八进制。

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


    另外:

    • 不要对main() 使用“隐式int”返回类型;按照 C99 的要求明确并使用 int main(void)int main(int argc, char **argv)
    • 不要从字符串中删除尾随的空值。

      char mode[4] = "0777";
      

      这可以防止 C 存储终端 null - 糟糕!使用:

      char mode[] = "0777";
      

      这分配了存储带有空终止符的字符串所需的 5 个字节。

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

    • 报告错误,末尾有换行符。
    • 最好在错误消息中包含程序名和文件名,并且(正如 CJY 指出的)在输出中包含系统错误号和相应的字符串。这需要&lt;string.h&gt; 标头(用于strerror())和&lt;errno.h&gt; 用于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' 通常也是个好主意:例如,/tmp 上通常使用 1777 权限 - 但在 MacOS X 上不使用。)

    【讨论】:

    • strtoul 更好,因为谁使用否定模式,认真的? :-P 此外,报告包含errno 的错误,例如使用perrorstrerror(或格式字符串中的%m,如果使用GNU libc)。
    • 谢谢,效果很好。还要感谢您纠正我的编程错误。
    • 错误消息中通常不会显示数字 errno 值,因为它是多余的,并且可能会泄露有关操作系统类型的不需要的信息。
    • @jilles:在某个层面上你是对的——但大多数 Unix 错误消息的独特性足以识别 O/S(作为 Unix),并且省略错误号之类的信息不如包括它。大多数时候,我与在机器上键入命令的用户一起工作。对用户隐藏操作系统是无关紧要的。在 Web 环境中,向用户报告的是另一回事,但日志中的内容应该包括系统错误号(可能还有文本),至少在我的估计中是这样。类似的 cmets 应用在 GUI 程序中 - 你处理错误的方式不同。
    • 可能希望在调用 chmod 之前将 errno 设置为 0。
    猜你喜欢
    • 2023-03-09
    • 2013-08-30
    • 2019-11-24
    • 2012-02-04
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 2014-08-05
    • 1970-01-01
    相关资源
    最近更新 更多