w_string w_fstype()

in watchman/fs/FSDetect.cpp [124:218]


w_string w_fstype(const char* path) {
#ifdef __linux__
  // If possible, we prefer to read the filesystem type names from
  // `/proc/self/mounts`
  std::string mounts;
  if (folly::readFile("/proc/self/mounts", mounts)) {
    auto fstype = find_fstype_in_linux_proc_mounts(path, mounts);
    if (fstype) {
      return fstype;
    }
  }

  // Reading the mount table can fail for the simple reason that `/proc` isn't
  // mounted, so fall back to some slightly manual code that looks at known
  // filesystem type ids.

  struct statfs sfs;
  const char* name = "unknown";

  // Unfortunately the FUSE magic number is not defined in linux/magic.h,
  // and is only available in the Linux source code in fs/fuse/inode.c
  constexpr __fsword_t FUSE_MAGIC_NUMBER = 0x65735546;

  if (statfs(path, &sfs) == 0) {
    switch (sfs.f_type) {
#ifdef CIFS_MAGIC_NUMBER
      case CIFS_MAGIC_NUMBER:
        name = "cifs";
        break;
#endif
#ifdef NFS_SUPER_MAGIC
      case NFS_SUPER_MAGIC:
        name = "nfs";
        break;
#endif
#ifdef SMB_SUPER_MAGIC
      case SMB_SUPER_MAGIC:
        name = "smb";
        break;
#endif
      case FUSE_MAGIC_NUMBER:
        name = "fuse";
        break;
      default:
        name = "unknown";
    }
  }

  return w_string(name, W_STRING_UNICODE);
#elif STATVFS_HAS_FSTYPE_AS_STRING
  // if this is going to be used on macos this needs
  // to detect edenfs with w_fstype_detect_macos_nfs
  struct statvfs sfs;

  if (statvfs(path, &sfs) == 0) {
#ifdef HAVE_STRUCT_STATVFS_F_FSTYPENAME
    return w_string(sfs.f_fstypename, W_STRING_UNICODE);
#endif
#ifdef HAVE_STRUCT_STATVFS_F_BASETYPE
    return w_string(sfs.f_basetype, W_STRING_UNICODE);
#endif
  }
#elif HAVE_STATFS
  struct statfs sfs;

  if (statfs(path, &sfs) == 0) {
    auto fstype = w_string(sfs.f_fstypename, W_STRING_UNICODE);
    auto edenfs_indicator = w_string(sfs.f_mntfromname, W_STRING_UNICODE);
    return w_fstype_detect_macos_nfs(fstype, edenfs_indicator);
  }
#endif
#ifdef _WIN32
  auto wpath = w_string_piece(path).asWideUNC();
  WCHAR fstype[MAX_PATH + 1];
  FileDescriptor h(
      intptr_t(CreateFileW(
          wpath.c_str(),
          GENERIC_READ,
          FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
          nullptr,
          OPEN_EXISTING,
          FILE_FLAG_BACKUP_SEMANTICS,
          nullptr)),
      FileDescriptor::FDType::Generic);
  if (h &&
      GetVolumeInformationByHandleW(
          (HANDLE)h.handle(), nullptr, 0, 0, 0, 0, fstype, MAX_PATH + 1)) {
    return w_string(fstype, wcslen(fstype));
  }
  return w_string("unknown", W_STRING_UNICODE);
#else
  unused_parameter(path);
  return w_string("unknown", W_STRING_UNICODE);
#endif
}