From e91dd46e3f65517ed9dbc6e431a56112a403cb3e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 28 Apr 2017 17:43:29 +0200 Subject: ident a CD without changing directory --- apt-pkg/contrib/cdromutl.cc | 46 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/apt-pkg/contrib/cdromutl.cc b/apt-pkg/contrib/cdromutl.cc index 428ef0161..3628f6173 100644 --- a/apt-pkg/contrib/cdromutl.cc +++ b/apt-pkg/contrib/cdromutl.cc @@ -184,26 +184,32 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version) MD5Summation Hash; bool writable_media = false; + int dirfd = open(CD.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC); + if (dirfd == -1) + return _error->Errno("open",_("Unable to read %s"),CD.c_str()); + // if we are on a writable medium (like a usb-stick) that is just // used like a cdrom don't use "." as it will constantly change, // use .disk instead - if (access(CD.c_str(), W_OK) == 0 && DirectoryExists(CD+string("/.disk"))) + if (faccessat(dirfd, ".", W_OK, 0) == 0) { - writable_media = true; - CD = CD.append("/.disk"); - if (_config->FindB("Debug::aptcdrom",false) == true) - std::clog << "Found writable cdrom, using alternative path: " << CD - << std::endl; + int diskfd = openat(dirfd, "./.disk", O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0); + if (diskfd != -1) + { + close(dirfd); + dirfd = diskfd; + writable_media = true; + CD = CD.append("/.disk"); + if (_config->FindB("Debug::aptcdrom",false) == true) + std::clog << "Found writable cdrom, using alternative path: " << CD + << std::endl; + } } - string StartDir = SafeGetCWD(); - if (chdir(CD.c_str()) != 0) - return _error->Errno("chdir",_("Unable to change to %s"),CD.c_str()); - - DIR *D = opendir("."); - if (D == 0) + DIR * const D = fdopendir(dirfd); + if (D == nullptr) return _error->Errno("opendir",_("Unable to read %s"),CD.c_str()); - + /* Run over the directory, we assume that the reader order will never change as the media is read-only. In theory if the kernel did some sort of wacked caching this might not be true.. */ @@ -222,31 +228,24 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version) else { struct stat Buf; - if (stat(Dir->d_name,&Buf) != 0) + if (fstatat(dirfd, Dir->d_name, &Buf, 0) != 0) continue; strprintf(S, "%lu", (unsigned long)Buf.st_mtime); } Hash.Add(S.c_str()); Hash.Add(Dir->d_name); - }; - - if (chdir(StartDir.c_str()) != 0) { - _error->Errno("chdir",_("Unable to change to %s"),StartDir.c_str()); - closedir(D); - return false; } - closedir(D); // Some stats from the fsys std::string S; if (_config->FindB("Debug::identcdrom",false) == false) { struct statvfs Buf; - if (statvfs(CD.c_str(),&Buf) != 0) + if (fstatvfs(dirfd, &Buf) != 0) return _error->Errno("statfs",_("Failed to stat the cdrom")); - // We use a kilobyte block size to advoid overflow + // We use a kilobyte block size to avoid overflow if (writable_media) { strprintf(S, "%lu", (unsigned long)(Buf.f_blocks*(Buf.f_bsize/1024))); @@ -260,6 +259,7 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version) else strprintf(S, "-%u.debug", Version); + closedir(D); Res = Hash.Result().Value() + S; return true; } -- cgit v1.2.3