在C程序中使用chmod

时间:2022-06-18 22:57:47

I have a program where I need to set the permissions of a file (say /home/hello.t) using chmod and I have to read the permissions to be set from a file. For this I first read the permissions into a character array and then try to modify the permissions of the file. But I see that permissions are set in a weird manner.

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

A sample program I have written:

我写的示例程序:

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");
}

I see that the permissions of the file are not set to 777. Can you please help me out on how to set the permissions of the file after reading the same from a character array.

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

1 个解决方案

#1


32  

The atoi() function only translates decimal, not octal.

atoi()函数只转换十进制,而不是八进制。

For octal conversion, use strtol() (or, as Chris Jester-Young points out, strtoul() - though the valid sizes of file permission modes for Unix all fit within 16 bits, and so will never produce a negative long anyway) with either 0 or 8 as the base. Actually, in this context, specifying 8 is best. It allows people to write 777 and get the correct octal value. With a base of 0 specified, the string 777 is decimal (again).

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


Additionally:

另外:

  • Do not use 'implicit int' return type for main(); be explicit as required by C99 and use int main(void) or int main(int argc, char **argv).
  • 不要对main()使用'implicit int'返回类型;根据C99的要求显式使用int main(void)或int main(int argc,char ** argv)。
  • Do not play with chopping trailing nulls off your string.

    不要玩你的字符串中的尾随空格。

    char mode[4] = "0777";
    

    This prevents C from storing a terminal null - bad! Use:

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

    char mode[] = "0777";
    

    This allocates the 5 bytes needed to store the string with a null terminator.

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

  • Report errors on stderr, not stdout.

    报告stderr上的错误,而不是stdout。

  • Report errors with a newline at the end.
  • 最后用换行符报告错误。
  • It is good practice to include the program name and file name in the error message, and also (as CJY pointed out) to include the system error number and the corresponding string in the output. That requires the <string.h> header (for strerror()) and <errno.h> for errno. Additionally, the exit status of the program should indicate failure when the chmod() operation fails.
  • 最好在错误消息中包含程序名称和文件名,并且(如CJY指出的那样)在输出中包含系统错误号和相应的字符串。这需要 头(对于strerror())和 对于errno。此外,程序的退出状态应指示chmod()操作失败时的失败。

Putting all the changes together yields:

将所有变化放在一起产生:

#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);
}

Be careful with errno; it can change when functions are called. It is safe enough here, but in many scenarios, it is a good idea to capture errno into a local variable and use the local variable in printing operations, etc.

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

Note too that the code does no error checking on the result of strtol(). In this context, it is safe enough; if the user supplied the value, it would be a bad idea to trust them to get it right.

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


One last comment: generally, you should not use 777 permission on files (or directories). For files, it means that you don't mind who gets to modify your executable program, or how. This is usually not the case; you do care (or should care) who modifies your programs. Generally, don't make data files executable at all; when files are executable, do not give public write access and look askance at group write access. For directories, public write permission means you do not mind who removes any of the files in the directory (or adds files). Again, occasionally, this may be the correct permission setting to use, but it is very seldom correct. (For directories, it is usually a good idea to use the 'sticky bit' too: 1777 permission is what is typically used on /tmp, for example - but not on MacOS X.)

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

#1


32  

The atoi() function only translates decimal, not octal.

atoi()函数只转换十进制,而不是八进制。

For octal conversion, use strtol() (or, as Chris Jester-Young points out, strtoul() - though the valid sizes of file permission modes for Unix all fit within 16 bits, and so will never produce a negative long anyway) with either 0 or 8 as the base. Actually, in this context, specifying 8 is best. It allows people to write 777 and get the correct octal value. With a base of 0 specified, the string 777 is decimal (again).

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


Additionally:

另外:

  • Do not use 'implicit int' return type for main(); be explicit as required by C99 and use int main(void) or int main(int argc, char **argv).
  • 不要对main()使用'implicit int'返回类型;根据C99的要求显式使用int main(void)或int main(int argc,char ** argv)。
  • Do not play with chopping trailing nulls off your string.

    不要玩你的字符串中的尾随空格。

    char mode[4] = "0777";
    

    This prevents C from storing a terminal null - bad! Use:

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

    char mode[] = "0777";
    

    This allocates the 5 bytes needed to store the string with a null terminator.

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

  • Report errors on stderr, not stdout.

    报告stderr上的错误,而不是stdout。

  • Report errors with a newline at the end.
  • 最后用换行符报告错误。
  • It is good practice to include the program name and file name in the error message, and also (as CJY pointed out) to include the system error number and the corresponding string in the output. That requires the <string.h> header (for strerror()) and <errno.h> for errno. Additionally, the exit status of the program should indicate failure when the chmod() operation fails.
  • 最好在错误消息中包含程序名称和文件名,并且(如CJY指出的那样)在输出中包含系统错误号和相应的字符串。这需要 头(对于strerror())和 对于errno。此外,程序的退出状态应指示chmod()操作失败时的失败。

Putting all the changes together yields:

将所有变化放在一起产生:

#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);
}

Be careful with errno; it can change when functions are called. It is safe enough here, but in many scenarios, it is a good idea to capture errno into a local variable and use the local variable in printing operations, etc.

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

Note too that the code does no error checking on the result of strtol(). In this context, it is safe enough; if the user supplied the value, it would be a bad idea to trust them to get it right.

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


One last comment: generally, you should not use 777 permission on files (or directories). For files, it means that you don't mind who gets to modify your executable program, or how. This is usually not the case; you do care (or should care) who modifies your programs. Generally, don't make data files executable at all; when files are executable, do not give public write access and look askance at group write access. For directories, public write permission means you do not mind who removes any of the files in the directory (or adds files). Again, occasionally, this may be the correct permission setting to use, but it is very seldom correct. (For directories, it is usually a good idea to use the 'sticky bit' too: 1777 permission is what is typically used on /tmp, for example - but not on MacOS X.)

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