X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=updatedb.cpp;h=a10a3e7818dbc9bfbefe867700e895648aac9f04;hb=068e02eec22686074a5c1e026140b601c8d61ab6;hp=4ead43f66c2493bf98ed5af3fa8c2163b6aa1284;hpb=5aea0223dcff337761ee1cd56e62a8064b133ec2;p=plocate diff --git a/updatedb.cpp b/updatedb.cpp index 4ead43f..a10a3e7 100644 --- a/updatedb.cpp +++ b/updatedb.cpp @@ -610,8 +610,12 @@ int scan(const string &path, int fd, dev_t parent_dev, dir_time modified, dir_ti } else { dir = fdopendir(fd); // Takes over ownership of fd. if (dir == nullptr) { - perror("fdopendir"); - exit(1); + // fdopendir() wants to fstat() the fd to verify that it's indeed + // a directory, which can seemingly fail on at least CIFS filesystems + // if the server feels like it. We treat this as if we had an error + // on opening it, ie., ignore the directory. + close(fd); + return 0; } dirent *de; @@ -703,8 +707,8 @@ int scan(const string &path, int fd, dev_t parent_dev, dir_time modified, dir_ti if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) { fprintf(stderr, "Hint: Try `ulimit -n 131072' or similar.\n"); } else { - fprintf(stderr, "Hint: Try `ulimit -n %lu' or similar (current limit is %lu).\n", - rlim.rlim_cur * 2, rlim.rlim_cur); + fprintf(stderr, "Hint: Try `ulimit -n %" PRIu64 " or similar (current limit is %" PRIu64 ").\n", + static_cast(rlim.rlim_cur * 2), static_cast(rlim.rlim_cur)); } exit(1); } @@ -713,6 +717,20 @@ int scan(const string &path, int fd, dev_t parent_dev, dir_time modified, dir_ti struct stat buf; if (fstat(e.fd, &buf) != 0) { + // It's possible that this is a filesystem that's excluded + // (and the failure is e.g. because the network is down). + // As a last-ditch effort, we try to check that before dying, + // i.e., duplicate the check from further down. + // + // It would be better to be able to run filesystem_is_excluded() + // for cheap on everything and just avoid the stat, but it seems + // hard to do that without any kind of raciness. + if (filesystem_is_excluded((path_plus_slash + e.name).c_str())) { + close(e.fd); + e.fd = -1; + continue; + } + perror((path_plus_slash + e.name).c_str()); exit(1); }