| 789 | |
| 790 | #ifdef PTS_EXTERNAL |
| 791 | int |
| 792 | pts_alloc_external(int fflags, struct thread *td, struct file *fp, |
| 793 | struct cdev *dev, const char *name) |
| 794 | { |
| 795 | int ok, error; |
| 796 | struct tty *tp; |
| 797 | struct pts_softc *psc; |
| 798 | struct proc *p = td->td_proc; |
| 799 | struct ucred *cred = td->td_ucred; |
| 800 | |
| 801 | /* Resource limiting. */ |
| 802 | PROC_LOCK(p); |
| 803 | error = racct_add(p, RACCT_NPTS, 1); |
| 804 | if (error != 0) { |
| 805 | PROC_UNLOCK(p); |
| 806 | return (EAGAIN); |
| 807 | } |
| 808 | ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_NPTS)); |
| 809 | if (!ok) { |
| 810 | racct_sub(p, RACCT_NPTS, 1); |
| 811 | PROC_UNLOCK(p); |
| 812 | return (EAGAIN); |
| 813 | } |
| 814 | PROC_UNLOCK(p); |
| 815 | |
| 816 | /* Allocate TTY and softc. */ |
| 817 | psc = malloc(sizeof(struct pts_softc), M_PTS, M_WAITOK|M_ZERO); |
| 818 | cv_init(&psc->pts_inwait, "ptsin"); |
| 819 | cv_init(&psc->pts_outwait, "ptsout"); |
| 820 | |
| 821 | psc->pts_unit = -1; |
| 822 | psc->pts_cdev = dev; |
| 823 | psc->pts_cred = crhold(cred); |
| 824 | |
| 825 | tp = tty_alloc(&pts_class, psc); |
| 826 | knlist_init_mtx(&psc->pts_inpoll.si_note, tp->t_mtx); |
| 827 | knlist_init_mtx(&psc->pts_outpoll.si_note, tp->t_mtx); |
| 828 | |
| 829 | /* Expose the slave device as well. */ |
| 830 | tty_makedev(tp, td->td_ucred, "%s", name); |
| 831 | |
| 832 | finit(fp, fflags, DTYPE_PTS, tp, &ptsdev_ops); |
| 833 | |
| 834 | return (0); |
| 835 | } |
| 836 | #endif /* PTS_EXTERNAL */ |
| 837 | |
| 838 | int |
nothing calls this directly
no test coverage detected