xref: /aosp_15_r20/external/ltp/testcases/kernel/pty/pty01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker  *
3*49cdfc7eSAndroid Build Coastguard Worker  *   Copyright (c) International Business Machines  Corp., 2002
4*49cdfc7eSAndroid Build Coastguard Worker  *
5*49cdfc7eSAndroid Build Coastguard Worker  *   This program is free software;  you can redistribute it and/or modify
6*49cdfc7eSAndroid Build Coastguard Worker  *   it under the terms of the GNU General Public License as published by
7*49cdfc7eSAndroid Build Coastguard Worker  *   the Free Software Foundation; either version 2 of the License, or
8*49cdfc7eSAndroid Build Coastguard Worker  *   (at your option) any later version.
9*49cdfc7eSAndroid Build Coastguard Worker  *
10*49cdfc7eSAndroid Build Coastguard Worker  *   This program is distributed in the hope that it will be useful,
11*49cdfc7eSAndroid Build Coastguard Worker  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12*49cdfc7eSAndroid Build Coastguard Worker  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13*49cdfc7eSAndroid Build Coastguard Worker  *   the GNU General Public License for more details.
14*49cdfc7eSAndroid Build Coastguard Worker  *
15*49cdfc7eSAndroid Build Coastguard Worker  *   You should have received a copy of the GNU General Public License
16*49cdfc7eSAndroid Build Coastguard Worker  *   along with this program;  if not, write to the Free Software
17*49cdfc7eSAndroid Build Coastguard Worker  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*49cdfc7eSAndroid Build Coastguard Worker  */
19*49cdfc7eSAndroid Build Coastguard Worker 
20*49cdfc7eSAndroid Build Coastguard Worker /* 12/23/2002	Port to LTP	[email protected] */
21*49cdfc7eSAndroid Build Coastguard Worker /* 06/30/2001	Port to Linux	[email protected] */
22*49cdfc7eSAndroid Build Coastguard Worker 
23*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
24*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
25*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
26*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
27*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
28*49cdfc7eSAndroid Build Coastguard Worker #include <fcntl.h>
29*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
30*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
31*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
32*49cdfc7eSAndroid Build Coastguard Worker #include <termios.h>
33*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
34*49cdfc7eSAndroid Build Coastguard Worker 
35*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
36*49cdfc7eSAndroid Build Coastguard Worker #include "safe_macros.h"
37*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/ioctl.h"
38*49cdfc7eSAndroid Build Coastguard Worker 
39*49cdfc7eSAndroid Build Coastguard Worker char *TCID = "pty01";		/* Test program identifier.    */
40*49cdfc7eSAndroid Build Coastguard Worker int TST_TOTAL = 5;		/* Total number of test cases. */
41*49cdfc7eSAndroid Build Coastguard Worker /**************/
42*49cdfc7eSAndroid Build Coastguard Worker 
43*49cdfc7eSAndroid Build Coastguard Worker /*
44*49cdfc7eSAndroid Build Coastguard Worker  * pty master clone device
45*49cdfc7eSAndroid Build Coastguard Worker  */
46*49cdfc7eSAndroid Build Coastguard Worker #define MASTERCLONE "/dev/ptmx"
47*49cdfc7eSAndroid Build Coastguard Worker 
48*49cdfc7eSAndroid Build Coastguard Worker /*
49*49cdfc7eSAndroid Build Coastguard Worker  * string for testing read/write on ptys
50*49cdfc7eSAndroid Build Coastguard Worker  */
51*49cdfc7eSAndroid Build Coastguard Worker #define STRING "Linux Test Project\n"
52*49cdfc7eSAndroid Build Coastguard Worker 
53*49cdfc7eSAndroid Build Coastguard Worker /*
54*49cdfc7eSAndroid Build Coastguard Worker  * test buffer size
55*49cdfc7eSAndroid Build Coastguard Worker  */
56*49cdfc7eSAndroid Build Coastguard Worker #define TESTSIZE 1024
57*49cdfc7eSAndroid Build Coastguard Worker 
58*49cdfc7eSAndroid Build Coastguard Worker /*
59*49cdfc7eSAndroid Build Coastguard Worker  * mode we expect grantpt() to leave pty as
60*49cdfc7eSAndroid Build Coastguard Worker  */
61*49cdfc7eSAndroid Build Coastguard Worker #define PTY_MODE 020622
62*49cdfc7eSAndroid Build Coastguard Worker 
63*49cdfc7eSAndroid Build Coastguard Worker /*
64*49cdfc7eSAndroid Build Coastguard Worker  * number of procs for parallel test
65*49cdfc7eSAndroid Build Coastguard Worker  */
66*49cdfc7eSAndroid Build Coastguard Worker #define NUMPROCS 15
67*49cdfc7eSAndroid Build Coastguard Worker 
68*49cdfc7eSAndroid Build Coastguard Worker /*
69*49cdfc7eSAndroid Build Coastguard Worker  * test slave locking
70*49cdfc7eSAndroid Build Coastguard Worker  */
test1(void)71*49cdfc7eSAndroid Build Coastguard Worker static int test1(void)
72*49cdfc7eSAndroid Build Coastguard Worker {
73*49cdfc7eSAndroid Build Coastguard Worker 	int masterfd;		/* master pty fd */
74*49cdfc7eSAndroid Build Coastguard Worker 	int slavefd;		/* slave pty fd */
75*49cdfc7eSAndroid Build Coastguard Worker 	char *slavename;
76*49cdfc7eSAndroid Build Coastguard Worker 	struct stat st;
77*49cdfc7eSAndroid Build Coastguard Worker 	char buf[TESTSIZE];
78*49cdfc7eSAndroid Build Coastguard Worker 
79*49cdfc7eSAndroid Build Coastguard Worker 	masterfd = SAFE_OPEN(NULL, MASTERCLONE, O_RDWR);
80*49cdfc7eSAndroid Build Coastguard Worker 
81*49cdfc7eSAndroid Build Coastguard Worker 	slavename = ptsname(masterfd);
82*49cdfc7eSAndroid Build Coastguard Worker 	if (slavename == NULL) {
83*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "ptsname() call failed");
84*49cdfc7eSAndroid Build Coastguard Worker 	}
85*49cdfc7eSAndroid Build Coastguard Worker 
86*49cdfc7eSAndroid Build Coastguard Worker 	if (grantpt(masterfd) != 0) {
87*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "grantpt() call failed");
88*49cdfc7eSAndroid Build Coastguard Worker 	}
89*49cdfc7eSAndroid Build Coastguard Worker 
90*49cdfc7eSAndroid Build Coastguard Worker 	if (stat(slavename, &st) != 0) {
91*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "stat(%s) failed", slavename);
92*49cdfc7eSAndroid Build Coastguard Worker 	}
93*49cdfc7eSAndroid Build Coastguard Worker 	if (st.st_uid != getuid()) {
94*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "uid mismatch");
95*49cdfc7eSAndroid Build Coastguard Worker 	}
96*49cdfc7eSAndroid Build Coastguard Worker 
97*49cdfc7eSAndroid Build Coastguard Worker 	 /* grantpt() is a no-op in bionic. */
98*49cdfc7eSAndroid Build Coastguard Worker #ifndef __BIONIC__
99*49cdfc7eSAndroid Build Coastguard Worker 	if (st.st_mode != (S_IFCHR | S_IRUSR | S_IWUSR | S_IWGRP)) {
100*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "mode mismatch (mode=%o)", st.st_mode);
101*49cdfc7eSAndroid Build Coastguard Worker 	}
102*49cdfc7eSAndroid Build Coastguard Worker #endif
103*49cdfc7eSAndroid Build Coastguard Worker 
104*49cdfc7eSAndroid Build Coastguard Worker 	slavefd = open(slavename, O_RDWR);
105*49cdfc7eSAndroid Build Coastguard Worker 	if (slavefd >= 0) {
106*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "open didn't fail as expected!");
107*49cdfc7eSAndroid Build Coastguard Worker 	}
108*49cdfc7eSAndroid Build Coastguard Worker 
109*49cdfc7eSAndroid Build Coastguard Worker 	if (unlockpt(masterfd) != 0) {
110*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "unlockpt() failed");
111*49cdfc7eSAndroid Build Coastguard Worker 	}
112*49cdfc7eSAndroid Build Coastguard Worker 
113*49cdfc7eSAndroid Build Coastguard Worker 	slavefd = SAFE_OPEN(NULL, slavename, O_RDWR);
114*49cdfc7eSAndroid Build Coastguard Worker 
115*49cdfc7eSAndroid Build Coastguard Worker 	/*
116*49cdfc7eSAndroid Build Coastguard Worker 	 * test writing to the master / reading from the slave
117*49cdfc7eSAndroid Build Coastguard Worker 	 */
118*49cdfc7eSAndroid Build Coastguard Worker 	if (write(masterfd, STRING, strlen(STRING)) != strlen(STRING)) {
119*49cdfc7eSAndroid Build Coastguard Worker 		/*
120*49cdfc7eSAndroid Build Coastguard Worker 		 * XXX: the errno printout might be garbage, but better to be
121*49cdfc7eSAndroid Build Coastguard Worker 		 * safe than sorry..
122*49cdfc7eSAndroid Build Coastguard Worker 		 */
123*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL | TERRNO, NULL, "write to master");
124*49cdfc7eSAndroid Build Coastguard Worker 	}
125*49cdfc7eSAndroid Build Coastguard Worker 
126*49cdfc7eSAndroid Build Coastguard Worker 	if (read(slavefd, buf, strlen(STRING)) != strlen(STRING)) {
127*49cdfc7eSAndroid Build Coastguard Worker 		/* XXX: Same as write above.. */
128*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL | TERRNO, NULL, "read from slave");
129*49cdfc7eSAndroid Build Coastguard Worker 	}
130*49cdfc7eSAndroid Build Coastguard Worker 	if (strncmp(STRING, buf, strlen(STRING) - 1) != 0) {
131*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL, NULL,
132*49cdfc7eSAndroid Build Coastguard Worker 			 "strings are different (STRING = '%s' != buf = '%s')",
133*49cdfc7eSAndroid Build Coastguard Worker 			 STRING, buf);
134*49cdfc7eSAndroid Build Coastguard Worker 	}
135*49cdfc7eSAndroid Build Coastguard Worker 
136*49cdfc7eSAndroid Build Coastguard Worker 	/*
137*49cdfc7eSAndroid Build Coastguard Worker 	 * test writing to the slave / reading from the master
138*49cdfc7eSAndroid Build Coastguard Worker 	 */
139*49cdfc7eSAndroid Build Coastguard Worker 	if (write(slavefd, STRING, strlen(STRING)) != strlen(STRING)) {
140*49cdfc7eSAndroid Build Coastguard Worker 		/* XXX: Same as write above.. */
141*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL | TERRNO, NULL, "write to slave");
142*49cdfc7eSAndroid Build Coastguard Worker 	}
143*49cdfc7eSAndroid Build Coastguard Worker 
144*49cdfc7eSAndroid Build Coastguard Worker 	if (read(masterfd, buf, strlen(STRING)) != strlen(STRING)) {
145*49cdfc7eSAndroid Build Coastguard Worker 		/* XXX: Same as write above.. */
146*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL | TERRNO, NULL, "read from master");
147*49cdfc7eSAndroid Build Coastguard Worker 	}
148*49cdfc7eSAndroid Build Coastguard Worker 	if (strncmp(STRING, buf, strlen(STRING) - 1) != 0) {
149*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL, NULL,
150*49cdfc7eSAndroid Build Coastguard Worker 			 "strings are different (STRING = '%s' != buf = '%s').",
151*49cdfc7eSAndroid Build Coastguard Worker 			 STRING, buf);
152*49cdfc7eSAndroid Build Coastguard Worker 	}
153*49cdfc7eSAndroid Build Coastguard Worker 
154*49cdfc7eSAndroid Build Coastguard Worker 	/*
155*49cdfc7eSAndroid Build Coastguard Worker 	 * try an invalid ioctl on the slave...
156*49cdfc7eSAndroid Build Coastguard Worker 	 */
157*49cdfc7eSAndroid Build Coastguard Worker 	if (ioctl(slavefd, TIOCGWINSZ, NULL) == 0) {
158*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL, NULL,
159*49cdfc7eSAndroid Build Coastguard Worker 			 "invalid slave TIOCGWINSZ ioctl succeeded.. it should "
160*49cdfc7eSAndroid Build Coastguard Worker 			 "have failed");
161*49cdfc7eSAndroid Build Coastguard Worker 	}
162*49cdfc7eSAndroid Build Coastguard Worker 
163*49cdfc7eSAndroid Build Coastguard Worker 	/*
164*49cdfc7eSAndroid Build Coastguard Worker 	 * try an invalid ioctl on the master...
165*49cdfc7eSAndroid Build Coastguard Worker 	 */
166*49cdfc7eSAndroid Build Coastguard Worker 	if (ioctl(masterfd, TIOCGWINSZ, NULL) == 0) {
167*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL, NULL,
168*49cdfc7eSAndroid Build Coastguard Worker 			 "invalid master TIOCGWINSZ ioctl succeeded.. it should "
169*49cdfc7eSAndroid Build Coastguard Worker 			 "have failed");
170*49cdfc7eSAndroid Build Coastguard Worker 	}
171*49cdfc7eSAndroid Build Coastguard Worker 
172*49cdfc7eSAndroid Build Coastguard Worker 	/*
173*49cdfc7eSAndroid Build Coastguard Worker 	 * close pty fds
174*49cdfc7eSAndroid Build Coastguard Worker 	 */
175*49cdfc7eSAndroid Build Coastguard Worker 	if (close(slavefd) != 0) {
176*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "close of slave");
177*49cdfc7eSAndroid Build Coastguard Worker 	}
178*49cdfc7eSAndroid Build Coastguard Worker 	if (close(masterfd) != 0) {
179*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "close of master");
180*49cdfc7eSAndroid Build Coastguard Worker 	}
181*49cdfc7eSAndroid Build Coastguard Worker 	tst_resm(TPASS, "test1");
182*49cdfc7eSAndroid Build Coastguard Worker 	/** NOTREACHED **/
183*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
184*49cdfc7eSAndroid Build Coastguard Worker }
185*49cdfc7eSAndroid Build Coastguard Worker 
186*49cdfc7eSAndroid Build Coastguard Worker /*
187*49cdfc7eSAndroid Build Coastguard Worker  * test slave operations with closed master
188*49cdfc7eSAndroid Build Coastguard Worker  */
test2(void)189*49cdfc7eSAndroid Build Coastguard Worker static void test2(void)
190*49cdfc7eSAndroid Build Coastguard Worker {
191*49cdfc7eSAndroid Build Coastguard Worker 	int masterfd;		/* master pty fd */
192*49cdfc7eSAndroid Build Coastguard Worker 	int slavefd;		/* slave pty fd */
193*49cdfc7eSAndroid Build Coastguard Worker 	int i;
194*49cdfc7eSAndroid Build Coastguard Worker 	char *slavename;
195*49cdfc7eSAndroid Build Coastguard Worker 	char c;
196*49cdfc7eSAndroid Build Coastguard Worker 
197*49cdfc7eSAndroid Build Coastguard Worker 	masterfd = SAFE_OPEN(NULL, MASTERCLONE, O_RDWR);
198*49cdfc7eSAndroid Build Coastguard Worker 
199*49cdfc7eSAndroid Build Coastguard Worker 	slavename = ptsname(masterfd);
200*49cdfc7eSAndroid Build Coastguard Worker 	if (slavename == NULL) {
201*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "ptsname() call failed");
202*49cdfc7eSAndroid Build Coastguard Worker 	}
203*49cdfc7eSAndroid Build Coastguard Worker 
204*49cdfc7eSAndroid Build Coastguard Worker 	if (grantpt(masterfd) != 0) {
205*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "grantpt() call failed");
206*49cdfc7eSAndroid Build Coastguard Worker 	}
207*49cdfc7eSAndroid Build Coastguard Worker 
208*49cdfc7eSAndroid Build Coastguard Worker 	if (unlockpt(masterfd) != 0) {
209*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "unlockpt() call failed");
210*49cdfc7eSAndroid Build Coastguard Worker 	}
211*49cdfc7eSAndroid Build Coastguard Worker 
212*49cdfc7eSAndroid Build Coastguard Worker 	slavefd = SAFE_OPEN(NULL, slavename, O_RDWR);
213*49cdfc7eSAndroid Build Coastguard Worker 
214*49cdfc7eSAndroid Build Coastguard Worker 	/*
215*49cdfc7eSAndroid Build Coastguard Worker 	 * close pty fds.  See what happens when we close the master
216*49cdfc7eSAndroid Build Coastguard Worker 	 * first.
217*49cdfc7eSAndroid Build Coastguard Worker 	 */
218*49cdfc7eSAndroid Build Coastguard Worker 	if (close(masterfd) != 0) {
219*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "close()");
220*49cdfc7eSAndroid Build Coastguard Worker 	}
221*49cdfc7eSAndroid Build Coastguard Worker 
222*49cdfc7eSAndroid Build Coastguard Worker 	errno = 0;
223*49cdfc7eSAndroid Build Coastguard Worker 	if ((i = read(slavefd, &c, 1)) == 1) {
224*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL, NULL,
225*49cdfc7eSAndroid Build Coastguard Worker 			 "reading from slave fd should have failed, but didn't"
226*49cdfc7eSAndroid Build Coastguard Worker 			 "(read '%c')", c);
227*49cdfc7eSAndroid Build Coastguard Worker 	}
228*49cdfc7eSAndroid Build Coastguard Worker 
229*49cdfc7eSAndroid Build Coastguard Worker 	if ((i = write(slavefd, &c, 1)) == 1) {
230*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL, NULL,
231*49cdfc7eSAndroid Build Coastguard Worker 			 "writing to slave fd should have failed, but didn't");
232*49cdfc7eSAndroid Build Coastguard Worker 	}
233*49cdfc7eSAndroid Build Coastguard Worker 
234*49cdfc7eSAndroid Build Coastguard Worker 	if (ioctl(slavefd, TIOCGWINSZ, NULL) == 0) {
235*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL, NULL,
236*49cdfc7eSAndroid Build Coastguard Worker 			 "trying TIOCGWINSZ on slave fd should have failed, "
237*49cdfc7eSAndroid Build Coastguard Worker 			 "but didn't");
238*49cdfc7eSAndroid Build Coastguard Worker 	}
239*49cdfc7eSAndroid Build Coastguard Worker 
240*49cdfc7eSAndroid Build Coastguard Worker 	if (close(slavefd) != 0) {
241*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "close");
242*49cdfc7eSAndroid Build Coastguard Worker 	}
243*49cdfc7eSAndroid Build Coastguard Worker 	tst_resm(TPASS, "test2");
244*49cdfc7eSAndroid Build Coastguard Worker }
245*49cdfc7eSAndroid Build Coastguard Worker 
246*49cdfc7eSAndroid Build Coastguard Worker /*
247*49cdfc7eSAndroid Build Coastguard Worker  * test operations on master with closed slave
248*49cdfc7eSAndroid Build Coastguard Worker  */
test3(void)249*49cdfc7eSAndroid Build Coastguard Worker static void test3(void)
250*49cdfc7eSAndroid Build Coastguard Worker {
251*49cdfc7eSAndroid Build Coastguard Worker 	int masterfd;		/* master pty fd */
252*49cdfc7eSAndroid Build Coastguard Worker 
253*49cdfc7eSAndroid Build Coastguard Worker 	masterfd = SAFE_OPEN(NULL, MASTERCLONE, O_RDWR);
254*49cdfc7eSAndroid Build Coastguard Worker 
255*49cdfc7eSAndroid Build Coastguard Worker 	if (ioctl(masterfd, TIOCGWINSZ, NULL) == 0) {
256*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL | TERRNO, NULL,
257*49cdfc7eSAndroid Build Coastguard Worker 			 "trying TIOCGWINSZ on master with no open slave "
258*49cdfc7eSAndroid Build Coastguard Worker 			 "succeeded unexpectedly");
259*49cdfc7eSAndroid Build Coastguard Worker 	}
260*49cdfc7eSAndroid Build Coastguard Worker 	tst_resm(TPASS, "test3");
261*49cdfc7eSAndroid Build Coastguard Worker }
262*49cdfc7eSAndroid Build Coastguard Worker 
263*49cdfc7eSAndroid Build Coastguard Worker /*
264*49cdfc7eSAndroid Build Coastguard Worker  * test multiple opens on slave side of pty
265*49cdfc7eSAndroid Build Coastguard Worker  */
test4(void)266*49cdfc7eSAndroid Build Coastguard Worker static void test4(void)
267*49cdfc7eSAndroid Build Coastguard Worker {
268*49cdfc7eSAndroid Build Coastguard Worker 	int masterfd;		/* master pty fd */
269*49cdfc7eSAndroid Build Coastguard Worker 	int slavefd;		/* slave pty fd */
270*49cdfc7eSAndroid Build Coastguard Worker 	int slavefd2;
271*49cdfc7eSAndroid Build Coastguard Worker 	int slavefd3;
272*49cdfc7eSAndroid Build Coastguard Worker 	char *slavename;
273*49cdfc7eSAndroid Build Coastguard Worker 
274*49cdfc7eSAndroid Build Coastguard Worker 	masterfd = SAFE_OPEN(NULL, MASTERCLONE, O_RDWR);
275*49cdfc7eSAndroid Build Coastguard Worker 
276*49cdfc7eSAndroid Build Coastguard Worker 	slavename = ptsname(masterfd);
277*49cdfc7eSAndroid Build Coastguard Worker 	if (slavename == NULL) {
278*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "ptsname() call failed");
279*49cdfc7eSAndroid Build Coastguard Worker 	}
280*49cdfc7eSAndroid Build Coastguard Worker 
281*49cdfc7eSAndroid Build Coastguard Worker 	if (grantpt(masterfd) != 0) {
282*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "grantpt() call failed");
283*49cdfc7eSAndroid Build Coastguard Worker 	}
284*49cdfc7eSAndroid Build Coastguard Worker 
285*49cdfc7eSAndroid Build Coastguard Worker 	if (unlockpt(masterfd) != 0) {
286*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "unlockpt() call failed");
287*49cdfc7eSAndroid Build Coastguard Worker 	}
288*49cdfc7eSAndroid Build Coastguard Worker 
289*49cdfc7eSAndroid Build Coastguard Worker 	slavefd = SAFE_OPEN(NULL, slavename, O_RDWR);
290*49cdfc7eSAndroid Build Coastguard Worker 
291*49cdfc7eSAndroid Build Coastguard Worker 	slavefd2 = open(slavename, O_RDWR);
292*49cdfc7eSAndroid Build Coastguard Worker 	if (slavefd < 0) {
293*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL | TERRNO, NULL, "Could not open %s (again)",
294*49cdfc7eSAndroid Build Coastguard Worker 			 slavename);
295*49cdfc7eSAndroid Build Coastguard Worker 	}
296*49cdfc7eSAndroid Build Coastguard Worker 
297*49cdfc7eSAndroid Build Coastguard Worker 	slavefd3 = open(slavename, O_RDWR);
298*49cdfc7eSAndroid Build Coastguard Worker 	if (slavefd < 0) {
299*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL | TERRNO, NULL, "Could not open %s (once more)",
300*49cdfc7eSAndroid Build Coastguard Worker 			 slavename);
301*49cdfc7eSAndroid Build Coastguard Worker 	}
302*49cdfc7eSAndroid Build Coastguard Worker 
303*49cdfc7eSAndroid Build Coastguard Worker 	/*
304*49cdfc7eSAndroid Build Coastguard Worker 	 * close pty fds.
305*49cdfc7eSAndroid Build Coastguard Worker 	 */
306*49cdfc7eSAndroid Build Coastguard Worker 	if (close(slavefd) != 0) {
307*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "close slave");
308*49cdfc7eSAndroid Build Coastguard Worker 	}
309*49cdfc7eSAndroid Build Coastguard Worker 
310*49cdfc7eSAndroid Build Coastguard Worker 	if (close(slavefd2) != 0) {
311*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "close slave again");
312*49cdfc7eSAndroid Build Coastguard Worker 	}
313*49cdfc7eSAndroid Build Coastguard Worker 
314*49cdfc7eSAndroid Build Coastguard Worker 	if (close(slavefd3) != 0) {
315*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "close slave once more");
316*49cdfc7eSAndroid Build Coastguard Worker 	}
317*49cdfc7eSAndroid Build Coastguard Worker 
318*49cdfc7eSAndroid Build Coastguard Worker 	if (close(masterfd) != 0) {
319*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL, "close master");
320*49cdfc7eSAndroid Build Coastguard Worker 	}
321*49cdfc7eSAndroid Build Coastguard Worker 	tst_resm(TPASS, "test4");
322*49cdfc7eSAndroid Build Coastguard Worker }
323*49cdfc7eSAndroid Build Coastguard Worker 
324*49cdfc7eSAndroid Build Coastguard Worker /*
325*49cdfc7eSAndroid Build Coastguard Worker  * test opening/closing lots of ptys in parallel.  We may run out
326*49cdfc7eSAndroid Build Coastguard Worker  * of ptys for this test depending on how the system is configured,
327*49cdfc7eSAndroid Build Coastguard Worker  * but that's not a fatal error.
328*49cdfc7eSAndroid Build Coastguard Worker  */
test5(void)329*49cdfc7eSAndroid Build Coastguard Worker static void test5(void)
330*49cdfc7eSAndroid Build Coastguard Worker {
331*49cdfc7eSAndroid Build Coastguard Worker 	int masterfd;		/* master pty fd */
332*49cdfc7eSAndroid Build Coastguard Worker 	char *slavename;
333*49cdfc7eSAndroid Build Coastguard Worker 	int status;
334*49cdfc7eSAndroid Build Coastguard Worker 	int i;
335*49cdfc7eSAndroid Build Coastguard Worker 
336*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < NUMPROCS; ++i) {
337*49cdfc7eSAndroid Build Coastguard Worker 		switch (fork()) {
338*49cdfc7eSAndroid Build Coastguard Worker 		case -1:
339*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TBROK, NULL, "fork()");
340*49cdfc7eSAndroid Build Coastguard Worker 			break;
341*49cdfc7eSAndroid Build Coastguard Worker 		case 0:
342*49cdfc7eSAndroid Build Coastguard Worker 			masterfd = open(MASTERCLONE, O_RDWR);
343*49cdfc7eSAndroid Build Coastguard Worker 			if (masterfd < 0) {
344*49cdfc7eSAndroid Build Coastguard Worker 				printf("proc %d: opening %s failed: %s",
345*49cdfc7eSAndroid Build Coastguard Worker 				       i, MASTERCLONE, strerror(errno));
346*49cdfc7eSAndroid Build Coastguard Worker 				exit(1);
347*49cdfc7eSAndroid Build Coastguard Worker 			}
348*49cdfc7eSAndroid Build Coastguard Worker 			if (grantpt(masterfd) != 0) {
349*49cdfc7eSAndroid Build Coastguard Worker 				printf("proc %d: grantpt() call failed: %s",
350*49cdfc7eSAndroid Build Coastguard Worker 				       i, strerror(errno));
351*49cdfc7eSAndroid Build Coastguard Worker 				exit(1);
352*49cdfc7eSAndroid Build Coastguard Worker 			}
353*49cdfc7eSAndroid Build Coastguard Worker 			slavename = ptsname(masterfd);
354*49cdfc7eSAndroid Build Coastguard Worker 			if (slavename == NULL) {
355*49cdfc7eSAndroid Build Coastguard Worker 				printf("proc %d: ptsname() call failed: %s",
356*49cdfc7eSAndroid Build Coastguard Worker 				       i, strerror(errno));
357*49cdfc7eSAndroid Build Coastguard Worker 				exit(1);
358*49cdfc7eSAndroid Build Coastguard Worker 			}
359*49cdfc7eSAndroid Build Coastguard Worker 			sleep(10);
360*49cdfc7eSAndroid Build Coastguard Worker 			if (close(masterfd) != 0) {
361*49cdfc7eSAndroid Build Coastguard Worker 				printf("proc %d: close failed: %s",
362*49cdfc7eSAndroid Build Coastguard Worker 				       i, strerror(errno));
363*49cdfc7eSAndroid Build Coastguard Worker 				exit(1);
364*49cdfc7eSAndroid Build Coastguard Worker 			}
365*49cdfc7eSAndroid Build Coastguard Worker 			exit(0);
366*49cdfc7eSAndroid Build Coastguard Worker 		default:
367*49cdfc7eSAndroid Build Coastguard Worker 			break;
368*49cdfc7eSAndroid Build Coastguard Worker 		}
369*49cdfc7eSAndroid Build Coastguard Worker 	}
370*49cdfc7eSAndroid Build Coastguard Worker 	while (wait(&status) > 0) {
371*49cdfc7eSAndroid Build Coastguard Worker 		if (status) {
372*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TFAIL, NULL,
373*49cdfc7eSAndroid Build Coastguard Worker 				 "child exited with non-zero status %d",
374*49cdfc7eSAndroid Build Coastguard Worker 				 status);
375*49cdfc7eSAndroid Build Coastguard Worker 		}
376*49cdfc7eSAndroid Build Coastguard Worker 	}
377*49cdfc7eSAndroid Build Coastguard Worker 	tst_resm(TPASS, "test5");
378*49cdfc7eSAndroid Build Coastguard Worker }
379*49cdfc7eSAndroid Build Coastguard Worker 
380*49cdfc7eSAndroid Build Coastguard Worker /*
381*49cdfc7eSAndroid Build Coastguard Worker  * main test driver
382*49cdfc7eSAndroid Build Coastguard Worker  */
main(void)383*49cdfc7eSAndroid Build Coastguard Worker int main(void)
384*49cdfc7eSAndroid Build Coastguard Worker {
385*49cdfc7eSAndroid Build Coastguard Worker 	test1();
386*49cdfc7eSAndroid Build Coastguard Worker 	test2();
387*49cdfc7eSAndroid Build Coastguard Worker 	test3();
388*49cdfc7eSAndroid Build Coastguard Worker 	test4();
389*49cdfc7eSAndroid Build Coastguard Worker 	test5();
390*49cdfc7eSAndroid Build Coastguard Worker 
391*49cdfc7eSAndroid Build Coastguard Worker 	/*
392*49cdfc7eSAndroid Build Coastguard Worker 	 * all done
393*49cdfc7eSAndroid Build Coastguard Worker 	 */
394*49cdfc7eSAndroid Build Coastguard Worker 	tst_exit();
395*49cdfc7eSAndroid Build Coastguard Worker }
396