* @brief trim rolled files to max number of rolled files, older first * * @param rolling_max_count - limit to which rolled files will be trimmed * @return true if success, false if failure */
| 280 | * @return true if success, false if failure |
| 281 | */ |
| 282 | bool |
| 283 | LogFile::trim_rolled(size_t rolling_max_count) |
| 284 | { |
| 285 | // man: "dirname() may modify the contents of path, so it may be desirable to pass a copy when calling one of these functions." |
| 286 | char *name = ats_strdup(m_name); |
| 287 | std::string logfile_dir(::dirname((name))); |
| 288 | ats_free(name); |
| 289 | |
| 290 | // Open the directory |
| 291 | int dirfd = open(logfile_dir.c_str(), O_RDONLY); |
| 292 | if (dirfd < 0) { |
| 293 | Error("Error opening logging directory %s to collect trim candidates: %s", logfile_dir.c_str(), strerror(errno)); |
| 294 | return false; |
| 295 | } |
| 296 | |
| 297 | // Check logging directory access |
| 298 | int err; |
| 299 | do { |
| 300 | err = faccessat(dirfd, logfile_dir.c_str(), R_OK | W_OK | X_OK, 0); |
| 301 | } while ((err < 0) && (errno == EINTR)); |
| 302 | |
| 303 | if (err < 0) { |
| 304 | close(dirfd); |
| 305 | Error("Error accessing logging directory %s: %s", logfile_dir.c_str(), strerror(errno)); |
| 306 | return false; |
| 307 | } |
| 308 | |
| 309 | // Open the logging directory |
| 310 | DIR *ld = fdopendir(dirfd); |
| 311 | if (ld == nullptr) { |
| 312 | close(dirfd); |
| 313 | Error("Error opening logging directory %s to collect trim candidates: %s", logfile_dir.c_str(), strerror(errno)); |
| 314 | return false; |
| 315 | } |
| 316 | |
| 317 | // Collect the rolled file names from the logging directory that match the specified log file name |
| 318 | std::vector<RolledFile> rolled; |
| 319 | char path[MAXPATHLEN]; |
| 320 | struct dirent *entry; |
| 321 | while ((entry = readdir(ld))) { |
| 322 | struct stat sbuf; |
| 323 | snprintf(path, MAXPATHLEN, "%s/%s", logfile_dir.c_str(), entry->d_name); |
| 324 | int sret = ::stat(path, &sbuf); |
| 325 | if (sret != -1 && S_ISREG(sbuf.st_mode)) { |
| 326 | int name_len = strlen(m_name); |
| 327 | int path_len = strlen(path); |
| 328 | if (path_len > name_len && 0 == ::strncmp(m_name, path, name_len) && LogFile::rolled_logfile(entry->d_name)) { |
| 329 | rolled.push_back(RolledFile(path, sbuf.st_mtime)); |
| 330 | } |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | closedir(ld); |
| 335 | |
| 336 | bool result = true; |
| 337 | std::sort(rolled.begin(), rolled.end(), [](const RolledFile &a, const RolledFile &b) { return a._mtime > b._mtime; }); |
| 338 | if (rolling_max_count < rolled.size()) { |
| 339 | for (auto it = rolled.begin() + rolling_max_count; it != rolled.end(); it++) { |