]> git.saurik.com Git - apple/libc.git/blame_incremental - stdlib/FreeBSD/grantpt.c.patch
Libc-391.2.6.tar.gz
[apple/libc.git] / stdlib / FreeBSD / grantpt.c.patch
... / ...
CommitLineData
1--- grantpt.c.orig 2006-04-21 22:41:31.000000000 -0700
2+++ grantpt.c 2006-04-21 22:43:03.000000000 -0700
3@@ -54,18 +54,16 @@
4 #include <unistd.h>
5 #include "un-namespace.h"
6
7-#define PTM_MAJOR 6 /* pseudo tty master major */
8-#define PTS_MAJOR 5 /* pseudo tty slave major */
9 #define PTM_PREFIX "pty" /* pseudo tty master naming convention */
10 #define PTS_PREFIX "tty" /* pseudo tty slave naming convention */
11
12 /*
13 * The following are range values for pseudo TTY devices. Pseudo TTYs have a
14- * name of /dev/[pt]ty[p-sP-S][0-9a-v], yielding 256 combinations per major.
15+ * name of /dev/[pt]ty[p-w][0-9a-f], yielding 128 combinations per major.
16 */
17-#define PT_MAX 256
18-#define PT_DEV1 "pqrsPQRS"
19-#define PT_DEV2 "0123456789abcdefghijklmnopqrstuv"
20+#define PT_MAX 128
21+#define PT_DEV1 "pqrstuvw"
22+#define PT_DEV2 "0123456789abcdef"
23
24 /*
25 * grantpt(3) support utility.
26@@ -73,11 +71,32 @@
27 #define _PATH_PTCHOWN "/usr/libexec/pt_chown"
28
29 /*
30+ * On Mac OS X, the major device number may not be the same between reboots.
31+ * So we need to determine the major device number the first time.
32+ */
33+#define _PATH_A_PTY (_PATH_DEV PTM_PREFIX "p0")
34+
35+static int _ptm_major = -1;
36+
37+static int
38+_init_major(void)
39+{
40+ struct stat st;
41+
42+ if (_ptm_major >= 0)
43+ return _ptm_major;
44+ if (stat(_PATH_A_PTY, &st) < 0)
45+ return -1; /* should never happen */
46+ _ptm_major = major(st.st_rdev);
47+ return _ptm_major;
48+}
49+/*
50 * ISPTM(x) returns 0 for struct stat x if x is not a pty master.
51 * The bounds checking may be unnecessary but it does eliminate doubt.
52 */
53-#define ISPTM(x) (S_ISCHR((x).st_mode) && \
54- major((x).st_rdev) == PTM_MAJOR && \
55+#define ISPTM(x) (_init_major() >= 0 && \
56+ S_ISCHR((x).st_mode) && \
57+ major((x).st_rdev) == _ptm_major && \
58 minor((x).st_rdev) >= 0 && \
59 minor((x).st_rdev) < PT_MAX)
60
61@@ -100,50 +119,53 @@
62 serrno = errno;
63
64 if ((slave = ptsname(fildes)) != NULL) {
65- /*
66- * Block SIGCHLD.
67- */
68- (void)sigemptyset(&nblock);
69- (void)sigaddset(&nblock, SIGCHLD);
70- (void)_sigprocmask(SIG_BLOCK, &nblock, &oblock);
71-
72- switch (pid = fork()) {
73- case -1:
74- break;
75- case 0: /* child */
76+ /* 4430299: if we are root, we don't need to fork/exec */
77+ if (geteuid() != 0) {
78 /*
79- * pt_chown expects the master pseudo TTY to be its
80- * standard input.
81+ * Block SIGCHLD.
82 */
83- (void)_dup2(fildes, STDIN_FILENO);
84- (void)_sigprocmask(SIG_SETMASK, &oblock, NULL);
85- execl(_PATH_PTCHOWN, _PATH_PTCHOWN, (char *)NULL);
86- _exit(EX_UNAVAILABLE);
87- /* NOTREACHED */
88- default: /* parent */
89+ (void)sigemptyset(&nblock);
90+ (void)sigaddset(&nblock, SIGCHLD);
91+ (void)_sigprocmask(SIG_BLOCK, &nblock, &oblock);
92+
93+ switch (pid = fork()) {
94+ case -1:
95+ break;
96+ case 0: /* child */
97+ /*
98+ * pt_chown expects the master pseudo TTY to be its
99+ * standard input.
100+ */
101+ (void)_dup2(fildes, STDIN_FILENO);
102+ (void)_sigprocmask(SIG_SETMASK, &oblock, NULL);
103+ execl(_PATH_PTCHOWN, _PATH_PTCHOWN, (char *)NULL);
104+ _exit(EX_UNAVAILABLE);
105+ /* NOTREACHED */
106+ default: /* parent */
107+ /*
108+ * Just wait for the process. Error checking is
109+ * done below.
110+ */
111+ while ((spid = _waitpid(pid, &status, 0)) == -1 &&
112+ (errno == EINTR))
113+ ;
114+ if (spid != -1 && WIFEXITED(status) &&
115+ WEXITSTATUS(status) == EX_OK)
116+ retval = 0;
117+ else
118+ errno = EACCES;
119+ break;
120+ }
121+
122 /*
123- * Just wait for the process. Error checking is
124- * done below.
125+ * Restore process's signal mask.
126 */
127- while ((spid = _waitpid(pid, &status, 0)) == -1 &&
128- (errno == EINTR))
129- ;
130- if (spid != -1 && WIFEXITED(status) &&
131- WEXITSTATUS(status) == EX_OK)
132- retval = 0;
133- else
134- errno = EACCES;
135- break;
136+ (void)_sigprocmask(SIG_SETMASK, &oblock, NULL);
137 }
138
139- /*
140- * Restore process's signal mask.
141- */
142- (void)_sigprocmask(SIG_SETMASK, &oblock, NULL);
143-
144 if (retval) {
145 /*
146- * pt_chown failed. Try to manually change the
147+ * pt_chown failed (or we're root). Try to manually change the
148 * permissions for the slave.
149 */
150 gid = (grp = getgrnam("tty")) ? grp->gr_gid : -1;
151@@ -227,8 +249,8 @@
152 errno = EINVAL;
153 else {
154 (void)sprintf(slave, _PATH_DEV PTS_PREFIX "%c%c",
155- PT_DEV1[minor(sbuf.st_rdev) / 32],
156- PT_DEV2[minor(sbuf.st_rdev) % 32]);
157+ PT_DEV1[minor(sbuf.st_rdev) / 16],
158+ PT_DEV2[minor(sbuf.st_rdev) % 16]);
159 retval = slave;
160 }
161 }