Example #1
0
int
lisp_fstat(HANDLE hfile, struct __stat64 *buf)
{
  int filetype;

  filetype = GetFileType(hfile) & ~FILE_TYPE_REMOTE;

  if (filetype == FILE_TYPE_UNKNOWN) {
    errno = EBADF;
    return -1;
  }

  memset(buf, 0, sizeof(*buf));
  buf->st_nlink = 1;
  
  switch(filetype) {
  case FILE_TYPE_CHAR:
  case FILE_TYPE_PIPE:
    if (filetype == FILE_TYPE_CHAR) {
      buf->st_mode = _S_IFCHR;
    } else {
      buf->st_mode = _S_IFIFO;
    }
    break;
  case FILE_TYPE_DISK:
    {
      BY_HANDLE_FILE_INFORMATION info;

      if (!GetFileInformationByHandle(hfile, &info)) {
        _dosmaperr(GetLastError());
        return -1;
      }

      if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
        buf->st_mode = STAT_READONLY;
      } else {
        buf->st_mode = STAT_READWRITE;
      }
      buf->st_mode |= _S_IFREG;
      buf->st_size = ((((__int64)(info.nFileSizeHigh))<<32LL) |
                      ((__int64)(info.nFileSizeLow)));
      buf->st_mtime = filetime_to_unix_time(&info.ftLastWriteTime);
      buf->st_atime = filetime_to_unix_time(&info.ftLastAccessTime);
      buf->st_ctime = filetime_to_unix_time(&info.ftCreationTime);
    }
    break;
  case FILE_TYPE_UNKNOWN:
  default:
    errno = EBADF;
    return -1;
  }
  return 0;
}
Example #2
0
static void stat_to_sys_path_info(DWORD attributes, DWORD size_low, DWORD size_high, FILETIME const* mtime,
    tr_sys_path_info* info)
{
    TR_ASSERT(mtime != NULL);
    TR_ASSERT(info != NULL);

    if (attributes & FILE_ATTRIBUTE_DIRECTORY)
    {
        info->type = TR_SYS_PATH_IS_DIRECTORY;
    }
    else if (!(attributes & (FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_VIRTUAL)))
    {
        info->type = TR_SYS_PATH_IS_FILE;
    }
    else
    {
        info->type = TR_SYS_PATH_IS_OTHER;
    }

    info->size = size_high;
    info->size <<= 32;
    info->size |= size_low;

    info->last_modified_at = filetime_to_unix_time(mtime);
}
Example #3
0
int ty_stat(const char *path, ty_file_info *info, bool follow)
{
    TY_UNUSED(follow);

    assert(path && path[0]);
    assert(info);

    HANDLE h;
    BY_HANDLE_FILE_INFORMATION attr;
    int r;

    // FIXME: check error handling
    h = CreateFile(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (h == INVALID_HANDLE_VALUE) {
        switch (GetLastError()) {
        case ERROR_ACCESS_DENIED:
            return ty_error(TY_ERROR_ACCESS, "Permission denied for '%s'", path);
        case ERROR_NOT_READY:
            return ty_error(TY_ERROR_IO, "I/O error while stating '%s'", path);
        case ERROR_FILE_NOT_FOUND:
            return ty_error(TY_ERROR_NOT_FOUND, "Path '%s' does not exist", path);
        case ERROR_PATH_NOT_FOUND:
            return ty_error(TY_ERROR_NOT_FOUND, "Part of '%s' is not a directory", path);
        }
        // Let's lie a little, error will be clearer this way
        return ty_error(TY_ERROR_SYSTEM, "GetFileAttributesEx('%s') failed: %s", path, ty_win32_strerror(0));
    }

    r = GetFileInformationByHandle(h, &attr);
    if (!r)
        return ty_error(TY_ERROR_SYSTEM, "GetFileInformationByHandle('%s') failed: %s", path, ty_win32_strerror(0));

    if (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
        info->type = TY_FILE_DIRECTORY;
    } else if (attr.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) {
        info->type = TY_FILE_SPECIAL;
    } else {
        info->type = TY_FILE_REGULAR;
    }

    info->size = ((uint64_t)attr.nFileSizeHigh << 32) | attr.nFileSizeLow;
    info->mtime = filetime_to_unix_time(&attr.ftLastWriteTime);

    return 0;
}