diff options
author | Elliott Hughes <enh@google.com> | 2019-09-03 15:42:34 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-09-03 15:42:34 -0700 |
commit | 8049184be8e79fc591a114d3253ff5b932678c00 (patch) | |
tree | df3a4dafa844d29d18a302a47ad9483593f8569b | |
parent | f0e70113d53803fdcb37b6c3c49203299f95da2e (diff) | |
parent | 37ff081e886f29c10a5f549094a53c8d547c6565 (diff) | |
download | bionic-8049184be8e79fc591a114d3253ff5b932678c00.tar.gz |
Merge "Support statvfs on API levels before 19."
am: 37ff081e88
Change-Id: Id79699c172491d805543e370980bfc736802f570
-rw-r--r-- | libc/Android.bp | 3 | ||||
-rw-r--r-- | libc/bionic/sys_statfs.cpp (renamed from libc/bionic/statvfs.cpp) | 48 | ||||
-rw-r--r-- | libc/bionic/sys_statvfs.cpp | 32 | ||||
-rw-r--r-- | libc/include/android/legacy_sys_statvfs_inlines.h | 48 | ||||
-rw-r--r-- | libc/include/bits/sys_statvfs_inlines.h | 95 | ||||
-rw-r--r-- | libc/include/sys/statvfs.h | 134 |
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> |