c-mkdir()存在多个问题



在一个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 directoryn");
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),则目录创建正确。怎么回事?为什么它在~/中的作用不同?我如何让它发挥作用?

  1. strcat在适当位置附加到字符串。从getpwuid返回的字符串根本不是要写入的。

  2. 它肯定不能保证后面有任何可用空间,所以你不能安全地附加到它上

  3. 即使可以,您也要调用strcat两次,所以传递给mkdir的字符串类似于/home/zach/.junk//.junk/,当您试图在/home/zach/.junk中创建一个您刚刚确定不存在的目录时,它将失败。

编写此代码时,就好像您认为字符串是";第一类";对象,可以像在许多其他语言中一样纯粹作为值进行操作。它们不是——它们是字符数组,和所有其他数组一样,内存管理由您决定。

您将home设置为pw->pw_dir,定义为类型char *,并且您正在尝试对其进行追加。无法保证pw->pw_dir指向的内容有足够的空间来追加其他字符。你很有可能写得超过了缓冲区的末尾。

即使您没有覆盖缓冲区,您也在附加"/。垃圾;两次,所以传递给mkdir的字符串是";home/.垃圾//.垃圾";

您需要为完整的目录名创建一个单独的字符串,这个字符串足够大,可以容纳它并在那里构建它。

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 directoryn");
if (mkdir(junk_dir), 0777) < 0) {
fprintf(stderr, "Error: Cannot create junk directory.n");
perror(" - errno");
exit(1);
}
}

最新更新