Skip to content

Commit 182ef69

Browse files
[libc] add statvfs
1 parent 6c1d445 commit 182ef69

22 files changed

+481
-0
lines changed

libc/config/linux/api.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,7 @@ def SetJmpAPI : PublicAPI<"setjmp.h"> {
262262
def SearchAPI : PublicAPI<"search.h"> {
263263
let Types = ["ACTION", "ENTRY", "struct hsearch_data"];
264264
}
265+
266+
def SysStatvfsAPI : PublicAPI<"sys/statvfs.h"> {
267+
let Types = ["struct statvfs"];
268+
}

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ set(TARGET_LIBC_ENTRYPOINTS
253253
libc.src.sys.stat.mkdirat
254254
libc.src.sys.stat.stat
255255

256+
# sys/statvfs.h
257+
libc.src.sys.statvfs.statvfs
258+
libc.src.sys.statvfs.fstatvfs
259+
256260
# sys/utsname.h entrypoints
257261
libc.src.sys.utsname.uname
258262

libc/include/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,15 @@ add_gen_header(
498498
.llvm-libc-types.struct_sockaddr_un
499499
)
500500

501+
add_gen_header(
502+
sys_statvfs
503+
DEF_FILE sys/statvfs.h.def
504+
GEN_HDR sys/statvfs.h
505+
DEPENDS
506+
.llvm_libc_common_h
507+
.llvm-libc-types.struct_statvfs
508+
)
509+
501510
add_gen_header(
502511
sys_syscall
503512
DEF_FILE sys/syscall.h.def

libc/include/llvm-libc-types/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,13 @@ add_header(
106106
DEPENDS
107107
libc.include.llvm-libc-macros.float_macros
108108
)
109+
add_header(fsblkcnt_t HDR fsblkcnt_t.h)
110+
add_header(fsfilcnt_t HDR fsfilcnt_t.h)
111+
add_header(
112+
struct_statvfs
113+
HDR
114+
struct_statvfs.h
115+
DEPENDS
116+
.fsblkcnt_t
117+
.fsfilcnt_t
118+
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//===-- Definition of fsblkcnt_t type -------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_TYPES_FSBLKCNT_T_H
10+
#define LLVM_LIBC_TYPES_FSBLKCNT_T_H
11+
12+
typedef __SIZE_TYPE__ fsblkcnt_t;
13+
14+
#endif // LLVM_LIBC_TYPES_FSBLKCNT_T_H
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//===-- Definition of fsfilcnt_t type -------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_TYPES_FSFILCNT_T_H
10+
#define LLVM_LIBC_TYPES_FSFILCNT_T_H
11+
12+
typedef __SIZE_TYPE__ fsfilcnt_t;
13+
14+
#endif // LLVM_LIBC_TYPES_FSFILCNT_T_H
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===-- Definition of type struct statvfs ---------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_TYPES_STRUCT_STATVFS_H
10+
#define LLVM_LIBC_TYPES_STRUCT_STATVFS_H
11+
#include <llvm-libc-types/fsblkcnt_t.h>
12+
#include <llvm-libc-types/fsfilcnt_t.h>
13+
struct statvfs {
14+
unsigned long f_bsize; /* Filesystem block size */
15+
unsigned long f_frsize; /* Fragment size */
16+
fsblkcnt_t f_blocks; /* Size of fs in f_frsize units */
17+
fsblkcnt_t f_bfree; /* Number of free blocks */
18+
fsblkcnt_t f_bavail; /* Number of free blocks for unprivileged users */
19+
fsfilcnt_t f_files; /* Number of inodes */
20+
fsfilcnt_t f_ffree; /* Number of free inodes */
21+
fsfilcnt_t f_favail; /* Number of free inodes for unprivileged users */
22+
unsigned long f_fsid; /* Filesystem ID */
23+
unsigned long f_flag; /* Mount flags */
24+
unsigned long f_namemax; /* Maximum filename length */
25+
};
26+
#endif // LLVM_LIBC_TYPES_STRUCT_STATVFS_H

libc/include/sys/statvfs.h.def

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//===-- POSIX header statvfs.h --------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SYS_STATVFS_H
10+
#define LLVM_LIBC_SYS_STATVFS_H
11+
12+
#include <__llvm-libc-common.h>
13+
14+
%%public_api()
15+
16+
#endif // LLVM_LIBC_SYS_STATVFS_H

libc/spec/posix.td

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ def ConstStructSockAddrPtr : ConstType<StructSockAddrPtr>;
8686

8787
def StructSockAddrUn : NamedType<"struct sockaddr_un">;
8888

89+
def StructStatvfs : NamedType<"struct statvfs">;
90+
def StructStatvfsPtr : PtrType<StructStatvfs>;
91+
def RestrictedStructStatvfsPtr : RestrictedPtrType<StructStatvfs>;
92+
8993
def POSIX : StandardSpec<"POSIX"> {
9094
PtrType CharPtr = PtrType<CharType>;
9195
RestrictedPtrType RestrictedCharPtr = RestrictedPtrType<CharType>;
@@ -888,6 +892,31 @@ def POSIX : StandardSpec<"POSIX"> {
888892
]
889893
>;
890894

895+
HeaderSpec SysStatvfs = HeaderSpec<
896+
"sys/statvfs.h",
897+
[], // Macros
898+
[StructStatvfs], // Types
899+
[], // Enumerations
900+
[
901+
FunctionSpec<
902+
"statvfs",
903+
RetValSpec<IntType>,
904+
[
905+
ArgSpec<ConstRestrictedCharPtr>,
906+
ArgSpec<RestrictedStructStatvfsPtr>
907+
]
908+
>,
909+
FunctionSpec<
910+
"fstatvfs",
911+
RetValSpec<IntType>,
912+
[
913+
ArgSpec<IntType>,
914+
ArgSpec<StructStatvfsPtr>
915+
]
916+
>,
917+
] // Functions
918+
>;
919+
891920
NamedType StructUtsName = NamedType<"struct utsname">;
892921
PtrType StructUtsNamePtr = PtrType<StructUtsName>;
893922
HeaderSpec SysUtsName = HeaderSpec<
@@ -1505,6 +1534,7 @@ def POSIX : StandardSpec<"POSIX"> {
15051534
SysSelect,
15061535
SysSocket,
15071536
SysStat,
1537+
SysStatvfs,
15081538
SysTypes,
15091539
SysUtsName,
15101540
SysWait,

libc/src/sys/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ add_subdirectory(select)
77
add_subdirectory(socket)
88
add_subdirectory(sendfile)
99
add_subdirectory(stat)
10+
add_subdirectory(statvfs)
1011
add_subdirectory(utsname)
1112
add_subdirectory(wait)
1213
add_subdirectory(prctl)

libc/src/sys/statvfs/CMakeLists.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
2+
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
3+
endif()
4+
5+
add_entrypoint_object(
6+
statvfs
7+
ALIAS
8+
DEPENDS
9+
.${LIBC_TARGET_OS}.statvfs
10+
)
11+
12+
add_entrypoint_object(
13+
fstatvfs
14+
ALIAS
15+
DEPENDS
16+
.${LIBC_TARGET_OS}.fstatvfs
17+
)

libc/src/sys/statvfs/fstatvfs.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header for fstatvfs ----------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_SYS_STATVFS_FSTATVFS_H
10+
#define LLVM_LIBC_SRC_SYS_STATVFS_FSTATVFS_H
11+
12+
#include "llvm-libc-types/struct_statvfs.h"
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
int fstatvfs(int fd, struct statvfs *buf);
17+
18+
} // namespace LIBC_NAMESPACE
19+
20+
#endif // LLVM_LIBC_SRC_SYS_STATVFS_FSTATVFS_H
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
add_header_library(
2+
statfs_utils
3+
HDRS
4+
statfs_utils.h
5+
DEPENDS
6+
libc.src.errno.errno
7+
libc.src.__support.OSUtil.osutil
8+
libc.src.__support.common
9+
libc.src.__support.CPP.optional
10+
libc.include.sys.syscall
11+
)
12+
13+
add_entrypoint_object(
14+
statvfs
15+
SRCS
16+
statvfs.cpp
17+
HDRS
18+
../statvfs.h
19+
DEPENDS
20+
libc.include.llvm-libc-types.struct_statvfs
21+
.statfs_utils
22+
)
23+
24+
add_entrypoint_object(
25+
fstatvfs
26+
SRCS
27+
fstatvfs.cpp
28+
HDRS
29+
../fstatvfs.h
30+
DEPENDS
31+
libc.include.llvm-libc-types.struct_statvfs
32+
.statfs_utils
33+
)
34+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//===-- Linux implementation of fstatvfs ----------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/sys/statvfs/fstatvfs.h"
10+
#include "src/__support/common.h"
11+
#include "src/sys/statvfs/linux/statfs_utils.h"
12+
13+
namespace LIBC_NAMESPACE {
14+
15+
LLVM_LIBC_FUNCTION(int, fstatvfs, (int fd, struct statvfs *buf)) {
16+
using namespace statfs_utils;
17+
if (cpp::optional<LinuxStatFs> result = linux_fstatfs(fd)) {
18+
*buf = statfs_to_statvfs(*result);
19+
return 0;
20+
}
21+
return -1;
22+
}
23+
24+
} // namespace LIBC_NAMESPACE
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//===-- Convert Statfs to Statvfs -------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_SYS_STATVFS_LINUX_STATFS_TO_STATVFS_H
10+
#define LLVM_LIBC_SRC_SYS_STATVFS_LINUX_STATFS_TO_STATVFS_H
11+
12+
#include "llvm-libc-types/struct_statvfs.h"
13+
#include "src/__support/CPP/optional.h"
14+
#include "src/__support/OSUtil/syscall.h"
15+
#include "src/__support/macros/attributes.h"
16+
#include "src/errno/libc_errno.h"
17+
#include <asm/statfs.h>
18+
#include <sys/syscall.h>
19+
namespace LIBC_NAMESPACE {
20+
21+
namespace statfs_utils {
22+
#ifdef SYS_statfs64
23+
using LinuxStatFs = statfs64;
24+
#else
25+
using LinuxStatFs = statfs;
26+
#endif
27+
28+
LIBC_INLINE cpp::optional<LinuxStatFs> linux_statfs(const char *path) {
29+
LinuxStatFs result;
30+
// On 32-bit platforms, original statfs cannot handle large file systems.
31+
// In such cases, SYS_statfs64 is defined and should be used.
32+
#ifdef SYS_statfs64
33+
int ret = syscall_impl<int>(SYS_statfs64, path, sizeof(result), &result);
34+
#else
35+
int ret = syscall_impl<int>(SYS_statfs, path, &result);
36+
#endif
37+
if (ret < 0) {
38+
libc_errno = -ret;
39+
return cpp::nullopt;
40+
}
41+
return result;
42+
}
43+
44+
LIBC_INLINE cpp::optional<LinuxStatFs> linux_fstatfs(int fd) {
45+
LinuxStatFs result;
46+
// On 32-bit platforms, original fstatfs cannot handle large file systems.
47+
// In such cases, SYS_fstatfs64 is defined and should be used.
48+
#ifdef SYS_fstatfs64
49+
int ret = syscall_impl<int>(SYS_fstatfs64, fd, sizeof(result), &result);
50+
#else
51+
int ret = syscall_impl<int>(SYS_fstatfs, fd, &result);
52+
#endif
53+
if (ret < 0) {
54+
libc_errno = -ret;
55+
return cpp::nullopt;
56+
}
57+
return result;
58+
}
59+
60+
// use struct stat(v)fs to avoid conflicts with the function names.
61+
LIBC_INLINE struct statvfs statfs_to_statvfs(const LinuxStatFs &in) {
62+
struct statvfs out;
63+
out.f_bsize = in.f_bsize;
64+
out.f_frsize = in.f_frsize;
65+
out.f_blocks = in.f_blocks;
66+
out.f_bfree = in.f_bfree;
67+
out.f_bavail = in.f_bavail;
68+
out.f_files = in.f_files;
69+
out.f_ffree = in.f_ffree;
70+
out.f_favail = in.f_ffree;
71+
out.f_fsid = in.f_fsid.val[0] |
72+
static_cast<decltype(out.f_fsid)>(in.f_fsid.val[1]) << 32;
73+
out.f_flag = in.f_flags;
74+
out.f_namemax = in.f_namelen;
75+
return out;
76+
}
77+
} // namespace statfs_utils
78+
} // namespace LIBC_NAMESPACE
79+
80+
#endif // LLVM_LIBC_SRC_SYS_STATVFS_LINUX_STATFS_TO_STATVFS_H
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===-- Linux implementation of statvfs -----------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/sys/statvfs/statvfs.h"
10+
#include "src/__support/common.h"
11+
#include "src/sys/statvfs/linux/statfs_utils.h"
12+
13+
namespace LIBC_NAMESPACE {
14+
15+
LLVM_LIBC_FUNCTION(int, statvfs,
16+
(const char *__restrict path,
17+
struct statvfs *__restrict buf)) {
18+
using namespace statfs_utils;
19+
if (cpp::optional<LinuxStatFs> result = linux_statfs(path)) {
20+
*buf = statfs_to_statvfs(*result);
21+
return 0;
22+
}
23+
return -1;
24+
}
25+
26+
} // namespace LIBC_NAMESPACE

0 commit comments

Comments
 (0)