17             "preserve atime of inpout files", 
false);
 
   28                                    std::vector<char>& target) {
 
   30         auto linklength = readlink(path.c_str(), target.data(), target.size());
 
   31         if (linklength == -1 && errno == ENOENT) {
 
   35         if (linklength >= 
static_cast<ssize_t
>(target.size())) {
 
   36             throw std::runtime_error(
"link size increased after stat for " + path);
 
   38         target[linklength] = 
'\0';
 
   51             fd = open(
path.c_str(), O_RDONLY);
 
   64                              "can't advise ", 
path, 
" as sequential");
 
   69                              "can't advise ", 
path, 
" as use only once");
 
   79                                  path, 
"close during unwind ",
 
   80                                  std::system_category().default_error_condition(errno).message());
 
   85                 struct timespec times[2];
 
   86                 readInitialStat.getAtime(times[0]);
 
   87                 times[1].tv_nsec = UTIME_OMIT; 
 
   89                 throwcall::good0(futimens(fd, times), 
"can't set time stamps on ", path, 
" to old values");
 
  104         if (readInitialStat.size < readInitialStat.blksize) { 
 
  107         if (sparseHandling == 
"auto" &&
 
  108             readInitialStat.size <= readInitialStat.sizeOnDisk) {
 
  110         } 
else if (sparseHandling == 
"never") {
 
  113         auto what = SEEK_HOLE;
 
  114         for (std::remove_const<decltype(readInitialStat.size)>::type pos = 0;
 
  115                 pos < readInitialStat.size;
 
  116                 what = what == SEEK_HOLE ? SEEK_DATA : SEEK_HOLE) {
 
  119             auto result = lseek(fd, pos, what);
 
  120             if (result == -1 && errno == ENXIO) { 
 
  121                 next = readInitialStat.size;
 
  124                                   "seek ", path, 
" for ", what == SEEK_HOLE ? 
"hole" : 
"data",
 
  125                                   ", from offset ", pos);
 
  129                 regions.emplace_back(pos, next, what == SEEK_DATA);
 
  135         return !regions.empty();
 
  141                           -1, 
"can't seek ", path, 
" to ", pos);
 
  142         if (! regions.empty()) {
 
  143             while (regions.front().getEnd() < pos) {
 
  145                 if (regions.empty()) {
 
  152         return regions.empty();
 
  155         b.
clear(totalBytesRead);
 
  156         bool lastblock = 
false;
 
  159         if (!regions.empty()) {
 
  160             auto region = regions.front();
 
  161             if (region.isHole()) {
 
  166                 auto result = lseek(fd, totalBytesRead, SEEK_DATA);
 
  167                 if (result == -1 && errno == ENXIO) { 
 
  168                     nextData = region.getEnd();
 
  170                     throwcall::badval(result, -1, 
"seek in ", path, 
" to data after ", totalBytesRead);
 
  173                 totalBytesRead += region.size(); 
 
  174                 if (nextData != totalBytesRead) {
 
  176                                              std::to_string(totalBytesRead) +
 
  178                                              std::to_string(nextData) +
 
  182                 return regions.empty();
 
  184                 if (region.getEnd() < totalBytesRead + bytesToRead) {
 
  185                     bytesToRead = region.getEnd() - totalBytesRead; 
 
  187                 if (region.getEnd() == totalBytesRead + bytesToRead) { 
 
  193         while (b.
size() + blockSize <= bytesToRead) {
 
  197                                                 -1, 
"read failed on ", path);
 
  199             if (bytes_read == 0) {
 
  201                 if (totalBytesRead < readInitialStat.size) {
 
  203                                              std::to_string(readInitialStat.size) +
 
  205                                              std::to_string(totalBytesRead) +
 
  210             totalBytesRead += bytes_read;
 
  211             if (totalBytesRead > readInitialStat.size) {
 
  213                                          std::to_string(readInitialStat.size) +
 
  215                                          std::to_string(totalBytesRead) +
 
  227         if (!regions.empty()) {
 
  228             throw std::logic_error(
"parallel read attempted on sparse file");
 
  234                                                 -1, 
"read failed on ", path);
 
  235             if (bytes_read == 0) {
 
  239             if (b.
size() > bytesToRead) {
 
  243         if (b.
size() < bytesToRead) {
 
  245                                      + std::to_string(bytesToRead)
 
  247                                      + std::to_string(b.
size()));
 
  253         struct stat readFinalStatBuf;
 
  256             throwcall::good0(fstat(fd, &readFinalStatBuf), 
"can't stat path file ", path);
 
  258         genericStat readFinalStat(readFinalStatBuf, std::chrono::nanoseconds(1));
 
  259         if (readFinalStat.
size != readInitialStat.size) {
 
  261                                      std::to_string(readInitialStat.size) +
 
  263                                      std::to_string(readFinalStat.
size) +
 
  264                                      ") during reading on " + path);
 
  269                                      std::to_string(std::chrono::duration_cast<std::chrono::duration<double>>(readFinalStat.
getMtime() - readInitialStat.getMtime()).count()) +
 
  270                                      "s different mtime) during reading");
 
  279             if (closedir(dir) != 0) {
 
  281                              "", 
"close directory during unwind ",
 
  282                              std::system_category().default_error_condition(errno).message());
 
  292         while (
auto entry = readdir(dir)) {
 
  294             if (entry->d_name[entry->d_name[0] != 
'.' ? 0 : entry->d_name[1] != 
'.' ? 1 : 2] == 
'\0') {
 
  301                 auto result = fstatat(dirfd(dir), entry->d_name, &statbuf, AT_SYMLINK_NOFOLLOW);
 
  302                 if (result != 0 && errno == ENOENT && ignoreMissing) {
 
  307             auto genStat = std::unique_ptr<const genericStat>(
new genericStat(statbuf, std::chrono::nanoseconds(1)));
 
  308             return std::unique_ptr<Entry>(
new Entry(entry->d_name, genStat));