[libc] Add implementation of functions stat, fstat and lstat.

All supporting type and macro definitions have also been added.

Reviewed By: lntue

Differential Revision: https://reviews.llvm.org/D134262
This commit is contained in:
Siva Chandra Reddy 2022-09-09 19:02:28 +00:00
parent f6e7ad5604
commit e310f8bddf
29 changed files with 718 additions and 6 deletions

View File

@ -277,7 +277,8 @@ def SysResourceAPI : PublicAPI<"sys/resource.h"> {
}
def SysStatAPI : PublicAPI<"sys/stat.h"> {
let Types = ["mode_t"];
let Types = ["mode_t", "dev_t", "ino_t", "nlink_t", "uid_t", "gid_t", "off_t",
"struct timespec", "blksize_t", "blkcnt_t", "struct stat"];
}
def SysSendfileAPI : PublicAPI<"sys/sendfile.h"> {

View File

@ -113,8 +113,11 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.sys.stat.chmod
libc.src.sys.stat.fchmod
libc.src.sys.stat.fchmodat
libc.src.sys.stat.fstat
libc.src.sys.stat.lstat
libc.src.sys.stat.mkdir
libc.src.sys.stat.mkdirat
libc.src.sys.stat.stat
# sys/utsname.h entrypoints
libc.src.sys.utsname.uname

View File

@ -222,6 +222,7 @@ add_gen_header(
.llvm_libc_common_h
.llvm-libc-macros.sys_stat_macros
.llvm-libc-types.mode_t
.llvm-libc-types.struct_stat
)
add_gen_header(

View File

@ -62,6 +62,15 @@
#define S_ISUID 04000
#define S_ISGID 02000
// File type flags
#define S_IFMT 0170000
#define S_IFDIR 0040000
#define S_IFCHR 0020000
#define S_IFBLK 0060000
#define S_IFREG 0100000
#define S_FIFO 0010000
#define S_IFLNK 0120000
// Special directory FD to indicate that the path argument to
// openat is relative to the current directory.
#define AT_FDCWD -100
@ -70,6 +79,13 @@
// has to perform the equivalent of "rmdir" on the path argument.
#define AT_REMOVEDIR 0x200
// Special flag for functions like lstat to convey that symlinks
// should not be followed.
#define AT_SYMLINK_NOFOLLOW 0x100
// Allow empty relative pathname.
#define AT_EMPTY_PATH 0x1000
// Values of SYS_fcntl commands.
#define F_DUPFD 0
#define F_GETFD 1

View File

@ -9,10 +9,13 @@ add_header(__pthread_tss_dtor_t HDR __pthread_tss_dtor_t.h)
add_header(__qsortcompare_t HDR __qsortcompare_t.h)
add_header(__sighandler_t HDR __sighandler_t.h)
add_header(__thread_type HDR __thread_type.h)
add_header(blkcnt_t HDR blkcnt_t.h)
add_header(blksize_t HDR blksize_t.h)
add_header(cnd_t HDR cnd_t.h)
add_header(cookie_io_functions_t HDR cookie_io_functions_t.h DEPENDS .off64_t)
add_header(double_t HDR double_t.h)
add_header(DIR HDR DIR.h)
add_header(dev_t HDR dev_t.h)
add_header(div_t HDR div_t.h)
add_header(ldiv_t HDR ldiv_t.h)
add_header(lldiv_t HDR lldiv_t.h)
@ -20,10 +23,13 @@ add_header(FILE HDR FILE.h)
add_header(fenv_t HDR fenv_t.h)
add_header(fexcept_t HDR fexcept_t.h)
add_header(float_t HDR float_t.h)
add_header(gid_t HDR gid_t.h)
add_header(uid_t HDR uid_t.h)
add_header(imaxdiv_t HDR imaxdiv_t.h)
add_header(ino_t HDR ino_t.h)
add_header(mode_t HDR mode_t.h)
add_header(mtx_t HDR mtx_t.h DEPENDS .__futex_word .__mutex_type)
add_header(nlink_t HDR nlink_t.h)
add_header(off_t HDR off_t.h)
add_header(once_flag HDR once_flag.h DEPENDS .__futex_word)
add_header(pthread_attr_t HDR pthread_attr_t.h DEPENDS .size_t)
@ -36,11 +42,19 @@ add_header(struct_rlimit HDR struct_rlimit.h DEPENDS .rlim_t)
add_header(ssize_t HDR ssize_t.h)
add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t)
add_header(struct_sigaction HDR struct_sigaction.h)
add_header(time_t HDR time_t.h)
add_header(struct_timespec HDR struct_timespec.h DEPENDS .time_t)
add_header(
struct_stat
HDR struct_stat.h
DEPENDS
.dev_t .ino_t .mode_t .nlink_t .uid_t .gid_t .off_t .struct_timespec
.blksize_t .blkcnt_t
)
add_header(struct_tm HDR struct_tm.h)
add_header(struct_utsname HDR struct_utsname.h)
add_header(thrd_start_t HDR thrd_start_t.h)
add_header(thrd_t HDR thrd_t.h DEPENDS .__thread_type)
add_header(time_t HDR time_t.h)
add_header(tss_t HDR tss_t.h)
add_header(tss_dtor_t HDR tss_dtor_t.h)
add_header(__atexithandler_t HDR __atexithandler_t.h)

View File

@ -0,0 +1,14 @@
//===-- Definition of blkcnt_t type ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __LLVM_LIBC_TYPES_BLKCNT_T_H__
#define __LLVM_LIBC_TYPES_BLKCNT_T_H__
typedef __INTPTR_TYPE__ blkcnt_t;
#endif // __LLVM_LIBC_TYPES_BLKCNT_T_H__

View File

@ -0,0 +1,14 @@
//===-- Definition of blksize_t type --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __LLVM_LIBC_TYPES_BLKSIZE_T_H__
#define __LLVM_LIBC_TYPES_BLKSIZE_T_H__
typedef __INTPTR_TYPE__ blksize_t;
#endif // __LLVM_LIBC_TYPES_BLKSIZE_T_H__

View File

@ -0,0 +1,14 @@
//===-- Definition of dev_t type ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __LLVM_LIBC_TYPES_DEV_T_H__
#define __LLVM_LIBC_TYPES_DEV_T_H__
typedef __UINT64_TYPE__ dev_t;
#endif // __LLVM_LIBC_TYPES_DEV_T_H__

View File

@ -0,0 +1,14 @@
//===-- Definition of gid_t type ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __LLVM_LIBC_TYPES_GID_T_H__
#define __LLVM_LIBC_TYPES_GID_T_H__
typedef __UINT32_TYPE__ gid_t;
#endif // __LLVM_LIBC_TYPES_GID_T_H__

View File

@ -1,4 +1,4 @@
//===-- Definition of type ino_t ------------------------------------------===//
//===-- Definition of ino_t type ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@ -9,6 +9,6 @@
#ifndef __LLVM_LIBC_TYPES_INO_T_H__
#define __LLVM_LIBC_TYPES_INO_T_H__
typedef unsigned long ino_t;
typedef __UINTPTR_TYPE__ ino_t;
#endif // __LLVM_LIBC_TYPES_INO_T_H__

View File

@ -0,0 +1,14 @@
//===-- Definition of nlink_t type ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __LLVM_LIBC_TYPES_NLINK_T_H__
#define __LLVM_LIBC_TYPES_NLINK_T_H__
typedef __UINTPTR_TYPE__ nlink_t;
#endif // __LLVM_LIBC_TYPES_NLINK_T_H__

View File

@ -0,0 +1,39 @@
//===-- Definition of struct stat -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __LLVM_LIBC_TYPES_STRUCT_STAT_H__
#define __LLVM_LIBC_TYPES_STRUCT_STAT_H__
#include <llvm-libc-types/blkcnt_t.h>
#include <llvm-libc-types/blksize_t.h>
#include <llvm-libc-types/dev_t.h>
#include <llvm-libc-types/gid_t.h>
#include <llvm-libc-types/ino_t.h>
#include <llvm-libc-types/mode_t.h>
#include <llvm-libc-types/nlink_t.h>
#include <llvm-libc-types/off_t.h>
#include <llvm-libc-types/struct_timespec.h>
#include <llvm-libc-types/uid_t.h>
struct stat {
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
blksize_t st_blksize;
blkcnt_t st_blocks;
};
#endif // __LLVM_LIBC_TYPES_STRUCT_STAT_H__

View File

@ -0,0 +1,19 @@
//===-- Definition of struct timespec -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __LLVM_LIBC_TYPES_TIMESPEC_H__
#define __LLVM_LIBC_TYPES_TIMESPEC_H__
#include <llvm-libc-types/time_t.h>
struct timespec {
time_t tv_sec;
long tv_nsec;
};
#endif // __LLVM_LIBC_TYPES_TIMESPEC_H__

View File

@ -9,6 +9,6 @@
#ifndef __LLVM_LIBC_TYPES_TIME_T_H__
#define __LLVM_LIBC_TYPES_TIME_T_H__
typedef long time_t;
typedef __INTPTR_TYPE__ time_t;
#endif // __LLVM_LIBC_TYPES_TIME_T_H__

View File

@ -0,0 +1,14 @@
//===-- Definition of uid_t type ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __LLVM_LIBC_TYPES_UID_T_H__
#define __LLVM_LIBC_TYPES_UID_T_H__
typedef __UINT32_TYPE__ uid_t;
#endif // __LLVM_LIBC_TYPES_UID_T_H__

View File

@ -16,6 +16,18 @@ def PThreadKeyT : NamedType<"pthread_key_t">;
def PThreadKeyTPtr : PtrType<PThreadKeyT>;
def InoT : NamedType<"ino_t">;
def UidT : NamedType<"uid_t">;
def GidT : NamedType<"gid_t">;
def DevT : NamedType<"dev_t">;
def BlkSizeT : NamedType<"blksize_t">;
def BlkCntT : NamedType<"blkcnt_t">;
def NLinkT : NamedType<"nlink_t">;
def TimeSpec : NamedType<"struct timespec">;
def StatType : NamedType<"struct stat">;
def StatTypePtr : PtrType<StatType>;
def RestrictedStatTypePtr : RestrictedPtrType<StatType>;
def DIR : NamedType<"DIR">;
def DIRPtr : PtrType<DIR>;
def DIRRestrictedPtr : RestrictedPtrType<DIR>;
@ -491,7 +503,7 @@ def POSIX : StandardSpec<"POSIX"> {
HeaderSpec SysStat = HeaderSpec<
"sys/stat.h",
[], // Macros
[ModeTType], // Types
[ModeTType, DevT, InoT, UidT, GidT, TimeSpec, BlkSizeT, BlkCntT, OffTType, NLinkT, StatType], // Types
[], // Enumerations
[
FunctionSpec<
@ -509,6 +521,16 @@ def POSIX : StandardSpec<"POSIX"> {
RetValSpec<IntType>,
[ArgSpec<IntType>, ArgSpec<ConstCharPtr>, ArgSpec<ModeTType>, ArgSpec<IntType>]
>,
FunctionSpec<
"fstat",
RetValSpec<IntType>,
[ArgSpec<IntType>, ArgSpec<StatTypePtr>]
>,
FunctionSpec<
"lstat",
RetValSpec<IntType>,
[ArgSpec<ConstRestrictedCharPtr>, ArgSpec<RestrictedStatTypePtr>]
>,
FunctionSpec<
"mkdir",
RetValSpec<IntType>,
@ -519,6 +541,11 @@ def POSIX : StandardSpec<"POSIX"> {
RetValSpec<IntType>,
[ArgSpec<IntType>, ArgSpec<ConstCharPtr>, ArgSpec<ModeTType>]
>,
FunctionSpec<
"stat",
RetValSpec<IntType>,
[ArgSpec<ConstRestrictedCharPtr>, ArgSpec<RestrictedStatTypePtr>]
>,
]
>;

View File

@ -23,6 +23,20 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.fchmod
)
add_entrypoint_object(
fstat
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.fstat
)
add_entrypoint_object(
lstat
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.lstat
)
add_entrypoint_object(
mkdir
ALIAS
@ -36,3 +50,10 @@ add_entrypoint_object(
DEPENDS
.${LIBC_TARGET_OS}.mkdirat
)
add_entrypoint_object(
stat
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.stat
)

20
libc/src/sys/stat/fstat.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header for fstat -------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_SYS_STAT_FSTAT_H
#define LLVM_LIBC_SRC_SYS_STAT_FSTAT_H
#include <sys/stat.h>
namespace __llvm_libc {
int fstat(int fd, struct stat *statbuf);
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_SYS_STAT_FSTAT_H

View File

@ -64,3 +64,50 @@ add_entrypoint_object(
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)
add_header_library(
kernel_statx
HDRS
kernel_statx.h
DEPENDS
libc.include.sys_stat
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)
add_entrypoint_object(
stat
SRCS
stat.cpp
HDRS
../stat.h
DEPENDS
.kernel_statx
libc.include.fcntl
libc.include.sys_stat
)
add_entrypoint_object(
lstat
SRCS
lstat.cpp
HDRS
../lstat.h
DEPENDS
.kernel_statx
libc.include.fcntl
libc.include.sys_stat
)
add_entrypoint_object(
fstat
SRCS
fstat.cpp
HDRS
../fstat.h
DEPENDS
.kernel_statx
libc.include.fcntl
libc.include.sys_stat
)

View File

@ -0,0 +1,23 @@
//===-- Linux implementation of fstat -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/sys/stat/fstat.h"
#include "kernel_statx.h"
#include "src/__support/common.h"
#include <fcntl.h>
#include <sys/stat.h>
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, fstat, (int fd, struct stat *statbuf)) {
return statx(fd, "", AT_EMPTY_PATH, statbuf);
}
} // namespace __llvm_libc

View File

@ -0,0 +1,105 @@
//===-- Wrapper over SYS_statx syscall ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_SYS_STAT_LINUX_STATX_H
#define LLVM_LIBC_SRC_SYS_STAT_LINUX_STATX_H
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include <errno.h>
#include <stdint.h>
#include <sys/stat.h>
#include <sys/syscall.h> // For syscall numbers.
// It is safe to include this kernel header as it is designed to be
// included from user programs without causing any name pollution.
#include <linux/kdev_t.h>
namespace {
// The type definitions in the internal namespace match kernel's definition of
// the statx_timestamp and statx types in linux/stat.h. We define equivalent
// types here instead of including that header file to avoid name mixup between
// linux/stat.h and the libc's stat.h.
struct statx_timestamp {
int64_t tv_sec;
uint32_t tv_nsec;
int32_t __reserved;
};
struct statx_buf {
uint32_t stx_mask; // What results were written
uint32_t stx_blksize; // Preferred general I/O size
uint64_t stx_attributes; // Flags conveying information about the file
uint32_t stx_nlink; // Number of hard links
uint32_t stx_uid; // User ID of owner
uint32_t stx_gid; // Group ID of owner
uint16_t stx_mode; // File mode
uint16_t __spare0[1];
uint64_t stx_ino; // Inode number
uint64_t stx_size; // File size
uint64_t stx_blocks; // Number of 512-byte blocks allocated
uint64_t stx_attributes_mask; // Mask to show what's supported in
// stx_attributes
struct statx_timestamp stx_atime; // Last access time
struct statx_timestamp stx_btime; // File creation time
struct statx_timestamp stx_ctime; // Last attribute change time
struct statx_timestamp stx_mtime; // Last data modification time
uint32_t stx_rdev_major; // Device ID of special file
uint32_t stx_rdev_minor;
uint32_t stx_dev_major; // ID of device containing file
uint32_t stx_dev_minor;
uint64_t stx_mnt_id;
uint64_t __spare2;
uint64_t __spare3[12]; // Spare space for future expansion
};
// The below mask value is based on the definition of a similarly
// named macro in linux/stat.h. When this flag is passed for the
// mask argument to the statx syscall, all fields except the
// stx_btime field will be filled in.
constexpr unsigned int STATX_BASIC_STATS_MASK = 0x7FF;
} // Anonymous namespace
namespace __llvm_libc {
inline int statx(int dirfd, const char *__restrict path, int flags,
struct stat *__restrict statbuf) {
// We make a statx syscall and copy out the result into the |statbuf|.
::statx_buf xbuf;
long ret =
syscall(SYS_statx, dirfd, path, flags, ::STATX_BASIC_STATS_MASK, &xbuf);
if (ret < 0) {
errno = -ret;
return -1;
}
statbuf->st_dev = MKDEV(xbuf.stx_dev_major, xbuf.stx_dev_minor);
statbuf->st_ino = xbuf.stx_ino;
statbuf->st_mode = xbuf.stx_mode;
statbuf->st_nlink = xbuf.stx_nlink;
statbuf->st_uid = xbuf.stx_uid;
statbuf->st_gid = xbuf.stx_gid;
statbuf->st_rdev = MKDEV(xbuf.stx_rdev_major, xbuf.stx_rdev_minor);
statbuf->st_size = xbuf.stx_size;
statbuf->st_atim.tv_sec = xbuf.stx_atime.tv_sec;
statbuf->st_atim.tv_nsec = xbuf.stx_atime.tv_nsec;
statbuf->st_mtim.tv_sec = xbuf.stx_mtime.tv_sec;
statbuf->st_mtim.tv_nsec = xbuf.stx_mtime.tv_nsec;
statbuf->st_ctim.tv_sec = xbuf.stx_ctime.tv_sec;
statbuf->st_ctim.tv_nsec = xbuf.stx_ctime.tv_nsec;
statbuf->st_blksize = xbuf.stx_blksize;
statbuf->st_blocks = xbuf.stx_blocks;
return 0;
}
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_SYS_STAT_LINUX_STATX_H

View File

@ -0,0 +1,26 @@
//===-- Linux implementation of lstat -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/sys/stat/lstat.h"
#include "kernel_statx.h"
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
#include <fcntl.h>
#include <sys/stat.h>
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, lstat,
(const char *__restrict path,
struct stat *__restrict statbuf)) {
return statx(AT_FDCWD, path, AT_SYMLINK_NOFOLLOW, statbuf);
}
} // namespace __llvm_libc

View File

@ -0,0 +1,25 @@
//===-- Linux implementation of stat --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/sys/stat/stat.h"
#include "kernel_statx.h"
#include "src/__support/common.h"
#include <fcntl.h>
#include <sys/stat.h>
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, stat,
(const char *__restrict path,
struct stat *__restrict statbuf)) {
return statx(AT_FDCWD, path, 0, statbuf);
}
} // namespace __llvm_libc

