1 /*
2 *
3 * Copyright (c) Wipro Technologies, 2002. All Rights Reserved.
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 *
22 * TEST IDENTIFIER : sethostname02
23 *
24 * EXECUTED BY : root / superuser
25 *
26 * TEST TITLE : test for checking error conditions for sethostname(2)
27 *
28 * TEST CASE TOTAL : 3
29 *
30 * AUTHOR : Suresh Babu V. <suresh.babu@wipro.com>
31 *
32 * SIGNALS
33 * Uses SIGUSR1 to pause before test if option set.
34 * (See the parse_opts(3) man page).
35 *
36 * DESCRIPTION
37 * Verify that,
38 * 1) sethostname(2) returns -1 and sets errno to EINVAL if the parameter,
39 * len is less than zero.
40 * 2) sethostname(2) returns -1 and sets errno to EINVAL if len is greater
41 * than the maximum allowed size.
42 * 3) sethostname(2) returns -1 and sets errno to EFAULT if an invalid
43 * address is given for name.
44 *
45 * Setup:
46 * Setup signal handling.
47 * Save current hostname
48 * Pause for SIGUSR1 if option specified.
49 *
50 * Test:
51 * Loop if the proper options are given.
52 * Execute system call
53 * Check return code, if system call failed and errno set == expected errno
54 * Issue sys call fails with expected return value and errno.
55 * Otherwise,
56 * Issue sys call failed to produce expected error.
57 *
58 * Cleanup:
59 * Restore old hostname.
60 * Print errno log and/or timing stats if options given
61 *
62 * Side Effects :
63 * sethostname() is resetting value to NULL, if an invalid address
64 * is given for name. So, to overcome this problem, hostname is
65 * resetting to original value as part of cleanup() routine.
66 *
67 * USAGE: <for command-line>
68 * sethostname02 [-c n] [-e] [-i n] [-I x] [-P x] [-p] [-t] [-h]
69 * where, -c n : Run n copies concurrently.
70 * -e : Turn on errno logging.
71 * -i n : Execute test n times.
72 * -I x : Execute test for x seconds.
73 * -P x : Pause for x seconds between iterations.
74 * -p : Pause for SIGUSR1 before startingt
75 * -t : Turn on syscall timing.
76 * -h : Display usage information.
77 *
78 ***************************************************************************/
79 #include <stdio.h>
80 #include <string.h>
81 #include <errno.h>
82 #include <sys/utsname.h>
83 #include "test.h"
84
85 #define LARGE_LENGTH MAX_LENGTH + 1
86 #define MAX_LENGTH _UTSNAME_LENGTH - 1
87
88 static void cleanup(void);
89 static void setup(void);
90
91 char *TCID = "sethostname02";
92 static char hostname[MAX_LENGTH];
93 static char hname[MAX_LENGTH];
94 static char largehost[LARGE_LENGTH];
95 static struct test_case_t {
96 char *err_desc; /* error description */
97 int exp_errno; /* Expected error no */
98 char *exp_errval; /* Expected error value string */
99 char *name; /* hostname */
100 int len; /* length */
101 } testcases[] = {
102 {
103 "Length is -ve", EINVAL, "EINVAL", hostname, -1}, {
104 "Length > max allowed size", EINVAL, "EINVAL", largehost,
105 sizeof(largehost)}
106 ,
107 #ifndef UCLINUX
108 /* Skip since uClinux does not implement memory protection */
109 {
110 "Invalid address ", EFAULT, "EFAULT", (void *)-1,
111 sizeof(hostname)}
112 #endif
113 };
114
115 int TST_TOTAL = ARRAY_SIZE(testcases);
116
main(int ac,char ** av)117 int main(int ac, char **av)
118 {
119 int i;
120 int lc;
121
122 tst_parse_opts(ac, av, NULL, NULL);
123
124 /* Do initial setup */
125 setup();
126
127 /* check for looping state if -i option is given */
128 for (lc = 0; TEST_LOOPING(lc); lc++) {
129 tst_count = 0;
130
131 for (i = 0; i < TST_TOTAL; ++i) {
132
133 /*
134 * Test the system call.
135 */
136 TEST(sethostname(testcases[i].name, testcases[i].len));
137
138 if ((TEST_RETURN == -1) &&
139 (TEST_ERRNO == testcases[i].exp_errno)) {
140 tst_resm(TPASS, "expected failure; Got %s",
141 testcases[i].exp_errval);
142 } else {
143 tst_resm(TFAIL, "call failed to produce "
144 "expected error; errno: %d : %s",
145 TEST_ERRNO, strerror(TEST_ERRNO));
146 }
147 }
148 }
149 /* do cleanup and exit */
150 cleanup();
151
152 tst_exit();
153 }
154
155 /*
156 * setup() - performs all one time setup for this test.
157 */
setup(void)158 void setup(void)
159 {
160 int ret;
161
162 tst_require_root();
163
164 /* capture the signals */
165 tst_sig(NOFORK, DEF_HANDLER, cleanup);
166
167 /* Keep the host name before starting the test */
168 if ((ret = gethostname(hname, sizeof(hname))) < 0) {
169 tst_brkm(TBROK, NULL, "gethostname() failed while"
170 " getting current host name");
171 }
172
173 /* Pause if the option was specified */
174 TEST_PAUSE;
175 }
176
177 /*
178 * cleanup() - performs all one time cleanup for this test
179 * completion or premature exit.
180 */
cleanup(void)181 void cleanup(void)
182 {
183 int ret;
184
185 /* Set the host name back to original name */
186 if ((ret = sethostname(hname, strlen(hname))) < 0) {
187 tst_resm(TWARN, "sethostname() failed while restoring"
188 " hostname to \"%s\"", hname);
189 }
190
191 }
192