SMB_STRUCT_STAT *sbuf)
{
struct dirent *result;
+ bool do_stat = false;
+ bool fake_ctime = lp_fake_directory_create_times(SNUM(handle->conn));
+ int flags = AT_SYMLINK_NOFOLLOW;
+ struct stat st;
+ int ret;
START_PROFILE(syscall_readdir);
- result = readdir(dirp);
- END_PROFILE(syscall_readdir);
- if (sbuf) {
- /* Default Posix readdir() does not give us stat info.
- * Set to invalid to indicate we didn't return this info. */
- SET_STAT_INVALID(*sbuf);
+
#if defined(HAVE_DIRFD) && defined(HAVE_FSTATAT)
- if (result != NULL) {
- /* See if we can efficiently return this. */
- struct stat st;
- int flags = AT_SYMLINK_NOFOLLOW;
- int ret = fstatat(dirfd(dirp),
- result->d_name,
- &st,
- flags);
- /*
- * As this is an optimization,
- * ignore it if we stat'ed a
- * symlink. Make the caller
- * do it again as we don't
- * know if they wanted the link
- * info, or its target info.
- */
- if ((ret == 0) && (!S_ISLNK(st.st_mode))) {
- init_stat_ex_from_stat(sbuf,
- &st,
- lp_fake_directory_create_times(
- SNUM(handle->conn)));
- }
- }
+ do_stat = true;
#endif
+
+ result = readdir(dirp);
+ END_PROFILE(syscall_readdir);
+
+ if (sbuf == NULL) {
+ return result;
+ }
+ if (result == NULL) {
+ return NULL;
}
+
+ /*
+ * Default Posix readdir() does not give us stat info.
+ * Set to invalid to indicate we didn't return this info.
+ */
+ SET_STAT_INVALID(*sbuf);
+
+ /* See if we can efficiently return this. */
+ if (!do_stat) {
+ return result;
+ }
+
+ ret = fstatat(dirfd(dirp),
+ result->d_name,
+ &st,
+ flags);
+ if (ret != 0) {
+ return result;
+ }
+
+ /*
+ * As this is an optimization, ignore it if we stat'ed a
+ * symlink. Make the caller do it again as we don't know if
+ * they wanted the link info, or its target info.
+ */
+ if (S_ISLNK(st.st_mode)) {
+ return result;
+ }
+ init_stat_ex_from_stat(sbuf, &st, fake_ctime);
+
return result;
}