Search code examples
clinuxubuntu-14.04stat

Does sys function call "stat" change my file?


I am currently trying to make "C" a little bit more scripting language like for myself. I writing my program specific code in a *.so file reload this file at runtime and execute the new code i wrote.

The problem i am facing is the result of the function "stat". Everytime i ask if the SO file has been modified via "stat(filename,statbuf)" the result stat->mtim always seems to have been changed. As result i continously reload my code in each loop run.

I have assumed that if no file change to a file happend st_mtime has to be always the same. Am i wrong?

Here the function how i retrieve the value st_mtime:

inline timespec LinuxGetLastWriteTime(const std::string& filename) {
    struct stat *buf;

    stat(filename.c_str(), buf);

    return buf->st_mtim;
}

And here where i check if i have to reload:

timespec NewSOWriteTime = LinuxGetLastWriteTime(SoSource);
if ( Game.last_modification  != NewSOWriteTime ) {
        LinuxUnloadGameCode(&Game);
        Game = LinuxLoadGameCode(SoSource, "libCode_temp.so");
}

and my two overloads of the != and <:

bool operator<(const timespec& lhs, const timespec& rhs) {
    if (lhs.tv_sec == rhs.tv_sec)
        return lhs.tv_nsec < rhs.tv_nsec;
    else
        return lhs.tv_sec < rhs.tv_sec;
}

bool operator!=(const timespec& lhs, const timespec& rhs) {
    if (lhs.tv_sec == rhs.tv_sec)
        return lhs.tv_nsec != rhs.tv_nsec;
    else
        return lhs.tv_sec != rhs.tv_sec;

Any Idea why this could can happen


Solution

  • The code you use:

    struct stat *buf;
    
    stat(filename.c_str(), buf);
    
    return buf->st_mtim;
    

    is strange, to say the least. You got unlucky and it didn't crash instantly, but noone really knows where it writes results; probably overwrking some other important data on the way. You should allocate buf yourself and pass its address to stat, e.g.:

    struct stat buf = {0};    // or memset(0)
    stat(filename.c_str(), &buf);
    return buf.st_mtim;
    

    You probably should also check error status of stat, but if buffer is zeroed it will just return 0 which may be fine.