I wrote: > Justin Pryzby <pry...@telsasoft.com> writes: >> Maybe we should lstat() the file to determine if it's a dangling link; if >> lstat() fails, then skip it. Currently, we use stat(), which shows metdata >> of >> a link's *target*. Maybe we'd change that.
> Hm, good point that ENOENT could refer to a symlink's target. Still, > I'm not sure it's worth going out of our way to disambiguate that, > given that these directories aren't really supposed to contain symlinks. > (And on the third hand, if they aren't supposed to, then maybe these > functions needn't look through any symlinks? In which case just > substituting lstat for stat would resolve the ambiguity.) After looking at the callers of pg_ls_dir_files, and noticing that it's already defined to ignore anything that's not a regular file, I think switching to lstat makes sense. I also grepped the other uses of ReadDir[Extended], and didn't see any other ones that seemed desperately in need of changing. So the attached seems like a sufficient fix. regards, tom lane
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index 01185f2..8429a12 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -596,10 +596,15 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok) /* Get the file info */ snprintf(path, sizeof(path), "%s/%s", dir, de->d_name); - if (stat(path, &attrib) < 0) + if (lstat(path, &attrib) < 0) + { + /* Ignore concurrently-deleted files, else complain */ + if (errno == ENOENT) + continue; ereport(ERROR, (errcode_for_file_access(), errmsg("could not stat file \"%s\": %m", path))); + } /* Ignore anything but regular files */ if (!S_ISREG(attrib.st_mode))