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