1 /* vi: set sw=4 ts=4: */
2 /*
3  * Mini getpty implementation for busybox
4  * Bjorn Wesen, Axis Communications AB (bjornw@axis.com)
5  *
6  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
7  */
8 #include "libbb.h"
9 
10 #define DEBUG 0
11 
xgetpty(char * line)12 int FAST_FUNC xgetpty(char *line)
13 {
14 	int p;
15 
16 #if ENABLE_FEATURE_DEVPTS
17 	p = open("/dev/ptmx", O_RDWR);
18 	if (p >= 0) {
19 		grantpt(p); /* chmod+chown corresponding slave pty */
20 		unlockpt(p); /* (what does this do?) */
21 # ifndef HAVE_PTSNAME_R
22 		{
23 			const char *name;
24 			name = ptsname(p); /* find out the name of slave pty */
25 			if (!name) {
26 				bb_simple_perror_msg_and_die("ptsname error (is /dev/pts mounted?)");
27 			}
28 			safe_strncpy(line, name, GETPTY_BUFSIZE);
29 		}
30 # else
31 		/* find out the name of slave pty */
32 		if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) {
33 			bb_simple_perror_msg_and_die("ptsname error (is /dev/pts mounted?)");
34 		}
35 		line[GETPTY_BUFSIZE-1] = '\0';
36 # endif
37 		return p;
38 	}
39 #else
40 	struct stat stb;
41 	int i;
42 	int j;
43 
44 	strcpy(line, "/dev/ptyXX");
45 
46 	for (i = 0; i < 16; i++) {
47 		line[8] = "pqrstuvwxyzabcde"[i];
48 		line[9] = '0';
49 		if (stat(line, &stb) < 0) {
50 			continue;
51 		}
52 		for (j = 0; j < 16; j++) {
53 			line[9] = j < 10 ? j + '0' : j - 10 + 'a';
54 			if (DEBUG)
55 				fprintf(stderr, "Trying to open device: %s\n", line);
56 			p = open(line, O_RDWR | O_NOCTTY);
57 			if (p >= 0) {
58 				line[5] = 't';
59 				return p;
60 			}
61 		}
62 	}
63 #endif /* FEATURE_DEVPTS */
64 	bb_simple_error_msg_and_die("can't find free pty");
65 }
66