예제 #1
0
FileInformation FileDescriptor::getInfo() const {
#ifndef _WIN32
  struct stat st;
  if (fstat(fd_, &st)) {
    int err = errno;
    throw std::system_error(err, std::generic_category(), "fstat");
  }
  return FileInformation(st);
#else // _WIN32
  FILE_BASIC_INFO binfo;
  FILE_STANDARD_INFO sinfo;

  if (!GetFileInformationByHandleEx(
          (HANDLE)handle(), FileBasicInfo, &binfo, sizeof(binfo))) {
    throw std::system_error(
        GetLastError(),
        std::system_category(),
        "GetFileInformationByHandleEx FileBasicInfo");
  }

  FileInformation info(binfo.FileAttributes);

  FILETIME_LARGE_INTEGER_to_timespec(binfo.CreationTime, &info.ctime);
  FILETIME_LARGE_INTEGER_to_timespec(binfo.LastAccessTime, &info.atime);
  FILETIME_LARGE_INTEGER_to_timespec(binfo.LastWriteTime, &info.mtime);

  if (!GetFileInformationByHandleEx(
          (HANDLE)handle(), FileStandardInfo, &sinfo, sizeof(sinfo))) {
    throw std::system_error(
        GetLastError(),
        std::system_category(),
        "GetFileInformationByHandleEx FileStandardInfo");
  }

  info.size = sinfo.EndOfFile.QuadPart;
  info.nlink = sinfo.NumberOfLinks;

  return info;
#endif
}
예제 #2
0
파일: stat.c 프로젝트: kwlzn/watchman
int lstat(const char *path, struct stat *st) {
  FILE_BASIC_INFO binfo;
  FILE_STANDARD_INFO sinfo;
  WCHAR *wpath = w_utf8_to_win_unc(path, -1);
  HANDLE h;
  DWORD err;

  memset(st, 0, sizeof(*st));

  if (!wpath) {
    return -1;
  }

  h = CreateFileW(wpath, FILE_READ_ATTRIBUTES,
        FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
        NULL);
  err = GetLastError();
  free(wpath);

  if (h == INVALID_HANDLE_VALUE) {
    w_log(W_LOG_DBG, "lstat(%s): %s\n", path, win32_strerror(err));
    errno = map_win32_err(err);
    return -1;
  }

  if (path[1] == ':') {
    int drive_letter = tolower(path[0]);
    st->st_rdev = st->st_dev = drive_letter - 'a';
  }

  if (GetFileInformationByHandleEx(h, FileBasicInfo, &binfo, sizeof(binfo))) {
    FILETIME_LARGE_INTEGER_to_timespec(binfo.CreationTime, &st->st_ctim);
    st->st_ctime = st->st_ctim.tv_sec;
    FILETIME_LARGE_INTEGER_to_timespec(binfo.LastAccessTime, &st->st_atim);
    st->st_atime = st->st_atim.tv_sec;
    FILETIME_LARGE_INTEGER_to_timespec(binfo.LastWriteTime, &st->st_mtim);
    st->st_mtime = st->st_mtim.tv_sec;

    if (binfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
      // This is a symlink, but msvcrt has no way to indicate that.
      // We'll treat it as a regular file until we have a better
      // representation :-/
      st->st_mode = _S_IFREG;
    } else if (binfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
      st->st_mode |= _S_IFDIR|S_IEXEC|S_IXGRP|S_IXOTH;
    } else {
      st->st_mode |= _S_IFREG;
    }
    if (binfo.FileAttributes & FILE_ATTRIBUTE_READONLY) {
      st->st_mode |= 0444;
    } else {
      st->st_mode |= 0666;
    }
  }

  if (GetFileInformationByHandleEx(h, FileStandardInfo,
        &sinfo, sizeof(sinfo))) {
    st->st_size = sinfo.EndOfFile.QuadPart;
    st->st_nlink = sinfo.NumberOfLinks;
  }

  CloseHandle(h);

  return 0;
}