C语言 在 C 程序中使用 chmod
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4568681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using chmod in a C program
提问by Raghav
I have a program where I need to set the permissions of a file (say /home/hello.t) using chmodand 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.
我有一个程序,我需要在其中设置文件的权限(例如/home/hello.t)chmod,我必须读取要从文件中设置的权限。为此,我首先将权限读入字符数组,然后尝试修改文件的权限。但是我看到权限的设置方式很奇怪。
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。你能帮我从字符数组中读取相同的文件后如何设置文件的权限吗?
回答by Jonathan Leffler
The atoi()function only translates decimal, not octal.
该atoi()函数只转换十进制,不转换八进制。
For octal conversion, use strtol()(or, as Chris Jester-Youngpoints out, strtoul()- though the valid sizes of file permission modes for Unix all fit within 16 bits, and so will never produce a negative longanyway) 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 位以内,因此long无论如何都不会产生负数)以 0 或 8 作为基数. 实际上,在这种情况下,最好指定 8。它允许人们写 777 并获得正确的八进制值。指定基数为 0 时,字符串 777 是十进制(再次)。
Additionally:
此外:
- Do not use 'implicit int' return type for
main(); be explicit as required by C99 and useint main(void)orint 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:char mode[] = "0777";This allocates the 5 bytes needed to store the string with a null terminator.
Report errors on
stderr, notstdout.- 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 (forstrerror()) and<errno.h>forerrno. Additionally, the exit status of the program should indicate failure when thechmod()operation fails.
- 不要使用“隐式 int”返回类型
main();按照 C99 的要求进行明确并使用int main(void)或int main(int argc, char **argv)。 不要从字符串中切掉尾随空值。
char mode[4] = "0777";这可以防止 C 存储终端 null - 不好!用:char mode[] = "0777";这分配了存储带有空终止符的字符串所需的 5 个字节。
报告错误
stderr,而不是stdout。- 最后用换行符报告错误。
- 在错误消息中包含程序名和文件名是一种很好的做法,并且(正如 CJY 指出的那样)在输出中包含系统错误号和相应的字符串。这需要
<string.h>标头 (forstrerror()) 和<errno.h>forerrno。此外,当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 errnointo 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 权限。对于文件,这意味着您不介意谁可以修改您的可执行程序,或者如何修改。通常情况并非如此。您确实关心(或应该关心)谁修改了您的程序。通常,根本不要使数据文件可执行;当文件是可执行文件时,不要给予公共写访问权限,并斜视组写访问权限。对于目录,公共写权限意味着您不介意谁删除目录中的任何文件(或添加文件)。同样,偶尔,这可能是要使用的正确权限设置,但很少正确。(对于目录,使用“粘滞位”通常也是一个好主意:例如,1777 权限通常用于/tmp,但不适用于 MacOS X。)

