| 37 | |
| 38 | namespace android::base { |
| 39 | static bool Readlink(const std::string& path, std::string* result) { |
| 40 | result->clear(); |
| 41 | // Most Linux file systems (ext2 and ext4, say) limit symbolic links to |
| 42 | // 4095 bytes. Since we'll copy out into the string anyway, it doesn't |
| 43 | // waste memory to just start there. We add 1 so that we can recognize |
| 44 | // whether it actually fit (rather than being truncated to 4095). |
| 45 | std::vector<char> buf(4095 + 1); |
| 46 | while (true) { |
| 47 | ssize_t size = readlink(path.c_str(), &buf[0], buf.size()); |
| 48 | // Unrecoverable error? |
| 49 | if (size == -1) return false; |
| 50 | // It fit! (If size == buf.size(), it may have been truncated.) |
| 51 | if (static_cast<size_t>(size) < buf.size()) { |
| 52 | result->assign(&buf[0], size); |
| 53 | return true; |
| 54 | } |
| 55 | // Double our buffer and try again. |
| 56 | buf.resize(buf.size() * 2); |
| 57 | } |
| 58 | } |
| 59 | } // namespace android::base |
| 60 | |
| 61 | |