20
libc/src/sys/stat/lstat.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header for lstat -------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_SYS_STAT_LSTAT_H
#define LLVM_LIBC_SRC_SYS_STAT_LSTAT_H
#include <sys/stat.h>
namespace __llvm_libc {
int lstat(const char *__restrict path, struct stat *__restrict statbuf);
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_SYS_STAT_LSTAT_H

20
libc/src/sys/stat/stat.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header for stat --------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_SYS_STAT_STAT_H
#define LLVM_LIBC_SRC_SYS_STAT_STAT_H
#include <sys/stat.h>
namespace __llvm_libc {
int stat(const char *__restrict path, struct stat *__restrict statbuf);
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_SYS_STAT_STAT_H

View File

@ -63,3 +63,51 @@ add_libc_unittest(
libc.src.sys.stat.mkdirat
libc.src.unistd.rmdir
)
add_libc_unittest(
stat_test
SUITE
libc_sys_stat_unittests
SRCS
stat_test.cpp
DEPENDS
libc.include.errno
libc.include.fcntl
libc.include.sys_stat
libc.src.sys.stat.stat
libc.src.fcntl.open
libc.src.unistd.close
libc.src.unistd.unlink
)
add_libc_unittest(
lstat_test
SUITE
libc_sys_stat_unittests
SRCS
lstat_test.cpp
DEPENDS
libc.include.errno
libc.include.fcntl
libc.include.sys_stat
libc.src.sys.stat.lstat
libc.src.fcntl.open
libc.src.unistd.close
libc.src.unistd.unlink
)
add_libc_unittest(
fstat_test
SUITE
libc_sys_stat_unittests
SRCS
fstat_test.cpp
DEPENDS
libc.include.errno
libc.include.fcntl
libc.include.sys_stat
libc.src.sys.stat.fstat
libc.src.fcntl.open
libc.src.unistd.close
libc.src.unistd.unlink
)

View File

@ -0,0 +1,51 @@
//===-- Unittests for fstat -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/fcntl/open.h"
#include "src/sys/stat/fstat.h"
#include "src/unistd/close.h"
#include "src/unistd/unlink.h"
#include "test/ErrnoSetterMatcher.h"
#include "utils/UnitTest/Test.h"
#include "utils/testutils/FDReader.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
TEST(LlvmLibcFStatTest, CreatAndReadMode) {
using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
// The test file is initially writable. We open it for writing and ensure
// that it indeed can be opened for writing. Next, we close the file and
// make it readonly using chmod. We test that chmod actually succeeded by
// trying to open the file for writing and failing.
constexpr const char *TEST_FILE = "testdata/fstat.test";
errno = 0;
int fd = __llvm_libc::open(TEST_FILE, O_CREAT | O_WRONLY, S_IRWXU);
ASSERT_GT(fd, 0);
ASSERT_EQ(errno, 0);
struct stat statbuf;
ASSERT_THAT(__llvm_libc::fstat(fd, &statbuf), Succeeds(0));
ASSERT_EQ(int(statbuf.st_mode), int(S_IRWXU | S_IFREG));
ASSERT_THAT(__llvm_libc::close(fd), Succeeds(0));
ASSERT_THAT(__llvm_libc::unlink(TEST_FILE), Succeeds(0));
}
TEST(LlvmLibcFStatTest, NonExistentFile) {
errno = 0;
using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
struct stat statbuf;
ASSERT_THAT(__llvm_libc::fstat(-1, &statbuf), Fails(EBADF));
errno = 0;
}

View File

@ -0,0 +1,51 @@
//===-- Unittests for lstat -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/fcntl/open.h"
#include "src/sys/stat/lstat.h"
#include "src/unistd/close.h"
#include "src/unistd/unlink.h"
#include "test/ErrnoSetterMatcher.h"
#include "utils/UnitTest/Test.h"
#include "utils/testutils/FDReader.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
TEST(LlvmLibcLStatTest, CreatAndReadMode) {
using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
// The test file is initially writable. We open it for writing and ensure
// that it indeed can be opened for writing. Next, we close the file and
// make it readonly using chmod. We test that chmod actually succeeded by
// trying to open the file for writing and failing.
constexpr const char *TEST_FILE = "testdata/lstat.test";
errno = 0;
int fd = __llvm_libc::open(TEST_FILE, O_CREAT | O_WRONLY, S_IRWXU);
ASSERT_GT(fd, 0);
ASSERT_EQ(errno, 0);
ASSERT_THAT(__llvm_libc::close(fd), Succeeds(0));
struct stat statbuf;
ASSERT_THAT(__llvm_libc::lstat(TEST_FILE, &statbuf), Succeeds(0));
ASSERT_EQ(int(statbuf.st_mode), int(S_IRWXU | S_IFREG));
ASSERT_THAT(__llvm_libc::unlink(TEST_FILE), Succeeds(0));
}
TEST(LlvmLibcLStatTest, NonExistentFile) {
errno = 0;
using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
struct stat statbuf;
ASSERT_THAT(__llvm_libc::lstat("non-existent-file", &statbuf), Fails(ENOENT));
errno = 0;
}

View File

@ -0,0 +1,51 @@
//===-- Unittests for stat ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/fcntl/open.h"
#include "src/sys/stat/stat.h"
#include "src/unistd/close.h"
#include "src/unistd/unlink.h"
#include "test/ErrnoSetterMatcher.h"
#include "utils/UnitTest/Test.h"
#include "utils/testutils/FDReader.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
TEST(LlvmLibcStatTest, CreatAndReadMode) {
using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
// The test file is initially writable. We open it for writing and ensure
// that it indeed can be opened for writing. Next, we close the file and
// make it readonly using chmod. We test that chmod actually succeeded by
// trying to open the file for writing and failing.
constexpr const char *TEST_FILE = "testdata/stat.test";
errno = 0;
int fd = __llvm_libc::open(TEST_FILE, O_CREAT | O_WRONLY, S_IRWXU);
ASSERT_GT(fd, 0);
ASSERT_EQ(errno, 0);
ASSERT_THAT(__llvm_libc::close(fd), Succeeds(0));
struct stat statbuf;
ASSERT_THAT(__llvm_libc::stat(TEST_FILE, &statbuf), Succeeds(0));
ASSERT_EQ(int(statbuf.st_mode), int(S_IRWXU | S_IFREG));
ASSERT_THAT(__llvm_libc::unlink(TEST_FILE), Succeeds(0));
}
TEST(LlvmLibcStatTest, NonExistentFile) {
errno = 0;
using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
struct stat statbuf;
ASSERT_THAT(__llvm_libc::stat("non-existent-file", &statbuf), Fails(ENOENT));
errno = 0;
}