c - SQLite3 sqlite3_open 成功,sqlite3_exec 失败并显示 CANTOPEN(错误 14)

标签 c sqlite

我有这段代码,它在 C 中使用了 SQLite:

int settings_set(const char *name, const char *value) {
    int r = SQLITE_ERROR;
    int res = sqlite3_open(PERSISTENTDB, &db_persistent);
    if (SQLITE_OK == res) {
        char *sql = sqlite3_mprintf("REPLACE INTO settings VALUES ('%q', '%q')", name, value);
        r = sqlite3_exec(db_persistent, sql, 0, 0, 0);
        if (SQLITE_OK == r) {
            log_write(LVL_NOTICE, "[data] set setting '%s' to '%s'\n", name, value);
        } else {
            log_write(LVL_NOTICE, "[data] failed to set setting '%s' to '%s': code %d\n", name, value, r);
        }
        sqlite3_close(db_persistent);
        sqlite3_free(sql);
    } else {
        log_write(LVL_NOTICE, "[data] settings_set(): could not open persistent database: code %d\n", res);
    }

    return r;
}

当此代码以 root 身份运行时(数据库文件设置为 rw-rw-rw- 并由 root 拥有),这工作正常。当以 nobody 身份运行时,我在 sqlite3_exec 调用中收到错误代码 14 (SQLITE_CANTOPEN)。所以,显然 sqlite3_open 调用成功了。我预计此错误会发生在公开通话中。

最佳答案

您的非根用户可能没有在托管数据库的目录中创建和写入新文件的权限。

documentation对于该错误代码状态:

The file in question might be a primary database file or on of several temporary disk files.

SQLite 会创建临时文件,至少在您修改数据库时是这样。如果您的非根进程无法创建这些,您将收到该错误。您可以通过在 strace 中运行您的程序来验证这一点,例如像这样的东西:

strace -e trace=open ./a.out

您将看到对 open 的哪些调用失败了(可能是针对日志文件),以及原因是什么。

关于c - SQLite3 sqlite3_open 成功,sqlite3_exec 失败并显示 CANTOPEN(错误 14),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26546150/

相关文章:

java - 谁在 ubuntu 服务器上神秘地向我的进程发送了 SIGKILL

c - 函数指针的别名

android - 从 sqlite 触发器调用 Java 方法 (android)

android - Android记事本教程中存储SQLite数据库

ios - FMDB:NULL 值被检索为空字符串

c - 使用 char 的大写和小写

c - 实现条目超时的 C 哈希表的最有效方法是什么?

c - 为什么调用AddNode()函数后大小等于二叉树中添加的数据?

java - Android 无法打开现有的 SQLite 数据库文件

java - Android - 卸载应用程序时未删除 Sqlite 数据库文件?