check for fd exhaustion in forkpty
[oweals/musl.git] / src / misc / forkpty.c
1 #include <pty.h>
2 #include <unistd.h>
3 #include <sys/ioctl.h>
4 #include <fcntl.h>
5
6 int forkpty(int *m, char *name, const struct termios *tio, const struct winsize *ws)
7 {
8         int s, t, i, istmp[3]={0};
9         pid_t pid;
10
11         if (openpty(m, &s, name, tio, ws) < 0) return -1;
12
13         /* Ensure before forking that we don't exceed fd limit */
14         for (i=0; i<3; i++) {
15                 if (fcntl(i, F_GETFL) < 0) {
16                         t = fcntl(s, F_DUPFD, i);
17                         if (t<0) break;
18                         else if (t!=i) close(t);
19                         else istmp[i] = 1;
20                 }
21         }
22         pid = i==3 ? fork() : -1;
23         if (!pid) {
24                 close(*m);
25                 setsid();
26                 ioctl(s, TIOCSCTTY, (char *)0);
27                 dup2(s, 0);
28                 dup2(s, 1);
29                 dup2(s, 2);
30                 if (s>2) close(s);
31                 return 0;
32         }
33         for (i=0; i<3; i++)
34                 if (istmp[i]) close(i);
35         close(s);
36         if (pid < 0) close(*m);
37         return pid;
38 }