message: On *nix, use a realpath(3) variant (which does not expand symlinks) in NormalizePath
  Before this commit, when a source file is a symlink, cquery is not able to serve LSP requests for it.
diff: #include <fcntl.h>
  #include <unistd.h>
  -#include <fcntl.h> /* For O_* constants */
  #include <semaphore.h>
  #include <sys/mman.h>
  -#include <sys/stat.h> /* For mode constants */
  #ifndef __APPLE__
  #include <sys/prctl.h>
  #include <malloc.h>
  #endif
  +namespace {
  +
  +// Returns the canonicalized absolute pathname, without expanding symbolic links.
  +// This is a variant of realpath(2), C++ rewrite of
  +// https://github.com/freebsd/freebsd/blob/master/lib/libc/stdlib/realpath.c
  +optional<std::string> RealPathNotExpandSymlink(std::string path) {
  + if (path.empty()) {
  + errno = EINVAL;
  + return nullopt;
  + }
  + if (path[0] == '\0') {
  + errno = ENOENT;
  + return nullopt;
  + }
  +
  + // Do not use PATH_MAX because it is tricky on Linux.
  + // See https://eklitzke.org/path-max-is-tricky
  + char tmp[1024];
  + std::string resolved;
  + size_t i = 0;
  + struct stat sb;
  + if (path[0] == '/') {
  + resolved = "/";
  + i = 1;
  + } else {
  + if (!getcwd(tmp, sizeof tmp))
  + return nullopt;
  + resolved = tmp;
  + }
  +
  + while (i < path.size()) {
  + auto j = path.find('/', i);
  + if (j == std::string::npos)
  + j = path.size();
  + auto next_token = path.substr(i, j - i);
  + i = j + 1;
  + if (resolved.back() != '/')
  + resolved += '/';
  + if (next_token.empty() || next_token == ".") {
  + // Handle consequential slashes and "."
  + continue;
  + } else if (next_token == "..") {
  + // Strip the last path component except when it is single "/"
  + if (resolved.size() > 1)
  + resolved.resize(resolved.rfind('/', resolved.size() - 2) + 1);
  + continue;
  + }
  + // Append the next path component.
  + // Here we differ from realpath(3), we use stat(2) instead of
  + // lstat(2) because we do not want to resolve symlinks.
  + resolved += next_token;
  + if (stat(resolved.c_str(), &sb) != 0)
  + return nullopt;
  + if (!S_ISDIR(sb.st_mode) && j < path.size()) {
  + errno = ENOTDIR;
  + return nullopt;
  + }
  + }
  +
  + // Remove trailing slash except when a single "/".
  + if (resolved.size() > 1 && resolved.back() == '/')
  + resolved.pop_back();
  + return resolved;
  +}
  +
  +} // namespace
  +
  struct PlatformMutexLinux : public PlatformMutex {
  sem_t* sem_ = nullptr;
  @@ -155,12 +220,8 @@ std::string GetWorkingDirectory() {
  }
  std::string NormalizePath(const std::string& path) {
  - errno = 0;
  - char name[PATH_MAX + 1];
  - (void)realpath(path.c_str(), name);
  - if (errno)
  - return path;
  - return name;
  + optional<std::string> resolved = RealPathNotExpandSymlink(path);
  + return resolved ? *resolved : path;
  }
  bool TryMakeDirectory(const std::string& absolute_path) {
  