Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Does sqlite3 use errno codes?

Tags:

c++

sqlite

errno

I am using the sqlite3 C++ api. After running

int rc = sqlite3_exec(db, pSQL, 0, 0, 0);

which returns a rc result of SQLITE_OK.

Additionally, I have tested for errno != 0. The result of cout << strerror(errno) << endl is consistently: No such file or directory

In other words, I know that sqlite3 has its own set of "Return Codes" (i.e. SQLITE_OK). However, does sqlite3 use errno codes correctly/consistently? That is, if another part of my application is using the global errno variable, should I be resetting it after every call to sqlite3_exec?

Thanks.


A more complete example of my code:

    const int errno_start = errno;
    if (errno_start > 0) {
        std::cout << "errno=" << strerror(errno) << std::endl;
        std::cout << "errno_start=" << strerror(errno_start) << std::endl;
    }
    // prepare sql statement
    const char *pSQL;
    pSQL = "CREATE TABLE "
            "IF NOT EXISTS "
            "test1"
            "("
            "id INTEGER,"
            "field VARCHAR(32),"
            "value DOUBLE,"
            "timestamp DATETIME"
            ")";

    //int rc = sqlite3_exec(db, pSQL, callback, 0, &szErrMsg);
    int rc = sqlite3_exec(db, pSQL, 0, 0, 0);
    const int errno_here1 = errno;
    if (errno_here1 > 0) {
        std::cout << "errno_start=" << strerror(errno_start) << ", errno_here1="
                << strerror(errno_here1) << std::endl;
    }
    if (rc != SQLITE_OK) {
        std::cout << "SQL Error: " << szErrMsg << std::endl;
        sqlite3_free(szErrMsg);
    } else {
        std::cout << "initialize successful" << std::endl;
    }

Result from this snippet is:

errno_start=Success, errno_here1=No such file or directory

initialize successful

like image 785
kmccoy Avatar asked Sep 07 '25 09:09

kmccoy


1 Answers

You should never rely on the value in errno to persist beyond the next OS call, as pretty much any OS call that can fail (i.e., almost all of them) may set it. At least there's one thing though: errno is now usually a thread-local behind the scenes. Still, a library may well set errno when you call into it, so it is wise to save the value immediately after a failing system call and ignore it otherwise.

SQLite makes OS calls inside itself (when it accesses the DB file, of course) so it may well set errno to virtually anything. The errors that it encounters are handled inside it; if there's something wrong, it will tell you using its own, documented error mechanism. That never includes any information from errno as it happens (and in fact that would be non-portable; SQLite runs on Windows as well, and that uses a different error code reporting mechanism).

like image 65
Donal Fellows Avatar answered Sep 09 '25 05:09

Donal Fellows