| 299 | |
| 300 | |
| 301 | Try<MountInfoTable::Entry> MountInfoTable::Entry::parse(const string& s) |
| 302 | { |
| 303 | MountInfoTable::Entry entry; |
| 304 | |
| 305 | const string separator = " - "; |
| 306 | size_t pos = s.find(separator); |
| 307 | if (pos == string::npos) { |
| 308 | return Error("Could not find separator ' - '"); |
| 309 | } |
| 310 | |
| 311 | // First group of fields (before the separator): 6 required fields |
| 312 | // then zero or more optional fields |
| 313 | vector<string> tokens = strings::tokenize(s.substr(0, pos), " "); |
| 314 | if (tokens.size() < 6) { |
| 315 | return Error("Failed to parse entry"); |
| 316 | } |
| 317 | |
| 318 | Try<int> id = numify<int>(tokens[0]); |
| 319 | if (id.isError()) { |
| 320 | return Error("Mount ID is not a number"); |
| 321 | } |
| 322 | entry.id = id.get(); |
| 323 | |
| 324 | Try<int> parent = numify<int>(tokens[1]); |
| 325 | if (parent.isError()) { |
| 326 | return Error("Parent ID is not a number"); |
| 327 | } |
| 328 | entry.parent = parent.get(); |
| 329 | |
| 330 | // Parse out the major:minor device number. |
| 331 | vector<string> device = strings::split(tokens[2], ":"); |
| 332 | if (device.size() != 2) { |
| 333 | return Error("Invalid major:minor device number"); |
| 334 | } |
| 335 | |
| 336 | Try<int> major = numify<int>(device[0]); |
| 337 | if (major.isError()) { |
| 338 | return Error("Device major is not a number"); |
| 339 | } |
| 340 | |
| 341 | Try<int> minor = numify<int>(device[1]); |
| 342 | if (minor.isError()) { |
| 343 | return Error("Device minor is not a number"); |
| 344 | } |
| 345 | |
| 346 | entry.devno = makedev(major.get(), minor.get()); |
| 347 | |
| 348 | entry.root = tokens[3]; |
| 349 | entry.target = tokens[4]; |
| 350 | |
| 351 | entry.vfsOptions = tokens[5]; |
| 352 | |
| 353 | // The "proc" manpage states there can be zero or more optional |
| 354 | // fields. The kernel source (fs/proc_namespace.c) has the optional |
| 355 | // fields ("tagged fields") separated by " " when printing the table |
| 356 | // (see show_mountinfo()). |
| 357 | if (tokens.size() > 6) { |
| 358 | tokens.erase(tokens.begin(), tokens.begin() + 6); |
no test coverage detected