• M
    virtestmock: Mock stat() properly · 49c1a078
    Michal Privoznik 提交于
    There is a lot to explain, but I try to make it as short as
    possible. I'd start by pasting some parts of sys/stat.h:
    
    extern int stat (const char *__restrict __file,
    		 struct stat *__restrict __buf) __THROW __nonnull ((1, 2));
    
    extern int __REDIRECT_NTH (stat, (const char *__restrict __file,
    				  struct stat *__restrict __buf), stat64)
         __nonnull ((1, 2));
    
    __extern_inline int
    __NTH (stat (const char *__path, struct stat *__statbuf))
    {
      return __xstat (_STAT_VER, __path, __statbuf);
    }
    
    Only one of these is effective at once, due to some usage of
    the mess we are dealing with in here. So, basically, while
    compiling or linking stat() in our code can be transformed into
    some other func. Or a dragon.
    Now, if you read stat(2) manpage, esp. "C library/kernel
    differences" section, you'll learn that glibc uses some tricks
    for older applications to work. I haven't gotten around actual
    code that does this, but based on my observations, if 'stat'
    symbol is found, glibc assumes it's dealing with ancient
    application. Unfortunately, it can be just ours stat coming from
    our mock. Therefore, calling stat() from a test will end up in
    our mock. But since glibc is not exposing the symbol anymore, our
    call of real_stat() will SIGSEGV immediately as the pointer to
    function is NULL. Therefore, we should expose only those symbols
    we know glibc has.
    Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
    49c1a078
virtestmock.c 7.6 KB