问题描述
在C项目中,我正在尝试在特定目录中创建目录。
// Find the user's home directory.
// Code from https://stackoverflow.com/a/2910392/14602523
struct passwd * pw = getpwuid(getuid());
char * home = pw->pw_dir;
// Test if the ".junk" directory exists in the home directory.
// If not,create it.
if (opendir(strcat(home,"/.junk/")) == NULL) {
printf(" - no junk directory\n");
if (mkdir(strcat(home,"/.junk/"),0777) < 0) {
fprintf(stderr,"Error: Cannot create junk directory.\n");
perror(" - errno");
exit(1);
}
}
opendir()
正常工作:如果.junk/
中存在名为~/
的目录,那么我不会收到任何打印消息,如果该目录不存在,那么我会得到一些提示输出。但是mkdir()
确实很严格,并且引起很多问题。如果~/.junk/
不存在,那么我得到以下输出:
- no junk directory
Error: Cannot create junk directory.
- errno: No such file or directory
但是,如果我尝试在当前目录中创建目录,例如mkdir("./.junk/",0777)
,则目录创建正确。这是怎么回事?为什么在~/
中它的行为有所不同,我如何使它工作?
解决方法
您已将home
设置为pw->pw_dir
,它被定义为类型char *
,并且您试图将其追加。无法保证pw->pw_dir
指向的内容具有足够的空间来附加其他字符。您很有可能正在写完缓冲区的末尾。
即使不覆盖缓冲区,也要两次附加“ /.junk”,因此传递给mkdir
的字符串是“ home / .junk //。junk”
您需要为完整的目录名称创建一个单独的字符串,该字符串的大小足以容纳它并在其中进行构建。
struct passwd * pw = getpwuid(getuid());
char * home = pw->pw_dir;
char junk_dir[strlen(pw->pw_dir) + strlen("/.junk/") + 1];
sprintf(junk_dir,"%s/.junk/",home);
// Test if the ".junk" directory exists in the home directory.
// If not,create it.
if (opendir(junk_dir) == NULL) {
printf(" - no junk directory\n");
if (mkdir(junk_dir),0777) < 0) {
fprintf(stderr,"Error: Cannot create junk directory.\n");
perror(" - errno");
exit(1);
}
}
,
-
strcat
附加到适当的字符串。从getpwuid
返回的字符串根本不打算写。 -
当然不能保证它后面有可用空间,所以您不能安全地追加到它。
-
即使可以,您也会两次调用
strcat
,所以传递给mkdir
的字符串类似于/home/zach/.junk//.junk/
,在尝试创建时会失败您刚刚确定的/home/zach/.junk
中的目录不存在。
编写此代码的方式就好像您认为字符串是C中的“一流”对象一样,可以像许多其他语言一样将其纯粹作为值进行操作。好吧,它们不是-它们是字符数组,就像所有其他数组一样,内存管理由您决定。