Skip to content

Commit 3497b76

Browse files
committed
fix: resolve symlinks when loading plugin libraries
Use stat() instead of d_type to check if a file is a regular file when scanning for plugin libraries. This allows symlinked plugins to be loaded, which is common in ROS 2 workspaces built with colcon build --symlink-install. The stat() approach also handles filesystems that report DT_UNKNOWN for d_type (e.g., NFS, XFS), making the code more robust. Fixes #3072
1 parent e6639f1 commit 3497b76

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

src/engine/engine_plugin.cc

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern "C" {
3535
#else
3636
#include <dirent.h>
3737
#include <dlfcn.h>
38+
#include <sys/stat.h>
3839
#endif
3940
}
4041

@@ -613,13 +614,14 @@ void mj_loadAllPluginLibraries(const char* directory,
613614

614615
// go through each entry in the directory
615616
for (struct dirent* dp; (dp = readdir(dirp));) {
616-
// only look at regular files (skip symlinks, pipes, directories, etc.)
617-
if (dp->d_type == DT_REG) {
618-
const std::string name(dp->d_name);
619-
if (name.size() > dso_suffix.size() &&
620-
name.substr(name.size() - dso_suffix.size()) == dso_suffix) {
621-
// load the library
622-
const std::string dso_path = directory + sep + name;
617+
const std::string name(dp->d_name);
618+
if (name.size() > dso_suffix.size() &&
619+
name.substr(name.size() - dso_suffix.size()) == dso_suffix) {
620+
const std::string dso_path = directory + sep + name;
621+
622+
// use stat to resolve symlinks and check that the target is a regular file
623+
struct stat file_stat;
624+
if (stat(dso_path.c_str(), &file_stat) == 0 && S_ISREG(file_stat.st_mode)) {
623625
load_dso_and_call_callback(name.c_str(), dso_path.c_str());
624626
}
625627
}

0 commit comments

Comments
 (0)