1 /* 2 * Copyright (c) 2015-2016 Dmitry V. Levin <ldv (at) altlinux.org> 3 * Copyright (c) 2016-2017 The strace developers. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <stdio.h> 30 #include <fcntl.h> 31 #include <unistd.h> 32 33 #include <linux/types.h> 34 #include <asm/statfs.h> 35 36 #include "xlat.h" 37 #include "xlat/fsmagic.h" 38 #include "xlat/statfs_flags.h" 39 40 #define PRINT_NUM(arg) \ 41 do { \ 42 if (sizeof(b->arg) == sizeof(int)) \ 43 printf(", %s=%u", #arg, \ 44 (unsigned int) b->arg); \ 45 else if (sizeof(b->arg) == sizeof(long)) \ 46 printf(", %s=%lu", #arg, \ 47 (unsigned long) b->arg); \ 48 else \ 49 printf(", %s=%llu", #arg, \ 50 (unsigned long long) b->arg); \ 51 } while (0) 52 53 static void 54 print_statfs_type(const char *const prefix, const unsigned int magic) 55 { 56 fputs(prefix, stdout); 57 unsigned int i; 58 for (i = 0; i < ARRAY_SIZE(fsmagic); ++i) 59 if (magic == fsmagic[i].val) { 60 fputs(fsmagic[i].str, stdout); 61 return; 62 } 63 printf("%#x", magic); 64 } 65 66 static void 67 print_statfs(const char *const sample, const char *magic_str) 68 { 69 int fd = open(sample, O_RDONLY); 70 if (fd < 0) 71 perror_msg_and_skip("open: %s", sample); 72 73 TAIL_ALLOC_OBJECT_CONST_PTR(STRUCT_STATFS, b); 74 long rc = SYSCALL_INVOKE(sample, fd, b, sizeof(*b)); 75 if (rc) 76 perror_msg_and_skip(SYSCALL_NAME); 77 78 PRINT_SYSCALL_HEADER(sample, fd, sizeof(*b)); 79 if (magic_str) 80 printf("{f_type=%s", magic_str); 81 else 82 print_statfs_type("{f_type=", b->f_type); 83 PRINT_NUM(f_bsize); 84 PRINT_NUM(f_blocks); 85 PRINT_NUM(f_bfree); 86 PRINT_NUM(f_bavail); 87 PRINT_NUM(f_files); 88 PRINT_NUM(f_ffree); 89 #ifdef PRINT_F_FSID 90 printf(", f_fsid={val=[%u, %u]}", 91 (unsigned) b->PRINT_F_FSID[0], (unsigned) b->PRINT_F_FSID[1]); 92 #endif 93 PRINT_NUM(f_namelen); 94 #ifdef PRINT_F_FRSIZE 95 PRINT_NUM(f_frsize); 96 #endif 97 #ifdef PRINT_F_FLAGS 98 if (b->f_flags & ST_VALID) { 99 printf(", f_flags="); 100 printflags(statfs_flags, b->f_flags, "ST_???"); 101 } 102 #endif 103 printf("}) = 0\n"); 104 } 105 106 int 107 main(void) 108 { 109 print_statfs("/proc/self/status", "PROC_SUPER_MAGIC"); 110 111 print_statfs(".", NULL); 112 113 long rc = SYSCALL_INVOKE("", -1, 0, sizeof(STRUCT_STATFS)); 114 const char *errstr = sprintrc(rc); 115 PRINT_SYSCALL_HEADER("", -1, sizeof(STRUCT_STATFS)); 116 printf("NULL) = %s\n", errstr); 117 118 #ifdef CHECK_ODD_SIZE 119 const unsigned long addr = (unsigned long) 0xfacefeeddeadbeefULL; 120 rc = SYSCALL_INVOKE("", -1, addr, sizeof(STRUCT_STATFS) + 1); 121 errstr = sprintrc(rc); 122 PRINT_SYSCALL_HEADER("", -1, sizeof(STRUCT_STATFS) + 1); 123 printf("%#lx) = %s\n", addr, errstr); 124 #endif 125 126 puts("+++ exited with 0 +++"); 127 return 0; 128 } 129