| 225 | |
| 226 | #if !defined(_WIN32) |
| 227 | bool Readlink(const std::string& path, std::string* result) { |
| 228 | result->clear(); |
| 229 | |
| 230 | // Most Linux file systems (ext2 and ext4, say) limit symbolic links to |
| 231 | // 4095 bytes. Since we'll copy out into the string anyway, it doesn't |
| 232 | // waste memory to just start there. We add 1 so that we can recognize |
| 233 | // whether it actually fit (rather than being truncated to 4095). |
| 234 | std::vector<char> buf(4095 + 1); |
| 235 | while (true) { |
| 236 | ssize_t size = readlink(path.c_str(), &buf[0], buf.size()); |
| 237 | // Unrecoverable error? |
| 238 | if (size == -1) return false; |
| 239 | // It fit! (If size == buf.size(), it may have been truncated.) |
| 240 | if (static_cast<size_t>(size) < buf.size()) { |
| 241 | result->assign(&buf[0], size); |
| 242 | return true; |
| 243 | } |
| 244 | // Double our buffer and try again. |
| 245 | buf.resize(buf.size() * 2); |
| 246 | } |
| 247 | } |
| 248 | #endif |
| 249 | |
| 250 | #if !defined(_WIN32) |
no test coverage detected