• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  *	ioctl01.c
23  *
24  * DESCRIPTION
25  *	Testcase to check the errnos set by the ioctl(2) system call.
26  *
27  * ALGORITHM
28  *	1. EBADF: Pass an invalid fd to ioctl(fd, ..) and expect EBADF.
29  *	2. EFAULT: Pass an invalid address of arg in ioctl(fd, .., arg)
30  *	3. EINVAL: Pass invalid cmd in ioctl(fd, cmd, arg)
31  *	4. ENOTTY: Pass an non-streams fd in ioctl(fd, cmd, arg)
32  *	5. EFAULT: Pass a NULL address for termio
33  *
34  * USAGE:  <for command-line>
35  *  ioctl01 -D /dev/tty[0-9] [-c n] [-e] [-i n] [-I x] [-P x] [-t]
36  *     where,  -c n : Run n copies concurrently.
37  *             -e   : Turn on errno logging.
38  *             -i n : Execute test n times.
39  *             -I x : Execute test for x seconds.
40  *             -P x : Pause for x seconds between iterations.
41  *             -t   : Turn on syscall timing.
42  *
43  * HISTORY
44  *	07/2001 Ported by Wayne Boyer
45  *	04/2002 Fixes by wjhuie
46  *
47  * RESTRICTIONS
48  *      test must be run with the -D option
49  *      test may have to be run as root depending on the tty permissions
50  */
51 
52 #include <errno.h>
53 #include <fcntl.h>
54 #include <stdio.h>
55 #include <termio.h>
56 #include <termios.h>
57 #include "test.h"
58 
59 char *TCID = "ioctl01";
60 int TST_TOTAL = 5;
61 
62 #define	INVAL_IOCTL	9999999
63 
64 static void setup(void);
65 static void cleanup(void);
66 static void help(void);
67 
68 static int fd, fd1;
69 static int bfd = -1;
70 
71 static struct termio termio;
72 
73 static struct test_case_t {
74 	int *fd;
75 	int request;
76 	struct termio *s_tio;
77 	int error;
78 } TC[] = {
79 	/* file descriptor is invalid */
80 	{
81 	&bfd, TCGETA, &termio, EBADF},
82 	    /* termio address is invalid */
83 	{
84 	&fd, TCGETA, (struct termio *)-1, EFAULT},
85 	    /* command is invalid */
86 	    /* This errno value was changed from EINVAL to ENOTTY
87 	     * by kernel commit 07d106d0 and bbb63c51
88 	     */
89 	{
90 	&fd, INVAL_IOCTL, &termio, ENOTTY},
91 	    /* file descriptor is for a regular file */
92 	{
93 	&fd1, TCGETA, &termio, ENOTTY},
94 	    /* termio is NULL */
95 	{
96 	&fd, TCGETA, NULL, EFAULT}
97 };
98 
99 static int Devflag;
100 static char *devname;
101 
102 static option_t options[] = {
103 	{"D:", &Devflag, &devname},
104 	{NULL, NULL, NULL}
105 };
106 
main(int ac,char ** av)107 int main(int ac, char **av)
108 {
109 	int lc;
110 	int i;
111 
112 	tst_parse_opts(ac, av, options, &help);
113 
114 	if (!Devflag)
115 		tst_brkm(TBROK, NULL, "You must specify a tty device with "
116 			 "the -D option.");
117 
118 	tst_require_root();
119 
120 	setup();
121 
122 	fd = open(devname, O_RDWR, 0777);
123 	if (fd == -1)
124 		tst_brkm(TBROK | TERRNO, cleanup, "Couldn't open %s", devname);
125 
126 	for (lc = 0; TEST_LOOPING(lc); lc++) {
127 
128 		tst_count = 0;
129 
130 		/* loop through the test cases */
131 		for (i = 0; i < TST_TOTAL; i++) {
132 
133 			TEST(ioctl(*(TC[i].fd), TC[i].request, TC[i].s_tio));
134 
135 			if (TEST_RETURN != -1) {
136 				tst_resm(TFAIL, "call succeeded unexpectedly");
137 				continue;
138 			}
139 
140 			if (TEST_ERRNO == TC[i].error)
141 				tst_resm(TPASS | TTERRNO, "failed as expected");
142 			else
143 				tst_resm(TFAIL | TTERRNO,
144 					 "failed unexpectedly; expected %d - %s",
145 					 TC[i].error, strerror(TC[i].error));
146 		}
147 	}
148 	cleanup();
149 
150 	tst_exit();
151 }
152 
help(void)153 static void help(void)
154 {
155 	printf("  -D <tty device> : for example, /dev/tty[0-9]\n");
156 }
157 
setup(void)158 static void setup(void)
159 {
160 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
161 
162 	TEST_PAUSE;
163 
164 	/* make a temporary directory and cd to it */
165 	tst_tmpdir();
166 
167 	if (tst_kvercmp(3, 7, 0) < 0) {
168 		TC[2].error = EINVAL;
169 	}
170 
171 	/* create a temporary file */
172 	fd1 = open("x", O_CREAT, 0777);
173 	if (fd1 == -1)
174 		tst_resm(TFAIL | TERRNO, "Could not open test file");
175 }
176 
cleanup(void)177 static void cleanup(void)
178 {
179 	close(fd1);
180 
181 	tst_rmdir();
182 }
183