aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2019-09-03 15:42:34 -0700
committerandroid-build-merger <android-build-merger@google.com>2019-09-03 15:42:34 -0700
commit8049184be8e79fc591a114d3253ff5b932678c00 (patch)
treedf3a4dafa844d29d18a302a47ad9483593f8569b
parentf0e70113d53803fdcb37b6c3c49203299f95da2e (diff)
parent37ff081e886f29c10a5f549094a53c8d547c6565 (diff)
downloadbionic-8049184be8e79fc591a114d3253ff5b932678c00.tar.gz
Merge "Support statvfs on API levels before 19."
am: 37ff081e88 Change-Id: Id79699c172491d805543e370980bfc736802f570
-rw-r--r--libc/Android.bp3
-rw-r--r--libc/bionic/sys_statfs.cpp (renamed from libc/bionic/statvfs.cpp)48
-rw-r--r--libc/bionic/sys_statvfs.cpp32
-rw-r--r--libc/include/android/legacy_sys_statvfs_inlines.h48
-rw-r--r--libc/include/bits/sys_statvfs_inlines.h95
-rw-r--r--libc/include/sys/statvfs.h134
6 files changed, 290 insertions, 70 deletions
diff --git a/libc/Android.bp b/libc/Android.bp
index 71d4d4a6a..e505c67ec 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1133,7 +1133,6 @@ cc_library_static {
"bionic/sigprocmask.cpp",
"bionic/spawn.cpp",
"bionic/stat.cpp",
- "bionic/statvfs.cpp",
"bionic/stdlib_l.cpp",
"bionic/strchrnul.cpp",
"bionic/strerror.cpp",
@@ -1150,6 +1149,8 @@ cc_library_static {
"bionic/sys_sem.cpp",
"bionic/sys_shm.cpp",
"bionic/sys_signalfd.cpp",
+ "bionic/sys_statfs.cpp",
+ "bionic/sys_statvfs.cpp",
"bionic/sys_time.cpp",
"bionic/sysinfo.cpp",
"bionic/syslog.cpp",
diff --git a/libc/bionic/statvfs.cpp b/libc/bionic/sys_statfs.cpp
index cd825eb16..d78de2ddc 100644
--- a/libc/bionic/statvfs.cpp
+++ b/libc/bionic/sys_statfs.cpp
@@ -14,12 +14,11 @@
* limitations under the License.
*/
-#include <sys/statvfs.h>
-
#include <sys/statfs.h>
-// Paper over the fact that 32-bit kernels use fstatfs64/statfs64 with an extra argument,
-// but 64-bit kernels don't have the "64" bit suffix or the extra size_t argument.
+// Paper over the fact that 32-bit kernels use fstatfs64/statfs64 with
+// an extra argument, but 64-bit kernels don't have the "64" bit suffix or
+// the extra size_t argument.
#if defined(__LP64__)
extern "C" int __fstatfs(int, struct statfs*);
extern "C" int __statfs(const char*, struct statfs*);
@@ -30,24 +29,11 @@ extern "C" int __fstatfs64(int, size_t, struct statfs*);
extern "C" int __statfs64(const char*, size_t, struct statfs*);
#endif
-// The kernel sets a private ST_VALID flag to signal to the C library whether the
-// f_flags field is valid. This flag should not be exposed to users of the C library.
+// The kernel sets a private ST_VALID flag to signal to the C library
+// whether the f_flags field is valid. This flag should not be exposed to
+// users of the C library.
#define ST_VALID 0x0020
-static void __statfs_to_statvfs(const struct statfs& in, struct statvfs* out) {
- out->f_bsize = in.f_bsize;
- out->f_frsize = in.f_frsize;
- out->f_blocks = in.f_blocks;
- out->f_bfree = in.f_bfree;
- out->f_bavail = in.f_bavail;
- out->f_files = in.f_files;
- out->f_ffree = in.f_ffree;
- out->f_favail = in.f_ffree;
- out->f_fsid = in.f_fsid.__val[0] | (static_cast<uint64_t>(in.f_fsid.__val[1]) << 32);
- out->f_flag = in.f_flags;
- out->f_namemax = in.f_namelen;
-}
-
int fstatfs(int fd, struct statfs* result) {
int rc = __fstatfs64(fd, sizeof(*result), result);
if (rc != 0) {
@@ -67,25 +53,3 @@ int statfs(const char* path, struct statfs* result) {
return 0;
}
__strong_alias(statfs64, statfs);
-
-int statvfs(const char* path, struct statvfs* result) {
- struct statfs tmp;
- int rc = statfs(path, &tmp);
- if (rc != 0) {
- return rc;
- }
- __statfs_to_statvfs(tmp, result);
- return 0;
-}
-__strong_alias(statvfs64, statvfs);
-
-int fstatvfs(int fd, struct statvfs* result) {
- struct statfs tmp;
- int rc = fstatfs(fd, &tmp);
- if (rc != 0) {
- return rc;
- }
- __statfs_to_statvfs(tmp, result);
- return 0;
-}
-__strong_alias(fstatvfs64, fstatvfs);
diff --git a/libc/bionic/sys_statvfs.cpp b/libc/bionic/sys_statvfs.cpp
new file mode 100644
index 000000000..ef5dc57da
--- /dev/null
+++ b/libc/bionic/sys_statvfs.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/statvfs.h>
+
+// libc++ uses statvfs (for Darwin compatibility), but on Linux statvfs is
+// just another name for statfs, so it didn't arrive until API level 19. We
+// make the implementation available as inlines to support std::filesystem
+// for NDK users (see https://github.com/android-ndk/ndk/issues/609).
+
+#define __BIONIC_SYS_STATVFS_INLINE /* Out of line. */
+#define __BIONIC_NEED_STATVFS_INLINES
+#undef __BIONIC_NEED_STATVFS64_INLINES
+#include <bits/sys_statvfs_inlines.h>
+
+// Historically we provided actual symbols for statvfs64 and fstatvfs64.
+// They're not particularly useful, but we can't take them away.
+__strong_alias(statvfs64, statvfs);
+__strong_alias(fstatvfs64, fstatvfs);
diff --git a/libc/include/android/legacy_sys_statvfs_inlines.h b/libc/include/android/legacy_sys_statvfs_inlines.h
new file mode 100644
index 000000000..369e6a259
--- /dev/null
+++ b/libc/include/android/legacy_sys_statvfs_inlines.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+/**
+ * @file legacy_sys_statvfs_inlines.h
+ * @brief Inline definitions of statvfs/fstatvfs for old API levels.
+ */
+
+#include <sys/cdefs.h>
+
+#if __ANDROID_API__ < 21
+
+#define __BIONIC_NEED_STATVFS64_INLINES
+#if __ANDROID_API__ < 19
+#define __BIONIC_NEED_STATVFS_INLINES
+#endif
+
+#define __BIONIC_SYS_STATVFS_INLINE static __inline
+#include <bits/sys_statvfs_inlines.h>
+
+#endif
diff --git a/libc/include/bits/sys_statvfs_inlines.h b/libc/include/bits/sys_statvfs_inlines.h
new file mode 100644
index 000000000..fd4578cd5
--- /dev/null
+++ b/libc/include/bits/sys_statvfs_inlines.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <sys/cdefs.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+#if defined(__BIONIC_SYS_STATVFS_INLINE)
+
+__BEGIN_DECLS
+
+#if defined(__BIONIC_NEED_STATVFS_INLINES)
+
+static __inline void __bionic_statfs_to_statvfs(const struct statfs* __in,
+ struct statvfs* __out) {
+ __out->f_bsize = __in->f_bsize;
+ __out->f_frsize = __in->f_frsize;
+ __out->f_blocks = __in->f_blocks;
+ __out->f_bfree = __in->f_bfree;
+ __out->f_bavail = __in->f_bavail;
+ __out->f_files = __in->f_files;
+ __out->f_ffree = __in->f_ffree;
+ __out->f_favail = __in->f_ffree;
+ __out->f_fsid = __in->f_fsid.__val[0] |
+ __BIONIC_CAST(static_cast, uint64_t, __in->f_fsid.__val[1]) << 32;
+ __out->f_flag = __in->f_flags;
+ __out->f_namemax = __in->f_namelen;
+}
+
+__BIONIC_SYS_STATVFS_INLINE int statvfs(const char* __path,
+ struct statvfs* __result) {
+ struct statfs __tmp;
+ int __rc = statfs(__path, &__tmp);
+ if (__rc != 0) return __rc;
+ __bionic_statfs_to_statvfs(&__tmp, __result);
+ return 0;
+}
+
+__BIONIC_SYS_STATVFS_INLINE int fstatvfs(int __fd,
+ struct statvfs* __result) {
+ struct statfs __tmp;
+ int __rc = fstatfs(__fd, &__tmp);
+ if (__rc != 0) return __rc;
+ __bionic_statfs_to_statvfs(&__tmp, __result);
+ return 0;
+}
+
+#endif
+
+#if defined(__BIONIC_NEED_STATVFS64_INLINES)
+
+__BIONIC_SYS_STATVFS_INLINE int statvfs64(const char* __path,
+ struct statvfs64* __result) {
+ return statvfs(__path, __BIONIC_CAST(reinterpret_cast, struct statvfs*,
+ __result));
+}
+
+__BIONIC_SYS_STATVFS_INLINE int fstatvfs64(int __fd,
+ struct statvfs64* __result) {
+ return fstatvfs(__fd, __BIONIC_CAST(reinterpret_cast, struct statvfs*,
+ __result));
+}
+
+#endif
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/sys/statvfs.h b/libc/include/sys/statvfs.h
index e60cadc75..93fa3d7a2 100644
--- a/libc/include/sys/statvfs.h
+++ b/libc/include/sys/statvfs.h
@@ -14,8 +14,12 @@
* limitations under the License.
*/
-#ifndef _SYS_STATVFS_H_
-#define _SYS_STATVFS_H_
+#pragma once
+
+/**
+ * @file sys/statvfs.h
+ * @brief Filesystem statistics.
+ */
#include <stdint.h>
#include <sys/cdefs.h>
@@ -23,47 +27,123 @@
__BEGIN_DECLS
-#ifdef __LP64__
-#define __STATVFS64_RESERVED uint32_t __f_reserved[6];
-#else
-#define __STATVFS64_RESERVED
+struct statvfs {
+ /** Block size. */
+ unsigned long f_bsize;
+ /** Fragment size. */
+ unsigned long f_frsize;
+ /** Total size of filesystem in `f_frsize` blocks. */
+ fsblkcnt_t f_blocks;
+ /** Number of free blocks. */
+ fsblkcnt_t f_bfree;
+ /** Number of free blocks for non-root. */
+ fsblkcnt_t f_bavail;
+ /** Number of inodes. */
+ fsfilcnt_t f_files;
+ /** Number of free inodes. */
+ fsfilcnt_t f_ffree;
+ /** Number of free inodes for non-root. */
+ fsfilcnt_t f_favail;
+ /** Filesystem id. */
+ unsigned long f_fsid;
+ /** Mount flags. (See `ST_` constants.) */
+ unsigned long f_flag;
+ /** Maximum filename length. */
+ unsigned long f_namemax;
+
+#if defined(__LP64__)
+ uint32_t __f_reserved[6];
#endif
+};
+
+struct statvfs64 {
+ /** Block size. */
+ unsigned long f_bsize;
+ /** Fragment size. */
+ unsigned long f_frsize;
+ /** Total size of filesystem in `f_frsize` blocks. */
+ fsblkcnt_t f_blocks;
+ /** Number of free blocks. */
+ fsblkcnt_t f_bfree;
+ /** Number of free blocks for non-root. */
+ fsblkcnt_t f_bavail;
+ /** Number of inodes. */
+ fsfilcnt_t f_files;
+ /** Number of free inodes. */
+ fsfilcnt_t f_ffree;
+ /** Number of free inodes for non-root. */
+ fsfilcnt_t f_favail;
+ /** Filesystem id. */
+ unsigned long f_fsid;
+ /** Mount flags. (See `ST_` constants.) */
+ unsigned long f_flag;
+ /** Maximum filename length. */
+ unsigned long f_namemax;
-#define __STATVFS64_BODY \
- unsigned long f_bsize; \
- unsigned long f_frsize; \
- fsblkcnt_t f_blocks; \
- fsblkcnt_t f_bfree; \
- fsblkcnt_t f_bavail; \
- fsfilcnt_t f_files; \
- fsfilcnt_t f_ffree; \
- fsfilcnt_t f_favail; \
- unsigned long f_fsid; \
- unsigned long f_flag; \
- unsigned long f_namemax; \
- __STATVFS64_RESERVED
-
-struct statvfs { __STATVFS64_BODY };
-struct statvfs64 { __STATVFS64_BODY };
-
-#undef __STATVFS64_BODY
-#undef __STATVFS64_RESERVED
+#if defined(__LP64__)
+ uint32_t __f_reserved[6];
+#endif
+};
+/** Flag for `f_flag` in `struct statvfs`: mounted read-only. */
#define ST_RDONLY 0x0001
+
+/** Flag for `f_flag` in `struct statvfs`: setuid/setgid ignored. */
#define ST_NOSUID 0x0002
+
+/** Flag for `f_flag` in `struct statvfs`: access to device files disallowed. */
#define ST_NODEV 0x0004
+
+/** Flag for `f_flag` in `struct statvfs`: execution disallowed. */
#define ST_NOEXEC 0x0008
+
+/** Flag for `f_flag` in `struct statvfs`: writes synced immediately. */
#define ST_SYNCHRONOUS 0x0010
+
+/** Flag for `f_flag` in `struct statvfs`: mandatory locking permitted. */
#define ST_MANDLOCK 0x0040
+
+/** Flag for `f_flag` in `struct statvfs`: access times not updated. */
#define ST_NOATIME 0x0400
+
+/** Flag for `f_flag` in `struct statvfs`: directory access times not updated. */
#define ST_NODIRATIME 0x0800
+
+/** Flag for `f_flag` in `struct statvfs`: see `MS_RELATIME`. */
#define ST_RELATIME 0x1000
+#if __ANDROID_API__ >= 19
+// These functions are implemented as static inlines before API level 19.
+
+/**
+ * [statvfs(3)](http://man7.org/linux/man-pages/man3/statvfs.3.html)
+ * queries filesystem statistics for the given path.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ */
int statvfs(const char* __path, struct statvfs* __buf) __INTRODUCED_IN(19);
-int statvfs64(const char* __path, struct statvfs64* __buf) __INTRODUCED_IN(21);
+
+/**
+ * [fstatvfs(3)](http://man7.org/linux/man-pages/man3/fstatvfs.3.html)
+ * queries filesystem statistics for the given file descriptor.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ */
int fstatvfs(int __fd, struct statvfs* __buf) __INTRODUCED_IN(19);
+
+#endif
+
+#if __ANDROID_API__ >= 21
+// These functions are implemented as static inlines before API level 21.
+
+/** Equivalent to statvfs(). */
+int statvfs64(const char* __path, struct statvfs64* __buf) __INTRODUCED_IN(21);
+
+/** Equivalent to fstatvfs(). */
int fstatvfs64(int __fd, struct statvfs64* __buf) __INTRODUCED_IN(21);
+#endif
+
__END_DECLS
-#endif
+#include <android/legacy_sys_statvfs_inlines.h>