|
| 1 | +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ |
| 2 | +│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│ |
| 3 | +╚──────────────────────────────────────────────────────────────────────────────╝ |
| 4 | +│ │ |
| 5 | +│ Musl Libc │ |
| 6 | +│ Copyright © 2005-2014 Rich Felker, et al. │ |
| 7 | +│ │ |
| 8 | +│ Permission is hereby granted, free of charge, to any person obtaining │ |
| 9 | +│ a copy of this software and associated documentation files (the │ |
| 10 | +│ "Software"), to deal in the Software without restriction, including │ |
| 11 | +│ without limitation the rights to use, copy, modify, merge, publish, │ |
| 12 | +│ distribute, sublicense, and/or sell copies of the Software, and to │ |
| 13 | +│ permit persons to whom the Software is furnished to do so, subject to │ |
| 14 | +│ the following conditions: │ |
| 15 | +│ │ |
| 16 | +│ The above copyright notice and this permission notice shall be │ |
| 17 | +│ included in all copies or substantial portions of the Software. │ |
| 18 | +│ │ |
| 19 | +│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │ |
| 20 | +│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │ |
| 21 | +│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │ |
| 22 | +│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │ |
| 23 | +│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │ |
| 24 | +│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │ |
| 25 | +│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ |
| 26 | +│ │ |
| 27 | +╚─────────────────────────────────────────────────────────────────────────────*/ |
| 28 | +#include "libc/calls/weirdtypes.h" |
| 29 | +#include "libc/calls/struct/sigset.h" |
| 30 | +#include "libc/sysv/consts/sig.h" |
| 31 | +#include "libc/calls/struct/sigset.h" |
| 32 | +#include "libc/thread/thread.h" |
| 33 | +#include "libc/calls/calls.h" |
| 34 | +#include "libc/sysv/consts/o.h" |
| 35 | +#include "libc/runtime/runtime.h" |
| 36 | +#include "libc/errno.h" |
| 37 | +#include "libc/calls/termios.h" |
| 38 | + |
| 39 | +asm(".ident\t\"\\n\\n\ |
| 40 | +Musl libc (MIT License)\\n\ |
| 41 | +Copyright 2005-2014 Rich Felker, et. al.\""); |
| 42 | +asm(".include \"libc/disclaimer.inc\""); |
| 43 | + |
| 44 | +int forkpty(int *pm, char *name, const struct termios *tio, const struct winsize *ws) |
| 45 | +{ |
| 46 | + int m, s, ec=0, p[2], cs; |
| 47 | + pid_t pid=-1; |
| 48 | + sigset_t set, oldset; |
| 49 | + |
| 50 | + if (openpty(&m, &s, name, tio, ws) < 0) return -1; |
| 51 | + |
| 52 | + sigfillset(&set); |
| 53 | + pthread_sigmask(SIG_BLOCK, &set, &oldset); |
| 54 | + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); |
| 55 | + |
| 56 | + if (pipe2(p, O_CLOEXEC)) { |
| 57 | + close(s); |
| 58 | + goto out; |
| 59 | + } |
| 60 | + |
| 61 | + pid = fork(); |
| 62 | + if (!pid) { |
| 63 | + close(m); |
| 64 | + close(p[0]); |
| 65 | + if (login_tty(s)) { |
| 66 | + write(p[1], &errno, sizeof errno); |
| 67 | + _exit(127); |
| 68 | + } |
| 69 | + close(p[1]); |
| 70 | + pthread_setcancelstate(cs, 0); |
| 71 | + pthread_sigmask(SIG_SETMASK, &oldset, 0); |
| 72 | + return 0; |
| 73 | + } |
| 74 | + close(s); |
| 75 | + close(p[1]); |
| 76 | + if (read(p[0], &ec, sizeof ec) > 0) { |
| 77 | + int status; |
| 78 | + waitpid(pid, &status, 0); |
| 79 | + pid = -1; |
| 80 | + errno = ec; |
| 81 | + } |
| 82 | + close(p[0]); |
| 83 | + |
| 84 | +out: |
| 85 | + if (pid > 0) *pm = m; |
| 86 | + else close(m); |
| 87 | + |
| 88 | + pthread_setcancelstate(cs, 0); |
| 89 | + pthread_sigmask(SIG_SETMASK, &oldset, 0); |
| 90 | + |
| 91 | + return pid; |
| 92 | +} |
0 commit comments