1 /* 2 * Check decoding of utimes/osf_utimes syscall. 3 * 4 * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #ifndef TEST_SYSCALL_NR 31 # error TEST_SYSCALL_NR must be defined 32 #endif 33 34 #ifndef TEST_SYSCALL_STR 35 # error TEST_SYSCALL_STR must be defined 36 #endif 37 38 #ifndef TEST_STRUCT 39 # error TEST_STRUCT must be defined 40 #endif 41 42 #include <stdint.h> 43 #include <stdio.h> 44 #include <sys/time.h> 45 #include <unistd.h> 46 47 static void 48 print_tv(const TEST_STRUCT *const tv) 49 { 50 printf("{tv_sec=%lld, tv_usec=%llu}", 51 (long long) tv->tv_sec, 52 zero_extend_signed_to_ull(tv->tv_usec)); 53 print_time_t_usec(tv->tv_sec, 54 zero_extend_signed_to_ull(tv->tv_usec), 1); 55 } 56 57 static const char *errstr; 58 59 static long 60 k_utimes(const kernel_ulong_t pathname, const kernel_ulong_t times) 61 { 62 long rc = syscall(TEST_SYSCALL_NR, pathname, times); 63 errstr = sprintrc(rc); 64 return rc; 65 } 66 67 int 68 main(void) 69 { 70 static const char proto_fname[] = TEST_SYSCALL_STR "_sample"; 71 static const char qname[] = "\"" TEST_SYSCALL_STR "_sample\""; 72 73 char *const fname = tail_memdup(proto_fname, sizeof(proto_fname)); 74 const kernel_ulong_t kfname = (uintptr_t) fname; 75 TEST_STRUCT *const tv = tail_alloc(sizeof(*tv) * 2); 76 77 /* pathname */ 78 k_utimes(0, 0); 79 printf("%s(NULL, NULL) = %s\n", TEST_SYSCALL_STR, errstr); 80 81 k_utimes(kfname + sizeof(proto_fname) - 1, 0); 82 printf("%s(\"\", NULL) = %s\n", TEST_SYSCALL_STR, errstr); 83 84 k_utimes(kfname, 0); 85 printf("%s(%s, NULL) = %s\n", TEST_SYSCALL_STR, qname, errstr); 86 87 fname[sizeof(proto_fname) - 1] = '+'; 88 k_utimes(kfname, 0); 89 fname[sizeof(proto_fname) - 1] = '\0'; 90 printf("%s(%p, NULL) = %s\n", TEST_SYSCALL_STR, fname, errstr); 91 92 if (F8ILL_KULONG_SUPPORTED) { 93 k_utimes(f8ill_ptr_to_kulong(fname), 0); 94 printf("%s(%#jx, NULL) = %s\n", TEST_SYSCALL_STR, 95 (uintmax_t) f8ill_ptr_to_kulong(fname), errstr); 96 } 97 98 /* times */ 99 k_utimes(kfname, (uintptr_t) (tv + 1)); 100 printf("%s(%s, %p) = %s\n", TEST_SYSCALL_STR, 101 qname, tv + 1, errstr); 102 103 k_utimes(kfname, (uintptr_t) (tv + 2)); 104 printf("%s(%s, %p) = %s\n", TEST_SYSCALL_STR, 105 qname, tv + 2, errstr); 106 107 tv[0].tv_sec = 0xdeadbeefU; 108 tv[0].tv_usec = 0xfacefeedU; 109 tv[1].tv_sec = (time_t) 0xcafef00ddeadbeefLL; 110 tv[1].tv_usec = (suseconds_t) 0xbadc0dedfacefeedLL; 111 112 k_utimes(kfname, (uintptr_t) tv); 113 printf("%s(%s, [", TEST_SYSCALL_STR, qname); 114 print_tv(&tv[0]); 115 printf(", "); 116 print_tv(&tv[1]); 117 printf("]) = %s\n", errstr); 118 119 tv[0].tv_sec = 1492358607; 120 tv[0].tv_usec = 1000000; 121 tv[1].tv_sec = 1492356078; 122 tv[1].tv_usec = 1000001; 123 124 k_utimes(kfname, (uintptr_t) tv); 125 printf("%s(%s, [", TEST_SYSCALL_STR, qname); 126 print_tv(&tv[0]); 127 printf(", "); 128 print_tv(&tv[1]); 129 printf("]) = %s\n", errstr); 130 131 tv[0].tv_usec = 345678; 132 tv[1].tv_usec = 456789; 133 134 k_utimes(kfname, (uintptr_t) tv); 135 printf("%s(%s, [", TEST_SYSCALL_STR, qname); 136 print_tv(&tv[0]); 137 printf(", "); 138 print_tv(&tv[1]); 139 printf("]) = %s\n", errstr); 140 141 if (F8ILL_KULONG_SUPPORTED) { 142 k_utimes(kfname, f8ill_ptr_to_kulong(tv)); 143 printf("%s(%s, %#jx) = %s\n", TEST_SYSCALL_STR, 144 qname, (uintmax_t) f8ill_ptr_to_kulong(tv), errstr); 145 } 146 147 puts("+++ exited with 0 +++"); 148 return 0; 149 } 150