| 266 | |
| 267 | |
| 268 | Try<MountInfoTable::Entry> MountInfoTable::findByTarget( |
| 269 | const std::string& target) |
| 270 | { |
| 271 | Result<string> realTarget = os::realpath(target); |
| 272 | if (!realTarget.isSome()) { |
| 273 | return Error( |
| 274 | "Failed to get the realpath of '" + target + "'" |
| 275 | ": " + (realTarget.isError() ? realTarget.error() : "Not found")); |
| 276 | } |
| 277 | |
| 278 | // Trying to find the mount entry that contains the 'realTarget'. We |
| 279 | // achieve that by doing a reverse traverse of the mount table to |
| 280 | // find the first entry whose target is a prefix of the specified |
| 281 | // 'realTarget'. |
| 282 | foreach (const Entry& entry, adaptor::reverse(entries)) { |
| 283 | if (entry.target == realTarget.get()) { |
| 284 | return entry; |
| 285 | } |
| 286 | |
| 287 | // NOTE: We have to use `path::join(entry.target, "")` here |
| 288 | // to make sure the parent is a directory. |
| 289 | if (strings::startsWith(realTarget.get(), path::join(entry.target, ""))) { |
| 290 | return entry; |
| 291 | } |
| 292 | } |
| 293 | |
| 294 | // It's unlikely that we cannot find the immediate parent because |
| 295 | // '/' is always mounted and will be the immediate parent if no |
| 296 | // other mounts found in between. |
| 297 | return Error("Not found"); |
| 298 | } |
| 299 | |
| 300 | |
| 301 | Try<MountInfoTable::Entry> MountInfoTable::Entry::parse(const string& s) |