X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fmisc%2Fforkpty.c;h=caf13adbf3f9a22aeee9d5cff4d5fe97432fb282;hb=814aae20093879dec36df0302febbafae2a66778;hp=07f8d01eed66741e31ec3c83a07ab5d4306d2fd0;hpb=1227e418eafbbe55e74eee5d2b1e6e53a60102cd;p=oweals%2Fmusl.git diff --git a/src/misc/forkpty.c b/src/misc/forkpty.c index 07f8d01e..caf13adb 100644 --- a/src/misc/forkpty.c +++ b/src/misc/forkpty.c @@ -1,38 +1,57 @@ #include +#include #include -#include +#include #include +#include +#include -int forkpty(int *m, char *name, const struct termios *tio, const struct winsize *ws) +int forkpty(int *pm, char *name, const struct termios *tio, const struct winsize *ws) { - int s, t, i, istmp[3]={0}; - pid_t pid; - - if (openpty(m, &s, name, tio, ws) < 0) return -1; - - /* Ensure before forking that we don't exceed fd limit */ - for (i=0; i<3; i++) { - if (fcntl(i, F_GETFL) < 0) { - t = fcntl(s, F_DUPFD, i); - if (t<0) break; - else if (t!=i) close(t); - else istmp[i] = 1; - } + int m, s, ec=0, p[2], cs; + pid_t pid=-1; + sigset_t set, oldset; + + if (openpty(&m, &s, name, tio, ws) < 0) return -1; + + sigfillset(&set); + pthread_sigmask(SIG_BLOCK, &set, &oldset); + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); + + if (pipe2(p, O_CLOEXEC)) { + close(s); + goto out; } - pid = i==3 ? fork() : -1; + + pid = fork(); if (!pid) { - close(*m); - setsid(); - ioctl(s, TIOCSCTTY, (char *)0); - dup2(s, 0); - dup2(s, 1); - dup2(s, 2); - if (s>2) close(s); + close(m); + close(p[0]); + if (login_tty(s)) { + write(p[1], &errno, sizeof errno); + _exit(127); + } + close(p[1]); + pthread_setcancelstate(cs, 0); + pthread_sigmask(SIG_SETMASK, &oldset, 0); return 0; } - for (i=0; i<3; i++) - if (istmp[i]) close(i); close(s); - if (pid < 0) close(*m); + close(p[1]); + if (read(p[0], &ec, sizeof ec) > 0) { + int status; + waitpid(pid, &status, 0); + pid = -1; + errno = ec; + } + close(p[0]); + +out: + if (pid > 0) *pm = m; + else close(m); + + pthread_setcancelstate(cs, 0); + pthread_sigmask(SIG_SETMASK, &oldset, 0); + return pid; }