| 477 | |
| 478 | |
| 479 | Try<Nothing> mount(const Option<string>& _source, |
| 480 | const string& target, |
| 481 | const Option<string>& _type, |
| 482 | unsigned long flags, |
| 483 | const void* data) |
| 484 | { |
| 485 | const char * source = _source.isSome() ? _source->c_str() : nullptr; |
| 486 | const char * type = _type.isSome() ? _type->c_str() : nullptr; |
| 487 | |
| 488 | // The prototype of function 'mount' on Linux is as follows: |
| 489 | // int mount(const char *source, |
| 490 | // const char *target, |
| 491 | // const char *filesystemtype, |
| 492 | // unsigned long mountflags, |
| 493 | // const void *data); |
| 494 | if (::mount(source, target.c_str(), type, flags, data) < 0) { |
| 495 | return ErrnoError(); |
| 496 | } |
| 497 | |
| 498 | const unsigned READ_ONLY_FLAG = MS_BIND | MS_RDONLY; |
| 499 | const unsigned READ_ONLY_MASK = MS_BIND | MS_RDONLY | MS_REC; |
| 500 | |
| 501 | // Bind mounts need to be remounted for the read-only flag to take |
| 502 | // effect. If this was a read-only bind mount, automatically remount |
| 503 | // so that every caller doesn't have to deal with this. We don't do |
| 504 | // anything if this was already a remount. |
| 505 | if ((flags & (READ_ONLY_FLAG | MS_REMOUNT)) == READ_ONLY_FLAG) { |
| 506 | if (::mount( |
| 507 | nullptr, |
| 508 | target.c_str(), |
| 509 | nullptr, |
| 510 | MS_REMOUNT | (flags & READ_ONLY_MASK), |
| 511 | nullptr) < 0) { |
| 512 | return ErrnoError("Read-only remount failed"); |
| 513 | } |
| 514 | } |
| 515 | |
| 516 | return Nothing(); |
| 517 | } |
| 518 | |
| 519 | |
| 520 | Try<Nothing> mount(const Option<string>& source, |