/* Contributed by Philipp Hachtmann in version 0.6 */ int __fxstat64 (int ver, int fildes, struct stat64 *buf) { static int (*real_fstat)(int, int , struct stat64 *); static int has_real_fstat=0; SINGLE_IF(has_real_fstat==0) real_fstat = NULL; real_fstat = dlsym(RTLD_NEXT, "__fxstat64"); if (dlerror() == NULL) { has_real_fstat = 1; } END_SINGLE_IF if (!has_real_fstat) { /* dlsym() failed */ #ifdef DEBUG (void) fprintf(stderr, "faketime problem: original fstat() not found.\n"); #endif return -1; /* propagate error to caller */ } int result = real_fstat(ver, fildes, buf); if (result == -1){ return -1; } if (buf != NULL){ if (!fake_stat_disabled) { buf->st_ctime = fake_time(&(buf->st_ctime)); buf->st_atime = fake_time(&(buf->st_atime)); buf->st_mtime = fake_time(&(buf->st_mtime)); } } return result; }
int sb2_fstat(int fd, struct stat *statbuf) { SB_LOG(SB_LOGLEVEL_NOISE, "sb2_fstat(%d)", fd); if (real_fstat(fd, statbuf) < 0) return(-1); i_virtualize_struct_stat(__func__, statbuf, NULL); return(0); }
int fstat(int fd, void *st) { #if HAVE___LXSTAT return __fxstat(0, fd, st); #else if (smbw_fd(fd)) { return smbw_fstat(fd, st); } return real_fstat(fd, st); #endif }
int __fxstat(int vers, int fd, void *st) { double xx[32]; int ret; if (smbw_fd(fd)) { return smbw_fstat(fd, st); } ret = real_fstat(fd, xx); xstat_convert(vers, st, xx); return ret; }
void stat_cache_update_fd(struct hash *hash, int fd, const struct hash *path_hash) { initialize(); // lstat the file struct stat st; if (real_fstat(fd, &st) < 0) die("fstat(%d) failed: %s", fd, strerror(errno)); // For now we go the simple route and hold the stat_cache lock for the // entire duration of the hash computation. In future we may want to drop // the lock while we compute the hash. Alternatively, switching to a finer // grain locking discipline might avoid the problem. shared_map_lock(&stat_cache); // Lookup entry, creating it if necessary, and check if it's up to date struct stat_cache_entry *entry; if (!shared_map_lookup(&stat_cache, path_hash, (void**)&entry, 1) || entry->st_mtimespec.tv_nsec != st.st_mtimespec.tv_nsec || entry->st_mtimespec.tv_sec != st.st_mtimespec.tv_sec || entry->st_size != st.st_size || entry->st_ino != st.st_ino || hash_is_all_one(&entry->contents_hash)) { // Entry is new or out of date. In either case, compute hash and // record new stat details. entry->st_ino = st.st_ino; entry->st_mtimespec = st.st_mtimespec; entry->st_size = st.st_size; // Hash the file if (lseek(fd, 0, SEEK_SET) < 0) die("lseek failed: %s", strerror(errno)); hash_fd(&entry->contents_hash, fd); } shared_map_unlock(&stat_cache); *hash = entry->contents_hash; }