1 /* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 /* 21 * NAME 22 * sysctl04.c 23 * 24 * DESCRIPTION 25 * Testcase to check that sysctl(2) sets errno to ENOTDIR 26 * 27 * ALGORITHM 28 * 1. Call sysctl(2) with sc_nlen set to 0, and expect ENOTDIR to be set. 29 * 2. Call sysctl(2) with sc_nlen greater than CTL_MAXNAME, and expect 30 * ENOTDIR to be set in the errno. 31 * 32 * USAGE: <for command-line> 33 * sysctl04 [-c n] [-e] [-i n] [-I x] [-P x] [-t] 34 * where, -c n : Run n copies concurrently. 35 * -e : Turn on errno logging. 36 * -i n : Execute test n times. 37 * -I x : Execute test for x seconds. 38 * -P x : Pause for x seconds between iterations. 39 * -t : Turn on syscall timing. 40 * 41 * HISTORY 42 * 07/2001 Ported by Wayne Boyer 43 * 44 * RESTRICTIONS 45 * None 46 */ 47 48 #include "test.h" 49 #include <stdio.h> 50 #include <errno.h> 51 #include <unistd.h> 52 #include <linux/unistd.h> 53 #include <linux/sysctl.h> 54 55 char *TCID = "sysctl04"; 56 57 /* This is an older/deprecated syscall that newer arches are omitting */ 58 #ifdef __NR_sysctl 59 60 int TST_TOTAL = 2; 61 62 int sysctl(int *name, int nlen, void *oldval, size_t * oldlenp, 63 void *newval, size_t newlen) 64 { 65 struct __sysctl_args args = 66 { name, nlen, oldval, oldlenp, newval, newlen }; 67 return syscall(__NR__sysctl, &args); 68 } 69 70 #define OSNAMESZ 100 71 72 void setup(void); 73 void cleanup(void); 74 75 struct test_case_t { 76 int size; 77 int error; 78 } TC[] = { 79 /* comment goes here */ 80 { 81 0, ENOTDIR}, 82 /* comment goes here */ 83 { 84 CTL_MAXNAME + 1, ENOTDIR} 85 }; 86 87 int main(int ac, char **av) 88 { 89 int lc; 90 91 char osname[OSNAMESZ]; 92 int i; 93 size_t osnamelth; 94 int name[] = { CTL_KERN, KERN_OSREV }; 95 96 tst_parse_opts(ac, av, NULL, NULL); 97 98 setup(); 99 100 osnamelth = sizeof(osname); 101 102 for (lc = 0; TEST_LOOPING(lc); lc++) { 103 104 /* reset tst_count in case we are looping */ 105 tst_count = 0; 106 107 /* loop through the test cases */ 108 for (i = 0; i < TST_TOTAL; i++) { 109 110 TEST(sysctl(name, 0, osname, &osnamelth, 0, 0)); 111 112 if (TEST_RETURN != -1) { 113 tst_resm(TFAIL, "call succeeded unexpectedly"); 114 continue; 115 } 116 117 if (TEST_ERRNO == TC[i].error) { 118 tst_resm(TPASS, "expected failure - " 119 "errno = %d : %s", TEST_ERRNO, 120 strerror(TEST_ERRNO)); 121 } else if (TEST_ERRNO == ENOSYS) { 122 tst_resm(TCONF, 123 "You may need to make CONFIG_SYSCTL_SYSCALL=y" 124 " to your kernel config."); 125 } else { 126 tst_resm(TFAIL, "unexpected error - %d : %s - " 127 "expected %d", TEST_ERRNO, 128 strerror(TEST_ERRNO), TC[i].error); 129 } 130 } 131 } 132 cleanup(); 133 134 tst_exit(); 135 } 136 137 /* 138 * setup() - performs all ONE TIME setup for this test. 139 */ 140 void setup(void) 141 { 142 143 tst_sig(NOFORK, DEF_HANDLER, cleanup); 144 145 TEST_PAUSE; 146 } 147 148 /* 149 * cleanup() - performs all ONE TIME cleanup for this test at 150 * completion or premature exit. 151 */ 152 void cleanup(void) 153 { 154 155 } 156 157 #else 158 int TST_TOTAL = 0; 159 160 int main(void) 161 { 162 163 tst_brkm(TCONF, NULL, 164 "This test needs a kernel that has sysctl syscall."); 165 } 166 #endif 167