1 /************************************************************************* 2 * Copyright (c) Crackerjack Project., 2007 3 * Copyright (c) Manas Kumar Nayak <maknayak (at) in.ibm.com> 4 * Copyright (c) Cyril Hrubis <chrubis (at) suse.cz> 2011 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 14 * the GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 * 20 ************************************************************************/ 21 22 #include "set_thread_area.h" 23 24 char *TCID = "set_thread_area_01"; 25 int TST_TOTAL = 6; 26 27 #if defined(HAVE_ASM_LDT_H) && defined(HAVE_STRUCT_USER_DESC) 28 29 static void cleanup(void) 30 { 31 } 32 33 static void setup(void) 34 { 35 TEST_PAUSE; 36 } 37 38 struct test { 39 int syscall; 40 const char *const syscall_name; 41 thread_area_s *u_info; 42 int exp_ret; 43 int exp_errno; 44 }; 45 46 /* 47 * The set_thread_area uses a free entry_number if entry number is set to -1 48 * and upon the syscall exit the entry number is set to entry which was used. 49 * So when we call get_thread_area on u_info1, the entry number is initalized 50 * corectly by the previous set_thread_area. 51 */ 52 static struct user_desc u_info1 = {.entry_number = -1 }; 53 static struct user_desc u_info2 = {.entry_number = -2 }; 54 55 #define VALUE_AND_STRING(val) val, #val 56 57 static struct test tests[] = { 58 {VALUE_AND_STRING(__NR_set_thread_area), &u_info1, 0, 0}, 59 {VALUE_AND_STRING(__NR_get_thread_area), &u_info1, 0, 0}, 60 {VALUE_AND_STRING(__NR_set_thread_area), &u_info2, -1, EINVAL}, 61 {VALUE_AND_STRING(__NR_get_thread_area), &u_info2, -1, EINVAL}, 62 {VALUE_AND_STRING(__NR_set_thread_area), (void *)-9, -1, EFAULT}, 63 {VALUE_AND_STRING(__NR_get_thread_area), (void *)-9, -1, EFAULT}, 64 }; 65 66 int main(int argc, char *argv[]) 67 { 68 int lc; 69 unsigned i; 70 71 tst_parse_opts(argc, argv, NULL, NULL); 72 73 setup(); 74 75 for (lc = 0; TEST_LOOPING(lc); lc++) { 76 for (i = 0; i < sizeof(tests) / sizeof(struct test); i++) { 77 TEST(ltp_syscall(tests[i].syscall, tests[i].u_info)); 78 79 if (TEST_RETURN != tests[i].exp_ret) { 80 tst_resm(TFAIL, "%s returned %li expected %i", 81 tests[i].syscall_name, 82 TEST_RETURN, tests[i].exp_ret); 83 continue; 84 } 85 86 if (TEST_ERRNO != tests[i].exp_errno) { 87 tst_resm(TFAIL, 88 "%s failed with %i (%s) expected %i (%s)", 89 tests[i].syscall_name, TEST_ERRNO, 90 strerror(TEST_ERRNO), 91 tests[i].exp_errno, 92 strerror(tests[i].exp_errno)); 93 continue; 94 } 95 96 tst_resm(TPASS, "%s returned %li errno %i (%s)", 97 tests[i].syscall_name, TEST_RETURN, 98 TEST_ERRNO, strerror(TEST_ERRNO)); 99 } 100 } 101 102 cleanup(); 103 tst_exit(); 104 } 105 #else 106 int main(void) 107 { 108 tst_brkm(TCONF, NULL, 109 "set_thread_area isn't available for this architecture"); 110 } 111 #endif 112