Remove test/dsched*. This doesn't build anymore after 3573cf7bf66147.
[dragonfly.git] / sys / kern / tty_pty.c
1 /*
2  * (MPSAFE)
3  *
4  * Copyright (c) 1982, 1986, 1989, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  *      @(#)tty_pty.c   8.4 (Berkeley) 2/20/95
32  * $FreeBSD: src/sys/kern/tty_pty.c,v 1.74.2.4 2002/02/20 19:58:13 dillon Exp $
33  */
34
35 /*
36  * MPSAFE NOTE: 
37  * Most functions here could use a separate lock to deal with concurrent
38  * access to the 'pt's.
39  *
40  * Right now the tty_token must be held for all this.
41  */
42
43 /*
44  * Pseudo-teletype Driver
45  * (Actually two drivers, requiring two dev_ops structures)
46  */
47
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/proc.h>
51 #include <sys/priv.h>
52 #include <sys/tty.h>
53 #include <sys/conf.h>
54 #include <sys/fcntl.h>
55 #include <sys/kernel.h>
56 #include <sys/vnode.h>
57 #include <sys/signalvar.h>
58 #include <sys/malloc.h>
59 #include <sys/device.h>
60 #include <sys/thread2.h>
61 #include <sys/devfs.h>
62 #include <sys/stat.h>
63 #include <sys/sysctl.h>
64
65 MALLOC_DEFINE(M_PTY, "ptys", "pty data structures");
66
67 static void ptsstart (struct tty *tp);
68 static void ptsstop (struct tty *tp, int rw);
69 static void ptsunhold (struct tty *tp);
70 static void ptcwakeup (struct tty *tp, int flag);
71 static void ptyinit (int n);
72 static int  filt_ptcread (struct knote *kn, long hint);
73 static void filt_ptcrdetach (struct knote *kn);
74 static int  filt_ptcwrite (struct knote *kn, long hint);
75 static void filt_ptcwdetach (struct knote *kn);
76
77 static  d_open_t        ptsopen;
78 static  d_close_t       ptsclose;
79 static  d_read_t        ptsread;
80 static  d_write_t       ptswrite;
81 static  d_ioctl_t       ptyioctl;
82 static  d_open_t        ptcopen;
83 static  d_close_t       ptcclose;
84 static  d_read_t        ptcread;
85 static  d_write_t       ptcwrite;
86 static  d_kqfilter_t    ptckqfilter;
87
88 DEVFS_DEFINE_CLONE_BITMAP(pty);
89
90 static  d_clone_t       ptyclone;
91
92 static int      pty_debug_level = 0;
93
94 static struct dev_ops pts98_ops = {
95         { "pts98", 0, D_TTY | D_MPSAFE },
96         .d_open =       ptsopen,
97         .d_close =      ptsclose,
98         .d_read =       ptsread,
99         .d_write =      ptswrite,
100         .d_ioctl =      ptyioctl,
101         .d_kqfilter =   ttykqfilter,
102         .d_revoke =     ttyrevoke
103 };
104
105 static struct dev_ops ptc98_ops = {
106         { "ptc98", 0, D_TTY | D_MASTER | D_MPSAFE },
107         .d_open =       ptcopen,
108         .d_close =      ptcclose,
109         .d_read =       ptcread,
110         .d_write =      ptcwrite,
111         .d_ioctl =      ptyioctl,
112         .d_kqfilter =   ptckqfilter,
113         .d_revoke =     ttyrevoke
114 };
115
116 static struct dev_ops pts_ops = {
117         { "pts", 0, D_TTY | D_MPSAFE },
118         .d_open =       ptsopen,
119         .d_close =      ptsclose,
120         .d_read =       ptsread,
121         .d_write =      ptswrite,
122         .d_ioctl =      ptyioctl,
123         .d_kqfilter =   ttykqfilter,
124         .d_revoke =     ttyrevoke
125 };
126
127 #define CDEV_MAJOR_C    6
128 static struct dev_ops ptc_ops = {
129         { "ptc", 0, D_TTY | D_MASTER | D_MPSAFE },
130         .d_open =       ptcopen,
131         .d_close =      ptcclose,
132         .d_read =       ptcread,
133         .d_write =      ptcwrite,
134         .d_ioctl =      ptyioctl,
135         .d_kqfilter =   ptckqfilter,
136         .d_revoke =     ttyrevoke
137 };
138
139 #define BUFSIZ 100              /* Chunk size iomoved to/from user */
140
141 struct  pt_ioctl {
142         int     pt_flags;
143         int     pt_refs;        /* Structural references interlock S/MOPEN */
144         int     pt_uminor;
145         struct  kqinfo pt_kqr, pt_kqw;
146         u_char  pt_send;
147         u_char  pt_ucntl;
148         struct tty pt_tty;
149         cdev_t  devs, devc;
150         struct  prison *pt_prison;
151 };
152
153 /*
154  * pt_flags ptc state
155  */
156 #define PF_PKT          0x0008          /* packet mode */
157 #define PF_STOPPED      0x0010          /* user told stopped */
158 #define PF_REMOTE       0x0020          /* remote and flow controlled input */
159 #define PF_NOSTOP       0x0040
160 #define PF_UCNTL        0x0080          /* user control mode */
161
162 #define PF_PTCSTATEMASK 0x00FF
163
164 /*
165  * pt_flags open state.  Note that PF_SCLOSED is used to activate
166  * read EOF on the ptc so it is only set after the slave has been
167  * opened and then closed, and cleared again if the slave is opened
168  * again.
169  */
170 #define PF_UNIX98       0x0100
171 #define PF_SOPEN        0x0200
172 #define PF_MOPEN        0x0400
173 #define PF_SCLOSED      0x0800
174 #define PF_TERMINATED   0x8000
175
176 /*
177  * This function creates and initializes a pts/ptc pair
178  *
179  * pts == /dev/tty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv]
180  * ptc == /dev/pty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv]
181  *
182  * XXX: define and add mapping of upper minor bits to allow more 
183  *      than 256 ptys.
184  */
185 static void
186 ptyinit(int n)
187 {
188         cdev_t devs, devc;
189         char *names = "pqrsPQRS";
190         struct pt_ioctl *pt;
191
192         /* For now we only map the lower 8 bits of the minor */
193         if (n & ~0xff)
194                 return;
195
196         pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO);
197         pt->devs = devs = make_dev(&pts_ops, n,
198             0, 0, 0666, "tty%c%r", names[n / 32], n % 32);
199         pt->devc = devc = make_dev(&ptc_ops, n,
200             0, 0, 0666, "pty%c%r", names[n / 32], n % 32);
201
202         pt->pt_tty.t_dev = devs;
203         pt->pt_uminor = n;
204         devs->si_drv1 = devc->si_drv1 = pt;
205         devs->si_tty = devc->si_tty = &pt->pt_tty;
206         devs->si_flags |= SI_OVERRIDE;  /* uid, gid, perms from dev */
207         devc->si_flags |= SI_OVERRIDE;  /* uid, gid, perms from dev */
208         ttyregister(&pt->pt_tty);
209 }
210
211 static int
212 ptyclone(struct dev_clone_args *ap)
213 {
214         int unit;
215         struct pt_ioctl *pt;
216
217         /*
218          * Limit the number of unix98 pty (slave) devices to 1000, as
219          * the utmp(5) format only allows for 8 bytes for the tty,
220          * "pts/XXX".
221          * If this limit is reached, we don't clone and return error
222          * to devfs.
223          */
224         unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(pty), 1000);
225
226         if (unit < 0) {
227                 ap->a_dev = NULL;
228                 return 1;
229         }
230
231         pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO);
232
233         pt->devc = make_only_dev(&ptc98_ops, unit,
234                                  ap->a_cred->cr_ruid,
235                                  0, 0600, "ptm/%d", unit);
236         pt->devs = make_dev(&pts98_ops, unit,
237                             ap->a_cred->cr_ruid,
238                             GID_TTY, 0620, "pts/%d", unit);
239         ap->a_dev = pt->devc;
240
241         pt->devs->si_flags |= SI_OVERRIDE;      /* uid, gid, perms from dev */
242         pt->devc->si_flags |= SI_OVERRIDE;      /* uid, gid, perms from dev */
243
244         pt->pt_tty.t_dev = pt->devs;
245         pt->pt_flags |= PF_UNIX98;
246         pt->pt_uminor = unit;
247         pt->devs->si_drv1 = pt->devc->si_drv1 = pt;
248         pt->devs->si_tty = pt->devc->si_tty = &pt->pt_tty;
249
250         ttyregister(&pt->pt_tty);
251
252         return 0;
253 }
254
255 /*
256  * pti_hold() prevents the pti from being destroyed due to a termination
257  * while a pt*open() is blocked.
258  *
259  * This function returns non-zero if we cannot hold due to a termination
260  * interlock.
261  *
262  * NOTE: Must be called with tty_token held
263  */
264 static int
265 pti_hold(struct pt_ioctl *pti)
266 {
267         if (pti->pt_flags & PF_TERMINATED)
268                 return(ENXIO);
269         ++pti->pt_refs;
270         return(0);
271 }
272
273 /*
274  * pti_done() releases the reference and checks to see if both sides have
275  * been closed on a unix98 pty, allowing us to destroy the device and
276  * release resources.
277  *
278  * We do not release resources on non-unix98 ptys.  Those are left
279  * statically allocated.
280  */
281 static void
282 pti_done(struct pt_ioctl *pti)
283 {
284         lwkt_gettoken(&tty_token);
285         if (--pti->pt_refs == 0) {
286                 cdev_t dev;
287                 int uminor_no;
288
289                 /*
290                  * Only unix09 ptys are freed up
291                  */
292                 if ((pti->pt_flags & PF_UNIX98) == 0) {
293                         lwkt_reltoken(&tty_token);
294                         return;
295                 }
296
297                 /*
298                  * Interlock open attempts against termination by setting
299                  * PF_TERMINATED.  This allows us to block while cleaning
300                  * out the device infrastructure.
301                  *
302                  * Do not terminate the tty if it still has a session
303                  * association (t_refs).
304                  */
305                 if ((pti->pt_flags & (PF_SOPEN|PF_MOPEN)) == 0 &&
306                     pti->pt_tty.t_refs == 0) {
307                         pti->pt_flags |= PF_TERMINATED;
308                         uminor_no = pti->pt_uminor;
309
310                         if ((dev = pti->devs) != NULL) {
311                                 dev->si_drv1 = NULL;
312                                 pti->devs = NULL;
313                                 destroy_dev(dev);
314                         }
315                         if ((dev = pti->devc) != NULL) {
316                                 dev->si_drv1 = NULL;
317                                 pti->devc = NULL;
318                                 destroy_dev(dev);
319                         }
320                         ttyunregister(&pti->pt_tty);
321                         devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(pty),
322                                                uminor_no);
323                         kfree(pti, M_PTY);
324                 }
325         }
326         lwkt_reltoken(&tty_token);
327 }
328
329 /*ARGSUSED*/
330 static  int
331 ptsopen(struct dev_open_args *ap)
332 {
333         cdev_t dev = ap->a_head.a_dev;
334         struct tty *tp;
335         int error;
336         struct pt_ioctl *pti;
337
338         /*
339          * The pti will already be assigned by the clone code or
340          * pre-created if a non-unix 98 pty.  If si_drv1 is NULL
341          * we are somehow racing a unix98 termination.
342          */
343         if (dev->si_drv1 == NULL)
344                 return(ENXIO);
345         pti = dev->si_drv1;
346
347         lwkt_gettoken(&tty_token);
348         if (pti_hold(pti)) {
349                 lwkt_reltoken(&tty_token);
350                 return(ENXIO);
351         }
352
353         tp = dev->si_tty;
354
355         /*
356          * Reinit most of the tty state if it isn't open.  Handle
357          * exclusive access.
358          */
359         if ((tp->t_state & TS_ISOPEN) == 0) {
360                 ttychars(tp);           /* Set up default chars */
361                 tp->t_iflag = TTYDEF_IFLAG;
362                 tp->t_oflag = TTYDEF_OFLAG;
363                 tp->t_lflag = TTYDEF_LFLAG;
364                 tp->t_cflag = TTYDEF_CFLAG;
365                 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
366         } else if ((tp->t_state & TS_XCLUDE) &&
367                    priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) {
368                 pti_done(pti);
369                 lwkt_reltoken(&tty_token);
370                 return (EBUSY);
371         } else if (pti->pt_prison != ap->a_cred->cr_prison) {
372                 pti_done(pti);
373                 lwkt_reltoken(&tty_token);
374                 return (EBUSY);
375         }
376
377         /*
378          * If the ptc is already present this will connect us up.  It
379          * is unclear if this is actually needed.
380          *
381          * If neither side is open be sure to clear any left over
382          * ZOMBIE state before continuing.
383          */
384         if (tp->t_oproc)
385                 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
386         else if ((pti->pt_flags & PF_SOPEN) == 0)
387                 tp->t_state &= ~TS_ZOMBIE;
388
389         /*
390          * Wait for the carrier (ptc side)
391          */
392         while ((tp->t_state & TS_CARR_ON) == 0) {
393                 if (ap->a_oflags & FNONBLOCK)
394                         break;
395                 error = ttysleep(tp, TSA_CARR_ON(tp), PCATCH, "ptsopn", 0);
396                 if (error) {
397                         pti_done(pti);
398                         lwkt_reltoken(&tty_token);
399                         return (error);
400                 }
401         }
402
403         /*
404          * Mark the tty open and mark the slave side as being open.
405          */
406         error = (*linesw[tp->t_line].l_open)(dev, tp);
407
408         if (error == 0) {
409                 pti->pt_flags |= PF_SOPEN;
410                 pti->pt_flags &= ~PF_SCLOSED;
411                 ptcwakeup(tp, FREAD|FWRITE);
412         }
413         pti_done(pti);
414
415         lwkt_reltoken(&tty_token);
416         return (error);
417 }
418
419 static  int
420 ptsclose(struct dev_close_args *ap)
421 {
422         cdev_t dev = ap->a_head.a_dev;
423         struct tty *tp;
424         struct pt_ioctl *pti = dev->si_drv1;
425         int err;
426
427         lwkt_gettoken(&tty_token);
428         if (pti_hold(pti))
429                 panic("ptsclose on terminated pti");
430
431         /*
432          * Disconnect the slave side
433          */
434         tp = dev->si_tty;
435         err = (*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
436         ptsstop(tp, FREAD|FWRITE);
437         ttyclose(tp);                   /* clears t_state */
438
439         /*
440          * Mark the pts side closed and signal the ptc.  Do not mark the
441          * tty a zombie... that is, allow the tty to be re-opened as long
442          * as the ptc is still open.  The ptc will read() EOFs until the
443          * pts side is reopened or the ptc is closed.
444          *
445          * xterm() depends on this behavior as it will revoke() the pts
446          * and then reopen it after the (unnecessary old code) chmod.
447          */
448         pti->pt_flags &= ~PF_SOPEN;
449         pti->pt_flags |= PF_SCLOSED;
450         if (tp->t_oproc)
451                 ptcwakeup(tp, FREAD);
452         pti_done(pti);
453         lwkt_reltoken(&tty_token);
454         return (err);
455 }
456
457 static  int
458 ptsread(struct dev_read_args *ap)
459 {
460         cdev_t dev = ap->a_head.a_dev;
461         struct proc *p = curproc;
462         struct tty *tp = dev->si_tty;
463         struct pt_ioctl *pti = dev->si_drv1;
464         struct lwp *lp;
465
466         int error = 0;
467
468         lp = curthread->td_lwp;
469
470         lwkt_gettoken(&tty_token);
471 again:
472         if (pti->pt_flags & PF_REMOTE) {
473                 while (isbackground(p, tp)) {
474                         if (SIGISMEMBER(p->p_sigignore, SIGTTIN) ||
475                             SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) ||
476                             p->p_pgrp->pg_jobc == 0 ||
477                             (p->p_flags & P_PPWAIT)) {
478                                 lwkt_reltoken(&tty_token);
479                                 return (EIO);
480                         }
481                         pgsignal(p->p_pgrp, SIGTTIN, 1);
482                         error = ttysleep(tp, &lbolt, PCATCH, "ptsbg", 0);
483                         if (error) {
484                                 lwkt_reltoken(&tty_token);
485                                 return (error);
486                         }
487                 }
488                 if (tp->t_canq.c_cc == 0) {
489                         if (ap->a_ioflag & IO_NDELAY) {
490                                 lwkt_reltoken(&tty_token);
491                                 return (EWOULDBLOCK);
492                         }
493                         error = ttysleep(tp, TSA_PTS_READ(tp), PCATCH,
494                                          "ptsin", 0);
495                         if (error) {
496                                 lwkt_reltoken(&tty_token);
497                                 return (error);
498                         }
499                         goto again;
500                 }
501                 while (tp->t_canq.c_cc > 1 && ap->a_uio->uio_resid > 0)
502                         if (ureadc(clist_getc(&tp->t_canq), ap->a_uio) < 0) {
503                                 error = EFAULT;
504                                 break;
505                         }
506                 if (tp->t_canq.c_cc == 1)
507                         clist_getc(&tp->t_canq);
508                 if (tp->t_canq.c_cc) {
509                         lwkt_reltoken(&tty_token);
510                         return (error);
511                 }
512         } else
513                 if (tp->t_oproc)
514                         error = (*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag);
515         ptcwakeup(tp, FWRITE);
516         lwkt_reltoken(&tty_token);
517         return (error);
518 }
519
520 /*
521  * Write to pseudo-tty.
522  * Wakeups of controlling tty will happen
523  * indirectly, when tty driver calls ptsstart.
524  */
525 static  int
526 ptswrite(struct dev_write_args *ap)
527 {
528         cdev_t dev = ap->a_head.a_dev;
529         struct tty *tp;
530         int ret;
531
532         lwkt_gettoken(&tty_token);
533         tp = dev->si_tty;
534         if (tp->t_oproc == NULL) {
535                 lwkt_reltoken(&tty_token);
536                 return (EIO);
537         }
538         ret = ((*linesw[tp->t_line].l_write)(tp, ap->a_uio, ap->a_ioflag));
539         lwkt_reltoken(&tty_token);
540         return ret;
541 }
542
543 /*
544  * Start output on pseudo-tty.
545  * Wake up process selecting or sleeping for input from controlling tty.
546  */
547 static void
548 ptsstart(struct tty *tp)
549 {
550         lwkt_gettoken(&tty_token);
551         struct pt_ioctl *pti = tp->t_dev->si_drv1;
552
553         if (tp->t_state & TS_TTSTOP) {
554                 lwkt_reltoken(&tty_token);
555                 return;
556         }
557         if (pti) {
558                 if (pti->pt_flags & PF_STOPPED) {
559                         pti->pt_flags &= ~PF_STOPPED;
560                         pti->pt_send = TIOCPKT_START;
561                 }
562         }
563         ptcwakeup(tp, FREAD);
564         lwkt_reltoken(&tty_token);
565 }
566
567 /*
568  * NOTE: Must be called with tty_token held
569  */
570 static void
571 ptcwakeup(struct tty *tp, int flag)
572 {
573         ASSERT_LWKT_TOKEN_HELD(&tty_token);
574
575         if (flag & FREAD) {
576                 wakeup(TSA_PTC_READ(tp));
577                 KNOTE(&tp->t_rkq.ki_note, 0);
578         }
579         if (flag & FWRITE) {
580                 wakeup(TSA_PTC_WRITE(tp));
581                 KNOTE(&tp->t_wkq.ki_note, 0);
582         }
583 }
584
585 static  int
586 ptcopen(struct dev_open_args *ap)
587 {
588         cdev_t dev = ap->a_head.a_dev;
589         struct tty *tp;
590         struct pt_ioctl *pti;
591
592         /*
593          * The pti will already be assigned by the clone code or
594          * pre-created if a non-unix 98 pty.  If si_drv1 is NULL
595          * we are somehow racing a unix98 termination.
596          */
597         if (dev->si_drv1 == NULL)
598                 return(ENXIO);
599
600         lwkt_gettoken(&tty_token);
601         pti = dev->si_drv1;
602         if (pti_hold(pti)) {
603                 lwkt_reltoken(&tty_token);
604                 return(ENXIO);
605         }
606         if (pti->pt_prison && pti->pt_prison != ap->a_cred->cr_prison) {
607                 pti_done(pti);
608                 lwkt_reltoken(&tty_token);
609                 return(EBUSY);
610         }
611         tp = dev->si_tty;
612         if (tp->t_oproc) {
613                 pti_done(pti);
614                 lwkt_reltoken(&tty_token);
615                 return (EIO);
616         }
617
618         /*
619          * If the slave side is not yet open clear any left over zombie
620          * state before doing our modem control.
621          */
622         if ((pti->pt_flags & PF_SOPEN) == 0)
623                 tp->t_state &= ~TS_ZOMBIE;
624
625         tp->t_oproc = ptsstart;
626         tp->t_stop = ptsstop;
627         tp->t_unhold = ptsunhold;
628
629         /*
630          * Carrier on!
631          */
632         (void)(*linesw[tp->t_line].l_modem)(tp, 1);
633
634         tp->t_lflag &= ~EXTPROC;
635         pti->pt_prison = ap->a_cred->cr_prison;
636         pti->pt_flags &= ~PF_PTCSTATEMASK;
637         pti->pt_send = 0;
638         pti->pt_ucntl = 0;
639
640         pti->devs->si_uid = ap->a_cred->cr_uid;
641         pti->devs->si_gid = 0;
642         pti->devs->si_perms = 0600;
643         pti->devc->si_uid = ap->a_cred->cr_uid;
644         pti->devc->si_gid = 0;
645         pti->devc->si_perms = 0600;
646
647         /*
648          * Mark master side open.  This does not cause any events
649          * on the slave side.
650          */
651         pti->pt_flags |= PF_MOPEN;
652         pti_done(pti);
653
654         lwkt_reltoken(&tty_token);
655         return (0);
656 }
657
658 static  int
659 ptcclose(struct dev_close_args *ap)
660 {
661         cdev_t dev = ap->a_head.a_dev;
662         struct tty *tp;
663         struct pt_ioctl *pti = dev->si_drv1;
664
665         lwkt_gettoken(&tty_token);
666         if (pti_hold(pti))
667                 panic("ptcclose on terminated pti");
668
669         tp = dev->si_tty;
670         (void)(*linesw[tp->t_line].l_modem)(tp, 0);
671
672         /*
673          * Mark the master side closed.  If the slave is still open
674          * mark the tty ZOMBIE, preventing any new action until both
675          * sides have closed.
676          *
677          * NOTE: The ttyflush() will wake up the slave once we've
678          *       set appropriate flags.  The ZOMBIE flag will be
679          *       cleared when the slave side is closed.
680          */
681         pti->pt_flags &= ~PF_MOPEN;
682         if (pti->pt_flags & PF_SOPEN)
683                 tp->t_state |= TS_ZOMBIE;
684
685         /*
686          * Turn off the carrier and disconnect.  This will notify the slave
687          * side.
688          */
689         if (tp->t_state & TS_ISOPEN) {
690                 tp->t_state &= ~(TS_CARR_ON | TS_CONNECTED);
691                 ttyflush(tp, FREAD | FWRITE);
692         }
693         tp->t_oproc = NULL;             /* mark closed */
694
695         pti->pt_prison = NULL;
696         pti->devs->si_uid = 0;
697         pti->devs->si_gid = 0;
698         pti->devs->si_perms = 0666;
699         pti->devc->si_uid = 0;
700         pti->devc->si_gid = 0;
701         pti->devc->si_perms = 0666;
702
703         pti_done(pti);
704
705         lwkt_reltoken(&tty_token);
706         return (0);
707 }
708
709 static  int
710 ptcread(struct dev_read_args *ap)
711 {
712         cdev_t dev = ap->a_head.a_dev;
713         struct tty *tp = dev->si_tty;
714         struct pt_ioctl *pti = dev->si_drv1;
715         char buf[BUFSIZ];
716         int error = 0, cc;
717
718         lwkt_gettoken(&tty_token);
719         /*
720          * We want to block until the slave
721          * is open, and there's something to read;
722          * but if we lost the slave or we're NBIO,
723          * then return the appropriate error instead.
724          */
725         for (;;) {
726                 if (tp->t_state&TS_ISOPEN) {
727                         if ((pti->pt_flags & PF_PKT) && pti->pt_send) {
728                                 error = ureadc((int)pti->pt_send, ap->a_uio);
729                                 if (error) {
730                                         lwkt_reltoken(&tty_token);
731                                         return (error);
732                                 }
733                                 if (pti->pt_send & TIOCPKT_IOCTL) {
734                                         cc = (int)szmin(ap->a_uio->uio_resid,
735                                                         sizeof(tp->t_termios));
736                                         uiomove((caddr_t)&tp->t_termios, cc,
737                                                 ap->a_uio);
738                                 }
739                                 pti->pt_send = 0;
740                                 lwkt_reltoken(&tty_token);
741                                 return (0);
742                         }
743                         if ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl) {
744                                 error = ureadc((int)pti->pt_ucntl, ap->a_uio);
745                                 if (error) {
746                                         lwkt_reltoken(&tty_token);
747                                         return (error);
748                                 }
749                                 pti->pt_ucntl = 0;
750                                 lwkt_reltoken(&tty_token);
751                                 return (0);
752                         }
753                         if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
754                                 break;
755                 }
756                 if ((tp->t_state & TS_CONNECTED) == 0) {
757                         lwkt_reltoken(&tty_token);
758                         return (0);     /* EOF */
759                 }
760                 if (ap->a_ioflag & IO_NDELAY) {
761                         lwkt_reltoken(&tty_token);
762                         return (EWOULDBLOCK);
763                 }
764                 error = tsleep(TSA_PTC_READ(tp), PCATCH, "ptcin", 0);
765                 if (error) {
766                         lwkt_reltoken(&tty_token);
767                         return (error);
768                 }
769         }
770         if (pti->pt_flags & (PF_PKT|PF_UCNTL))
771                 error = ureadc(0, ap->a_uio);
772         while (ap->a_uio->uio_resid > 0 && error == 0) {
773                 cc = q_to_b(&tp->t_outq, buf,
774                             (int)szmin(ap->a_uio->uio_resid, BUFSIZ));
775                 if (cc <= 0)
776                         break;
777                 error = uiomove(buf, (size_t)cc, ap->a_uio);
778         }
779         ttwwakeup(tp);
780         lwkt_reltoken(&tty_token);
781         return (error);
782 }
783
784 static  void
785 ptsstop(struct tty *tp, int flush)
786 {
787         struct pt_ioctl *pti = tp->t_dev->si_drv1;
788         int flag;
789
790         lwkt_gettoken(&tty_token);
791         /* note: FLUSHREAD and FLUSHWRITE already ok */
792         if (pti) {
793                 if (flush == 0) {
794                         flush = TIOCPKT_STOP;
795                         pti->pt_flags |= PF_STOPPED;
796                 } else {
797                         pti->pt_flags &= ~PF_STOPPED;
798                 }
799                 pti->pt_send |= flush;
800                 /* change of perspective */
801         }
802         flag = 0;
803         if (flush & FREAD)
804                 flag |= FWRITE;
805         if (flush & FWRITE)
806                 flag |= FREAD;
807         ptcwakeup(tp, flag);
808
809         lwkt_reltoken(&tty_token);
810 }
811
812 /*
813  * ttyunhold() calls us instead of just decrementing tp->t_refs.  This
814  * is needed because a session can hold onto a pts (half closed state)
815  * even if there are no live file descriptors.  Without the callback
816  * we can't clean up.
817  */
818 static  void
819 ptsunhold(struct tty *tp)
820 {
821         struct pt_ioctl *pti = tp->t_dev->si_drv1;
822
823         lwkt_gettoken(&tty_token);
824         pti_hold(pti);
825         --tp->t_refs;
826         pti_done(pti);
827         lwkt_reltoken(&tty_token);
828 }
829
830 /*
831  * kqueue ops for pseudo-terminals.
832  */
833 static struct filterops ptcread_filtops =
834         { FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, filt_ptcrdetach, filt_ptcread };
835 static struct filterops ptcwrite_filtops =
836         { FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, filt_ptcwdetach, filt_ptcwrite };
837
838 static  int
839 ptckqfilter(struct dev_kqfilter_args *ap)
840 {
841         cdev_t dev = ap->a_head.a_dev;
842         struct knote *kn = ap->a_kn;
843         struct tty *tp = dev->si_tty;
844         struct klist *klist;
845
846         ap->a_result = 0;
847         switch (kn->kn_filter) {
848         case EVFILT_READ:
849                 klist = &tp->t_rkq.ki_note;
850                 kn->kn_fop = &ptcread_filtops;
851                 break;
852         case EVFILT_WRITE:
853                 klist = &tp->t_wkq.ki_note;
854                 kn->kn_fop = &ptcwrite_filtops;
855                 break;
856         default:
857                 ap->a_result = EOPNOTSUPP;
858                 return (0);
859         }
860
861         kn->kn_hook = (caddr_t)dev;
862         knote_insert(klist, kn);
863         return (0);
864 }
865
866 static int
867 filt_ptcread (struct knote *kn, long hint)
868 {
869         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
870         struct pt_ioctl *pti = ((cdev_t)kn->kn_hook)->si_drv1;
871
872         lwkt_gettoken(&tty_token);
873         if ((tp->t_state & TS_ZOMBIE) || (pti->pt_flags & PF_SCLOSED)) {
874                 lwkt_reltoken(&tty_token);
875                 kn->kn_flags |= (EV_EOF | EV_NODATA);
876                 return (1);
877         }
878
879         if ((tp->t_state & TS_ISOPEN) &&
880             ((tp->t_outq.c_cc && (tp->t_state & TS_TTSTOP) == 0) ||
881              ((pti->pt_flags & PF_PKT) && pti->pt_send) ||
882              ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))) {
883                 kn->kn_data = tp->t_outq.c_cc;
884                 lwkt_reltoken(&tty_token);
885                 return(1);
886         } else {
887                 lwkt_reltoken(&tty_token);
888                 return(0);
889         }
890 }
891
892 static int
893 filt_ptcwrite (struct knote *kn, long hint)
894 {
895         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
896         struct pt_ioctl *pti = ((cdev_t)kn->kn_hook)->si_drv1;
897
898         lwkt_gettoken(&tty_token);
899         if (tp->t_state & TS_ZOMBIE) {
900                 lwkt_reltoken(&tty_token);
901                 kn->kn_flags |= (EV_EOF | EV_NODATA);
902                 return (1);
903         }
904
905         if (tp->t_state & TS_ISOPEN &&
906             ((pti->pt_flags & PF_REMOTE) ?
907              (tp->t_canq.c_cc == 0) :
908              ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) ||
909               (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON))))) {
910                 kn->kn_data = tp->t_canq.c_cc + tp->t_rawq.c_cc;
911                 lwkt_reltoken(&tty_token);
912                 return(1);
913         } else {
914                 lwkt_reltoken(&tty_token);
915                 return(0);
916         }
917         /* NOTREACHED */
918 }
919
920 static void
921 filt_ptcrdetach (struct knote *kn)
922 {
923         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
924
925         knote_remove(&tp->t_rkq.ki_note, kn);
926 }
927
928 static void
929 filt_ptcwdetach (struct knote *kn)
930 {
931         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
932
933         knote_remove(&tp->t_wkq.ki_note, kn);
934 }
935
936 /*
937  * I/O ops
938  */
939 static  int
940 ptcwrite(struct dev_write_args *ap)
941 {
942         cdev_t dev = ap->a_head.a_dev;
943         struct tty *tp = dev->si_tty;
944         u_char *cp = NULL;
945         int cc = 0;
946         u_char locbuf[BUFSIZ];
947         int cnt = 0;
948         struct pt_ioctl *pti = dev->si_drv1;
949         int error = 0;
950
951         lwkt_gettoken(&tty_token);
952 again:
953         if ((tp->t_state&TS_ISOPEN) == 0)
954                 goto block;
955         if (pti->pt_flags & PF_REMOTE) {
956                 if (tp->t_canq.c_cc)
957                         goto block;
958                 while ((ap->a_uio->uio_resid > 0 || cc > 0) &&
959                        tp->t_canq.c_cc < TTYHOG - 1) {
960                         if (cc == 0) {
961                                 cc = (int)szmin(ap->a_uio->uio_resid, BUFSIZ);
962                                 cc = imin(cc, TTYHOG - 1 - tp->t_canq.c_cc);
963                                 cp = locbuf;
964                                 error = uiomove(cp, (size_t)cc, ap->a_uio);
965                                 if (error) {
966                                         lwkt_reltoken(&tty_token);
967                                         return (error);
968                                 }
969                                 /* check again for safety */
970                                 if ((tp->t_state & TS_ISOPEN) == 0) {
971                                         /* adjust as usual */
972                                         ap->a_uio->uio_resid += cc;
973                                         lwkt_reltoken(&tty_token);
974                                         return (EIO);
975                                 }
976                         }
977                         if (cc > 0) {
978                                 cc = b_to_q((char *)cp, cc, &tp->t_canq);
979                                 /*
980                                  * XXX we don't guarantee that the canq size
981                                  * is >= TTYHOG, so the above b_to_q() may
982                                  * leave some bytes uncopied.  However, space
983                                  * is guaranteed for the null terminator if
984                                  * we don't fail here since (TTYHOG - 1) is
985                                  * not a multiple of CBSIZE.
986                                  */
987                                 if (cc > 0)
988                                         break;
989                         }
990                 }
991                 /* adjust for data copied in but not written */
992                 ap->a_uio->uio_resid += cc;
993                 clist_putc(0, &tp->t_canq);
994                 ttwakeup(tp);
995                 wakeup(TSA_PTS_READ(tp));
996                 lwkt_reltoken(&tty_token);
997                 return (0);
998         }
999         while (ap->a_uio->uio_resid > 0 || cc > 0) {
1000                 if (cc == 0) {
1001                         cc = (int)szmin(ap->a_uio->uio_resid, BUFSIZ);
1002                         cp = locbuf;
1003                         error = uiomove(cp, (size_t)cc, ap->a_uio);
1004                         if (error) {
1005                                 lwkt_reltoken(&tty_token);
1006                                 return (error);
1007                         }
1008                         /* check again for safety */
1009                         if ((tp->t_state & TS_ISOPEN) == 0) {
1010                                 /* adjust for data copied in but not written */
1011                                 ap->a_uio->uio_resid += cc;
1012                                 lwkt_reltoken(&tty_token);
1013                                 return (EIO);
1014                         }
1015                 }
1016                 while (cc > 0) {
1017                         if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
1018                            (tp->t_canq.c_cc > 0 || !(tp->t_lflag&ICANON))) {
1019                                 wakeup(TSA_HUP_OR_INPUT(tp));
1020                                 goto block;
1021                         }
1022                         (*linesw[tp->t_line].l_rint)(*cp++, tp);
1023                         cnt++;
1024                         cc--;
1025                 }
1026                 cc = 0;
1027         }
1028         lwkt_reltoken(&tty_token);
1029         return (0);
1030 block:
1031         /*
1032          * Come here to wait for slave to open, for space
1033          * in outq, or space in rawq, or an empty canq.
1034          */
1035         if ((tp->t_state & TS_CONNECTED) == 0) {
1036                 /* adjust for data copied in but not written */
1037                 ap->a_uio->uio_resid += cc;
1038                 lwkt_reltoken(&tty_token);
1039                 return (EIO);
1040         }
1041         if (ap->a_ioflag & IO_NDELAY) {
1042                 /* adjust for data copied in but not written */
1043                 ap->a_uio->uio_resid += cc;
1044                 if (cnt == 0) {
1045                         lwkt_reltoken(&tty_token);
1046                         return (EWOULDBLOCK);
1047                 }
1048                 lwkt_reltoken(&tty_token);
1049                 return (0);
1050         }
1051         error = tsleep(TSA_PTC_WRITE(tp), PCATCH, "ptcout", 0);
1052         if (error) {
1053                 /* adjust for data copied in but not written */
1054                 ap->a_uio->uio_resid += cc;
1055                 lwkt_reltoken(&tty_token);
1056                 return (error);
1057         }
1058         goto again;
1059 }
1060
1061 /*ARGSUSED*/
1062 static  int
1063 ptyioctl(struct dev_ioctl_args *ap)
1064 {
1065         cdev_t dev = ap->a_head.a_dev;
1066         struct tty *tp = dev->si_tty;
1067         struct pt_ioctl *pti = dev->si_drv1;
1068         u_char *cc = tp->t_cc;
1069         int stop, error;
1070
1071         lwkt_gettoken(&tty_token);
1072         if (dev_dflags(dev) & D_MASTER) {
1073                 switch (ap->a_cmd) {
1074
1075                 case TIOCGPGRP:
1076                         /*
1077                          * We avoid calling ttioctl on the controller since,
1078                          * in that case, tp must be the controlling terminal.
1079                          */
1080                         *(int *)ap->a_data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
1081                         lwkt_reltoken(&tty_token);
1082                         return (0);
1083
1084                 case TIOCPKT:
1085                         if (*(int *)ap->a_data) {
1086                                 if (pti->pt_flags & PF_UCNTL) {
1087                                         lwkt_reltoken(&tty_token);
1088                                         return (EINVAL);
1089                                 }
1090                                 pti->pt_flags |= PF_PKT;
1091                         } else {
1092                                 pti->pt_flags &= ~PF_PKT;
1093                         }
1094                         lwkt_reltoken(&tty_token);
1095                         return (0);
1096
1097                 case TIOCUCNTL:
1098                         if (*(int *)ap->a_data) {
1099                                 if (pti->pt_flags & PF_PKT) {
1100                                         lwkt_reltoken(&tty_token);
1101                                         return (EINVAL);
1102                                 }
1103                                 pti->pt_flags |= PF_UCNTL;
1104                         } else {
1105                                 pti->pt_flags &= ~PF_UCNTL;
1106                         }
1107                         lwkt_reltoken(&tty_token);
1108                         return (0);
1109
1110                 case TIOCREMOTE:
1111                         if (*(int *)ap->a_data)
1112                                 pti->pt_flags |= PF_REMOTE;
1113                         else
1114                                 pti->pt_flags &= ~PF_REMOTE;
1115                         ttyflush(tp, FREAD|FWRITE);
1116                         lwkt_reltoken(&tty_token);
1117                         return (0);
1118
1119                 case TIOCISPTMASTER:
1120                         if ((pti->pt_flags & PF_UNIX98) &&
1121                             (pti->devc == dev)) {
1122                                 lwkt_reltoken(&tty_token);
1123                                 return (0);
1124                         } else {
1125                                 lwkt_reltoken(&tty_token);
1126                                 return (EINVAL);
1127                         }
1128                 }
1129
1130                 /*
1131                  * The rest of the ioctls shouldn't be called until 
1132                  * the slave is open.
1133                  */
1134                 if ((tp->t_state & TS_ISOPEN) == 0) {
1135                         lwkt_reltoken(&tty_token);
1136                         return (EAGAIN);
1137                 }
1138
1139                 switch (ap->a_cmd) {
1140                 case TIOCSETD:
1141                 case TIOCSETA:
1142                 case TIOCSETAW:
1143                 case TIOCSETAF:
1144                         /*
1145                          * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
1146                          * ttywflush(tp) will hang if there are characters in
1147                          * the outq.
1148                          */
1149                         ndflush(&tp->t_outq, tp->t_outq.c_cc);
1150                         break;
1151
1152                 case TIOCSIG:
1153                         if (*(unsigned int *)ap->a_data >= NSIG ||
1154                             *(unsigned int *)ap->a_data == 0) {
1155                                 lwkt_reltoken(&tty_token);
1156                                 return(EINVAL);
1157                         }
1158                         if ((tp->t_lflag&NOFLSH) == 0)
1159                                 ttyflush(tp, FREAD|FWRITE);
1160                         pgsignal(tp->t_pgrp, *(unsigned int *)ap->a_data, 1);
1161                         if ((*(unsigned int *)ap->a_data == SIGINFO) &&
1162                             ((tp->t_lflag&NOKERNINFO) == 0))
1163                                 ttyinfo(tp);
1164                         lwkt_reltoken(&tty_token);
1165                         return(0);
1166                 }
1167         }
1168         if (ap->a_cmd == TIOCEXT) {
1169                 /*
1170                  * When the EXTPROC bit is being toggled, we need
1171                  * to send an TIOCPKT_IOCTL if the packet driver
1172                  * is turned on.
1173                  */
1174                 if (*(int *)ap->a_data) {
1175                         if (pti->pt_flags & PF_PKT) {
1176                                 pti->pt_send |= TIOCPKT_IOCTL;
1177                                 ptcwakeup(tp, FREAD);
1178                         }
1179                         tp->t_lflag |= EXTPROC;
1180                 } else {
1181                         if ((tp->t_lflag & EXTPROC) &&
1182                             (pti->pt_flags & PF_PKT)) {
1183                                 pti->pt_send |= TIOCPKT_IOCTL;
1184                                 ptcwakeup(tp, FREAD);
1185                         }
1186                         tp->t_lflag &= ~EXTPROC;
1187                 }
1188                 lwkt_reltoken(&tty_token);
1189                 return(0);
1190         }
1191         error = (*linesw[tp->t_line].l_ioctl)(tp, ap->a_cmd, ap->a_data,
1192                                               ap->a_fflag, ap->a_cred);
1193         if (error == ENOIOCTL)
1194                  error = ttioctl(tp, ap->a_cmd, ap->a_data, ap->a_fflag);
1195         if (error == ENOIOCTL) {
1196                 if (pti->pt_flags & PF_UCNTL &&
1197                     (ap->a_cmd & ~0xff) == UIOCCMD(0)) {
1198                         if (ap->a_cmd & 0xff) {
1199                                 pti->pt_ucntl = (u_char)ap->a_cmd;
1200                                 ptcwakeup(tp, FREAD);
1201                         }
1202                         lwkt_reltoken(&tty_token);
1203                         return (0);
1204                 }
1205                 error = ENOTTY;
1206         }
1207         /*
1208          * If external processing and packet mode send ioctl packet.
1209          */
1210         if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
1211                 switch(ap->a_cmd) {
1212                 case TIOCSETA:
1213                 case TIOCSETAW:
1214                 case TIOCSETAF:
1215                         pti->pt_send |= TIOCPKT_IOCTL;
1216                         ptcwakeup(tp, FREAD);
1217                 default:
1218                         break;
1219                 }
1220         }
1221         stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
1222                 && CCEQ(cc[VSTART], CTRL('q'));
1223         if (pti->pt_flags & PF_NOSTOP) {
1224                 if (stop) {
1225                         pti->pt_send &= ~TIOCPKT_NOSTOP;
1226                         pti->pt_send |= TIOCPKT_DOSTOP;
1227                         pti->pt_flags &= ~PF_NOSTOP;
1228                         ptcwakeup(tp, FREAD);
1229                 }
1230         } else {
1231                 if (!stop) {
1232                         pti->pt_send &= ~TIOCPKT_DOSTOP;
1233                         pti->pt_send |= TIOCPKT_NOSTOP;
1234                         pti->pt_flags |= PF_NOSTOP;
1235                         ptcwakeup(tp, FREAD);
1236                 }
1237         }
1238         lwkt_reltoken(&tty_token);
1239         return (error);
1240 }
1241
1242
1243 static void ptc_drvinit (void *unused);
1244
1245 SYSCTL_INT(_kern, OID_AUTO, pty_debug, CTLFLAG_RW, &pty_debug_level,
1246                 0, "Change pty debug level");
1247
1248 static void
1249 ptc_drvinit(void *unused)
1250 {
1251         int i;
1252
1253         /*
1254          * Unix98 pty stuff.
1255          * Create the clonable base device.
1256          */
1257         make_autoclone_dev(&ptc_ops, &DEVFS_CLONE_BITMAP(pty), ptyclone,
1258             0, 0, 0666, "ptmx");
1259
1260         for (i = 0; i < 256; i++) {
1261                 ptyinit(i);
1262         }
1263 }
1264
1265 SYSINIT(ptcdev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE + CDEV_MAJOR_C, ptc_drvinit,
1266     NULL);