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