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 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);
    }
}
,
  1. strcat附加到适当的字符串。从getpwuid返回的字符串根本不打算写。

  2. 当然不能保证它后面有可用空间,所以您不能安全地追加到它。

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

编写此代码的方式就好像您认为字符串是C中的“一流”对象一样,可以像许多其他语言一样将其纯粹作为值进行操作。好吧,它们不是-它们是字符数组,就像所有其他数组一样,内存管理由您决定。