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