| 438 | } |
| 439 | |
| 440 | bool LoadPlugins(const std::string &directory) { |
| 441 | DIR *dir = opendir(directory.c_str()); |
| 442 | if (!dir) { |
| 443 | return false; |
| 444 | } |
| 445 | |
| 446 | std::list<std::string> remaining; |
| 447 | dirent *entry; |
| 448 | while ((entry = readdir(dir)) != nullptr) { |
| 449 | if ((entry->d_type == DT_REG || entry->d_type == DT_LNK) && |
| 450 | HasSuffix(entry->d_name, ".so")) { |
| 451 | const std::string full_path = directory + "/" + entry->d_name; |
| 452 | remaining.push_back(full_path); |
| 453 | } |
| 454 | } |
| 455 | |
| 456 | for (int pass = 1; pass <= kInheritanceLimit && remaining.size() > 0; |
| 457 | ++pass) { |
| 458 | for (auto it = remaining.begin(); it != remaining.end();) { |
| 459 | const std::string full_path = *it; |
| 460 | LOG(INFO) << "Loading plugin (attempt " << pass << "): " << full_path; |
| 461 | if (!LoadPlugin(full_path)) { |
| 462 | VLOG(1) << "Error loading plugin " << full_path |
| 463 | << "dlerror=" << dlerror(); |
| 464 | ++it; |
| 465 | } else { |
| 466 | it = remaining.erase(it); |
| 467 | } |
| 468 | } |
| 469 | } |
| 470 | |
| 471 | for (auto it = remaining.begin(); it != remaining.end(); ++it) { |
| 472 | LOG(ERROR) |
| 473 | << "Failed to load plugin " << *it |
| 474 | << ". Run daemon in verbose mode (--v=1) to see dlopen() attempts."; |
| 475 | } |
| 476 | |
| 477 | closedir(dir); |
| 478 | return (remaining.size() == 0); |
| 479 | } |
| 480 | |
| 481 | std::string GetCurrentDirectory() { |
| 482 | char dest[PATH_MAX + 1]; |