blob: 388588e3fb77c7a7bf8f4330e9045a4541b88630 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <errno.h>
#include <lib/fdio/fdio.h>
#include <stdint.h>
#include <sys/stat.h>
#include <sys/statx.h>
#include <unistd.h>
#include <algorithm>
#include <cerrno>
#include "private.h"
int statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *buf) {
struct stat s;
if (buf == nullptr || pathname == nullptr) {
return ERRNO(EFAULT);
}
if (pathname[0] == '\0') {
return ERRNO(EINVAL);
}
int ret = fstatat(dirfd, pathname, &s, 0);
if (ret != 0) {
return ret;
}
// Fill up the necessary fields for statx from stat.
memset(buf, 0, sizeof(struct statx));
if (mask & STATX_MODE) {
buf->stx_mode = s.st_mode;
buf->stx_mask |= STATX_MODE;
}
if (mask & STATX_INO) {
buf->stx_ino = s.st_ino;
buf->stx_mask |= STATX_INO;
}
if (mask & STATX_SIZE) {
buf->stx_size = s.st_size;
buf->stx_mask |= STATX_SIZE;
}
buf->stx_blksize = s.st_blksize;
if (mask & STATX_BLOCKS) {
// stx_blocks are blocks of size 512.
buf->stx_blocks = s.st_blocks * VNATTR_BLKSIZE / 512;
buf->stx_mask |= STATX_BLOCKS;
}
if (mask & STATX_NLINK) {
buf->stx_nlink = s.st_nlink;
buf->stx_mask |= STATX_NLINK;
}
if (mask & STATX_BTIME) {
buf->stx_btime.tv_sec = s.st_ctim.tv_sec;
buf->stx_btime.tv_nsec = s.st_ctim.tv_nsec;
buf->stx_mask |= STATX_BTIME;
}
if (mask & STATX_MTIME) {
buf->stx_mtime.tv_sec = s.st_mtim.tv_sec;
buf->stx_mtime.tv_nsec = s.st_mtim.tv_nsec;
buf->stx_mask |= STATX_MTIME;
}
return 0;
}