X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fmisc%2Fforkpty.c;h=caf13adbf3f9a22aeee9d5cff4d5fe97432fb282;hb=2e5fff43dd7fc808197744c67cca7908ac19bb4f;hp=0bbf2de2746bba58d38b258428700320415706f8;hpb=10d7561db5d51231939fa0b42d17eaac2bff6938;p=musl diff --git a/src/misc/forkpty.c b/src/misc/forkpty.c index 0bbf2de2..caf13adb 100644 --- a/src/misc/forkpty.c +++ b/src/misc/forkpty.c @@ -1,25 +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; - 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); - 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; } 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; }