apache可移植运行时库中的文件IO

时间:2013-07-23 23:24:16

标签: c apr

在通过Zed Shaw学习C the Hard Way的过程中,我遇到了根据the documentation here具有类型签名的函数apr_dir_make_recursive()

apr_status_t apr_dir_make_recursive(const char *path, apr_fileperms_t perm, apr_pool_t *pool)

这使得该目录与Unix命令mkdir -p相同。

为什么IO功能需要内存池才能运行?

我的第一个想法是填充新制作的目录可能是一个可选参数,但是下面的代码使用了一个初始化但假定为空的内存池。这是否意味着IO函数本身需要一个内存池,我们传入它以供它使用?但这似乎也不太可能;该函数不能简单地创建一个本地内存池供它使用,然后在返回或出错时销毁它?

那么,内存池有什么用?在这一点上链接的文档是无益的。

代码缩短并显示在下面,为好奇。

int DB_init()
{
     apr_pool_t *p = NULL;
     apr_pool_initialize();
     apr_pool_create(&p, NULL);

     if(access(DB_DIR, W_OK | X_OK) == -1) {
          apr_status_t rc = apr_dir_make_recursive(DB_DIR,
               APR_UREAD | APR_UWRITE | APR_UEXECUTE |
               APR_GREAD | APR_GWRITE | APR_GEXECUTE, p);
     }

     if(access(DB_FILE, W_OK) == -1) {
          FILE *db = DB_open(DB_FILE, "w");
          check(db, "Cannot open database: %s", DB_FILE);
          DB_close(db);
     }

     apr_pool_destroy(p);
     return 0;

}

2 个答案:

答案 0 :(得分:1)

如果您提取来源,您会看到:apr_dir_make_recursive()来电path_remove_last_component()

static char *path_remove_last_component (const char *path, apr_pool_t *pool)
{
    const char *newpath = path_canonicalize (path, pool);
    int i;

    for (i = (strlen(newpath) - 1); i >= 0; i--) {
        if (path[i] == PATH_SEPARATOR)
            break;
    }

    return apr_pstrndup (pool, path, (i < 0) ? 0 : i);
}

此功能正在apr_pstrndup()创建路径的副本,每个路径代表一个较小的组件。

回答你的问题 - 因为它是如何实施的。是不是可以在不分配内存的情况下做同样的事情,是的。我认为在这种情况下,通过复制必要的路径组件,一切都变得更清晰,更具可读性。

答案 1 :(得分:0)

函数的实现(找到here)表明pool用于分配表示路径各个组件的字符串。

该函数不创建自己的本地池的原因是因为可以在对apr_*()函数的多次调用中重用该池。恰好DB_init()无需重用apr_pool_t