X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fmisc%2Fforkpty.c;h=caf13adbf3f9a22aeee9d5cff4d5fe97432fb282;hb=4bd22b8f3e6ffa8f43ea73e7bb6276aafb5a7743;hp=2d1b0ae28e5f178f181a61fee214d5cd7a9a63f4;hpb=4921ce08673d14e53b3931b8536238d944a2c1ce;p=musl diff --git a/src/misc/forkpty.c b/src/misc/forkpty.c index 2d1b0ae2..caf13adb 100644 --- a/src/misc/forkpty.c +++ b/src/misc/forkpty.c @@ -1,22 +1,57 @@ #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; - pid_t pid; + 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; + } - if (openpty(m, &s, name, tio, ws) < 0) return -1; pid = fork(); if (!pid) { - close(*m); - dup2(s, 0); - dup2(s, 1); - dup2(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; } 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; }