kernel - Fix telnet ttyp* allocation
[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         error = (*linesw[tp->t_line].l_open)(dev, tp);
402         if (error == 0)
403                 ptcwakeup(tp, FREAD|FWRITE);
404
405 #ifdef UNIX98_PTYS
406         /*
407          * Unix98 pty stuff.
408          * On open of the slave, we set the corresponding flag in the common
409          * struct.
410          */
411         ptydebug(1, "ptsopen=%s | unix98? %s\n", dev->si_name,
412             (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
413
414         if (error == 0 && (pti->pt_flags2 & PF_UNIX98)) {
415                 pti->pt_flags2 |= PF_SOPEN;
416         }
417 #endif
418         pti_done(pti);
419
420         lwkt_reltoken(&tty_token);
421         return (error);
422 }
423
424 static  int
425 ptsclose(struct dev_close_args *ap)
426 {
427         cdev_t dev = ap->a_head.a_dev;
428         struct tty *tp;
429         struct pt_ioctl *pti = dev->si_drv1;
430         int err;
431
432         lwkt_gettoken(&tty_token);
433         if (pti_hold(pti))
434                 panic("ptsclose on terminated pti");
435         tp = dev->si_tty;
436         err = (*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
437         ptsstop(tp, FREAD|FWRITE);
438         (void) ttyclose(tp); /* clears t_state */
439
440 #ifdef UNIX98_PTYS
441         /*
442          * Unix98 pty stuff.
443          * On close of the slave, we unset the corresponding flag, and if the master
444          * isn't open anymore, we destroy the slave and unset the unit.
445          */
446         ptydebug(1, "ptsclose=%s | unix98? %s\n", dev->si_name,
447             (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
448
449         if (pti->pt_flags2 & PF_UNIX98) {
450                 pti->pt_flags2 &= ~PF_SOPEN;
451                 KKASSERT((pti->pt_flags2 & PF_SOPEN) == 0);
452                 ptydebug(1, "master open? %s\n",
453                     (pti->pt_flags2 & PF_MOPEN)?"yes":"no");
454         }
455 #endif
456         pti_done(pti);
457         lwkt_reltoken(&tty_token);
458         return (err);
459 }
460
461 static  int
462 ptsread(struct dev_read_args *ap)
463 {
464         cdev_t dev = ap->a_head.a_dev;
465         struct proc *p = curproc;
466         struct tty *tp = dev->si_tty;
467         struct pt_ioctl *pti = dev->si_drv1;
468         struct lwp *lp;
469
470         int error = 0;
471
472         lp = curthread->td_lwp;
473
474         lwkt_gettoken(&tty_token);
475 again:
476         if (pti->pt_flags & PF_REMOTE) {
477                 while (isbackground(p, tp)) {
478                         if (SIGISMEMBER(p->p_sigignore, SIGTTIN) ||
479                             SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) ||
480                             p->p_pgrp->pg_jobc == 0 || p->p_flag & P_PPWAIT) {
481                                 lwkt_reltoken(&tty_token);
482                                 return (EIO);
483                         }
484                         pgsignal(p->p_pgrp, SIGTTIN, 1);
485                         error = ttysleep(tp, &lbolt, PCATCH, "ptsbg", 0);
486                         if (error) {
487                                 lwkt_reltoken(&tty_token);
488                                 return (error);
489                         }
490                 }
491                 if (tp->t_canq.c_cc == 0) {
492                         if (ap->a_ioflag & IO_NDELAY) {
493                                 lwkt_reltoken(&tty_token);
494                                 return (EWOULDBLOCK);
495                         }
496                         error = ttysleep(tp, TSA_PTS_READ(tp), PCATCH,
497                                          "ptsin", 0);
498                         if (error) {
499                                 lwkt_reltoken(&tty_token);
500                                 return (error);
501                         }
502                         goto again;
503                 }
504                 while (tp->t_canq.c_cc > 1 && ap->a_uio->uio_resid > 0)
505                         if (ureadc(clist_getc(&tp->t_canq), ap->a_uio) < 0) {
506                                 error = EFAULT;
507                                 break;
508                         }
509                 if (tp->t_canq.c_cc == 1)
510                         clist_getc(&tp->t_canq);
511                 if (tp->t_canq.c_cc) {
512                         lwkt_reltoken(&tty_token);
513                         return (error);
514                 }
515         } else
516                 if (tp->t_oproc)
517                         error = (*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag);
518         ptcwakeup(tp, FWRITE);
519         lwkt_reltoken(&tty_token);
520         return (error);
521 }
522
523 /*
524  * Write to pseudo-tty.
525  * Wakeups of controlling tty will happen
526  * indirectly, when tty driver calls ptsstart.
527  */
528 static  int
529 ptswrite(struct dev_write_args *ap)
530 {
531         cdev_t dev = ap->a_head.a_dev;
532         struct tty *tp;
533         int ret;
534
535         lwkt_gettoken(&tty_token);
536         tp = dev->si_tty;
537         if (tp->t_oproc == 0) {
538                 lwkt_reltoken(&tty_token);
539                 return (EIO);
540         }
541         ret = ((*linesw[tp->t_line].l_write)(tp, ap->a_uio, ap->a_ioflag));
542         lwkt_reltoken(&tty_token);
543         return ret;
544 }
545
546 /*
547  * Start output on pseudo-tty.
548  * Wake up process selecting or sleeping for input from controlling tty.
549  */
550 static void
551 ptsstart(struct tty *tp)
552 {
553         lwkt_gettoken(&tty_token);
554         struct pt_ioctl *pti = tp->t_dev->si_drv1;
555
556         if (tp->t_state & TS_TTSTOP)
557                 return;
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         tp->t_oproc = ptsstart;
619         tp->t_stop = ptsstop;
620         (void)(*linesw[tp->t_line].l_modem)(tp, 1);
621         tp->t_lflag &= ~EXTPROC;
622         pti->pt_prison = ap->a_cred->cr_prison;
623         pti->pt_flags = 0;
624         pti->pt_send = 0;
625         pti->pt_ucntl = 0;
626
627         pti->devs->si_uid = ap->a_cred->cr_uid;
628         pti->devs->si_gid = 0;
629         pti->devs->si_perms = 0600;
630         pti->devc->si_uid = ap->a_cred->cr_uid;
631         pti->devc->si_gid = 0;
632         pti->devc->si_perms = 0600;
633
634 #ifdef UNIX98_PTYS
635         /*
636          * Unix98 pty stuff.
637          * On open of the master, we set the corresponding flag in the common
638          * struct.
639          */
640         ptydebug(1, "ptcopen=%s (master) | unix98? %s\n", dev->si_name,
641             (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
642
643         if (pti->pt_flags2 & PF_UNIX98) {
644                 pti->pt_flags2 |= PF_MOPEN;
645         }
646 #endif
647         pti_done(pti);
648
649         lwkt_reltoken(&tty_token);
650         return (0);
651 }
652
653 static  int
654 ptcclose(struct dev_close_args *ap)
655 {
656         cdev_t dev = ap->a_head.a_dev;
657         struct tty *tp;
658         struct pt_ioctl *pti = dev->si_drv1;
659
660         lwkt_gettoken(&tty_token);
661         if (pti_hold(pti))
662                 panic("ptcclose on terminated pti");
663
664         tp = dev->si_tty;
665         (void)(*linesw[tp->t_line].l_modem)(tp, 0);
666
667         /*
668          * XXX MDMBUF makes no sense for ptys but would inhibit the above
669          * l_modem().  CLOCAL makes sense but isn't supported.   Special
670          * l_modem()s that ignore carrier drop make no sense for ptys but
671          * may be in use because other parts of the line discipline make
672          * sense for ptys.  Recover by doing everything that a normal
673          * ttymodem() would have done except for sending a SIGHUP.
674          */
675         if (tp->t_state & TS_ISOPEN) {
676                 tp->t_state &= ~(TS_CARR_ON | TS_CONNECTED);
677                 tp->t_state |= TS_ZOMBIE;
678                 ttyflush(tp, FREAD | FWRITE);
679         }
680         tp->t_oproc = 0;                /* mark closed */
681
682 #ifdef UNIX98_PTYS
683         /*
684          * Unix98 pty stuff.
685          * On close of the master, we unset the corresponding flag in the common
686          * struct asap.
687          */
688         pti->pt_flags2 &= ~PF_MOPEN;
689 #endif
690
691         pti->pt_prison = NULL;
692         pti->devs->si_uid = 0;
693         pti->devs->si_gid = 0;
694         pti->devs->si_perms = 0666;
695         pti->devc->si_uid = 0;
696         pti->devc->si_gid = 0;
697         pti->devc->si_perms = 0666;
698
699         pti_done(pti);
700
701         lwkt_reltoken(&tty_token);
702         return (0);
703 }
704
705 static  int
706 ptcread(struct dev_read_args *ap)
707 {
708         cdev_t dev = ap->a_head.a_dev;
709         struct tty *tp = dev->si_tty;
710         struct pt_ioctl *pti = dev->si_drv1;
711         char buf[BUFSIZ];
712         int error = 0, cc;
713
714         lwkt_gettoken(&tty_token);
715         /*
716          * We want to block until the slave
717          * is open, and there's something to read;
718          * but if we lost the slave or we're NBIO,
719          * then return the appropriate error instead.
720          */
721         for (;;) {
722                 if (tp->t_state&TS_ISOPEN) {
723                         if (pti->pt_flags&PF_PKT && pti->pt_send) {
724                                 error = ureadc((int)pti->pt_send, ap->a_uio);
725                                 if (error) {
726                                         lwkt_reltoken(&tty_token);
727                                         return (error);
728                                 }
729                                 if (pti->pt_send & TIOCPKT_IOCTL) {
730                                         cc = (int)szmin(ap->a_uio->uio_resid,
731                                                         sizeof(tp->t_termios));
732                                         uiomove((caddr_t)&tp->t_termios, cc,
733                                                 ap->a_uio);
734                                 }
735                                 pti->pt_send = 0;
736                                 lwkt_reltoken(&tty_token);
737                                 return (0);
738                         }
739                         if (pti->pt_flags&PF_UCNTL && pti->pt_ucntl) {
740                                 error = ureadc((int)pti->pt_ucntl, ap->a_uio);
741                                 if (error) {
742                                         lwkt_reltoken(&tty_token);
743                                         return (error);
744                                 }
745                                 pti->pt_ucntl = 0;
746                                 lwkt_reltoken(&tty_token);
747                                 return (0);
748                         }
749                         if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
750                                 break;
751                 }
752                 if ((tp->t_state & TS_CONNECTED) == 0) {
753                         lwkt_reltoken(&tty_token);
754                         return (0);     /* EOF */
755                 }
756                 if (ap->a_ioflag & IO_NDELAY) {
757                         lwkt_reltoken(&tty_token);
758                         return (EWOULDBLOCK);
759                 }
760                 error = tsleep(TSA_PTC_READ(tp), PCATCH, "ptcin", 0);
761                 if (error) {
762                         lwkt_reltoken(&tty_token);
763                         return (error);
764                 }
765         }
766         if (pti->pt_flags & (PF_PKT|PF_UCNTL))
767                 error = ureadc(0, ap->a_uio);
768         while (ap->a_uio->uio_resid > 0 && error == 0) {
769                 cc = q_to_b(&tp->t_outq, buf,
770                             (int)szmin(ap->a_uio->uio_resid, BUFSIZ));
771                 if (cc <= 0)
772                         break;
773                 error = uiomove(buf, (size_t)cc, ap->a_uio);
774         }
775         ttwwakeup(tp);
776         lwkt_reltoken(&tty_token);
777         return (error);
778 }
779
780 static  void
781 ptsstop(struct tty *tp, int flush)
782 {
783         struct pt_ioctl *pti = tp->t_dev->si_drv1;
784         int flag;
785
786         lwkt_gettoken(&tty_token);
787         /* note: FLUSHREAD and FLUSHWRITE already ok */
788         if (pti) {
789                 if (flush == 0) {
790                         flush = TIOCPKT_STOP;
791                         pti->pt_flags |= PF_STOPPED;
792                 } else {
793                         pti->pt_flags &= ~PF_STOPPED;
794                 }
795                 pti->pt_send |= flush;
796                 /* change of perspective */
797         }
798         flag = 0;
799         if (flush & FREAD)
800                 flag |= FWRITE;
801         if (flush & FWRITE)
802                 flag |= FREAD;
803         ptcwakeup(tp, flag);
804
805         lwkt_reltoken(&tty_token);
806 }
807
808 /*
809  * kqueue ops for pseudo-terminals.
810  */
811 static struct filterops ptcread_filtops =
812         { FILTEROP_ISFD, NULL, filt_ptcrdetach, filt_ptcread };
813 static struct filterops ptcwrite_filtops =
814         { FILTEROP_ISFD, NULL, filt_ptcwdetach, filt_ptcwrite };
815
816 static  int
817 ptckqfilter(struct dev_kqfilter_args *ap)
818 {
819         cdev_t dev = ap->a_head.a_dev;
820         struct knote *kn = ap->a_kn;
821         struct tty *tp = dev->si_tty;
822         struct klist *klist;
823
824         lwkt_gettoken(&tty_token);
825         ap->a_result = 0;
826         switch (kn->kn_filter) {
827         case EVFILT_READ:
828                 klist = &tp->t_rkq.ki_note;
829                 kn->kn_fop = &ptcread_filtops;
830                 break;
831         case EVFILT_WRITE:
832                 klist = &tp->t_wkq.ki_note;
833                 kn->kn_fop = &ptcwrite_filtops;
834                 break;
835         default:
836                 ap->a_result = EOPNOTSUPP;
837                 lwkt_reltoken(&tty_token);
838                 return (0);
839         }
840
841         kn->kn_hook = (caddr_t)dev;
842         knote_insert(klist, kn);
843         lwkt_reltoken(&tty_token);
844         return (0);
845 }
846
847 static int
848 filt_ptcread (struct knote *kn, long hint)
849 {
850         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
851         struct pt_ioctl *pti = ((cdev_t)kn->kn_hook)->si_drv1;
852
853         lwkt_gettoken(&tty_token);
854         if (tp->t_state & TS_ZOMBIE) {
855                 kn->kn_flags |= EV_EOF;
856                 lwkt_reltoken(&tty_token);
857                 return (1);
858         }
859
860         if ((tp->t_state & TS_ISOPEN) &&
861             ((tp->t_outq.c_cc && (tp->t_state & TS_TTSTOP) == 0) ||
862              ((pti->pt_flags & PF_PKT) && pti->pt_send) ||
863              ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))) {
864                 kn->kn_data = tp->t_outq.c_cc;
865                 lwkt_reltoken(&tty_token);
866                 return(1);
867         } else {
868                 lwkt_reltoken(&tty_token);
869                 return(0);
870         }
871 }
872
873 static int
874 filt_ptcwrite (struct knote *kn, long hint)
875 {
876         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
877         struct pt_ioctl *pti = ((cdev_t)kn->kn_hook)->si_drv1;
878
879         lwkt_gettoken(&tty_token);
880         if (tp->t_state & TS_ZOMBIE) {
881                 kn->kn_flags |= EV_EOF;
882                 lwkt_reltoken(&tty_token);
883                 return (1);
884         }
885
886         if (tp->t_state & TS_ISOPEN &&
887             ((pti->pt_flags & PF_REMOTE) ?
888              (tp->t_canq.c_cc == 0) :
889              ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) ||
890               (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON))))) {
891                 kn->kn_data = tp->t_canq.c_cc + tp->t_rawq.c_cc;
892                 lwkt_reltoken(&tty_token);
893                 return(1);
894         } else {
895                 lwkt_reltoken(&tty_token);
896                 return(0);
897         }
898         /* NOTREACHED */
899 }
900
901 static void
902 filt_ptcrdetach (struct knote *kn)
903 {
904         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
905
906         knote_remove(&tp->t_rkq.ki_note, kn);
907 }
908
909 static void
910 filt_ptcwdetach (struct knote *kn)
911 {
912         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
913
914         knote_remove(&tp->t_wkq.ki_note, kn);
915 }
916
917 /*
918  * I/O ops
919  */
920 static  int
921 ptcwrite(struct dev_write_args *ap)
922 {
923         cdev_t dev = ap->a_head.a_dev;
924         struct tty *tp = dev->si_tty;
925         u_char *cp = 0;
926         int cc = 0;
927         u_char locbuf[BUFSIZ];
928         int cnt = 0;
929         struct pt_ioctl *pti = dev->si_drv1;
930         int error = 0;
931
932         lwkt_gettoken(&tty_token);
933 again:
934         if ((tp->t_state&TS_ISOPEN) == 0)
935                 goto block;
936         if (pti->pt_flags & PF_REMOTE) {
937                 if (tp->t_canq.c_cc)
938                         goto block;
939                 while ((ap->a_uio->uio_resid > 0 || cc > 0) &&
940                        tp->t_canq.c_cc < TTYHOG - 1) {
941                         if (cc == 0) {
942                                 cc = (int)szmin(ap->a_uio->uio_resid, BUFSIZ);
943                                 cc = imin(cc, TTYHOG - 1 - tp->t_canq.c_cc);
944                                 cp = locbuf;
945                                 error = uiomove(cp, (size_t)cc, ap->a_uio);
946                                 if (error) {
947                                         lwkt_reltoken(&tty_token);
948                                         return (error);
949                                 }
950                                 /* check again for safety */
951                                 if ((tp->t_state & TS_ISOPEN) == 0) {
952                                         /* adjust as usual */
953                                         ap->a_uio->uio_resid += cc;
954                                         lwkt_reltoken(&tty_token);
955                                         return (EIO);
956                                 }
957                         }
958                         if (cc > 0) {
959                                 cc = b_to_q((char *)cp, cc, &tp->t_canq);
960                                 /*
961                                  * XXX we don't guarantee that the canq size
962                                  * is >= TTYHOG, so the above b_to_q() may
963                                  * leave some bytes uncopied.  However, space
964                                  * is guaranteed for the null terminator if
965                                  * we don't fail here since (TTYHOG - 1) is
966                                  * not a multiple of CBSIZE.
967                                  */
968                                 if (cc > 0)
969                                         break;
970                         }
971                 }
972                 /* adjust for data copied in but not written */
973                 ap->a_uio->uio_resid += cc;
974                 clist_putc(0, &tp->t_canq);
975                 ttwakeup(tp);
976                 wakeup(TSA_PTS_READ(tp));
977                 lwkt_reltoken(&tty_token);
978                 return (0);
979         }
980         while (ap->a_uio->uio_resid > 0 || cc > 0) {
981                 if (cc == 0) {
982                         cc = (int)szmin(ap->a_uio->uio_resid, BUFSIZ);
983                         cp = locbuf;
984                         error = uiomove(cp, (size_t)cc, ap->a_uio);
985                         if (error) {
986                                 lwkt_reltoken(&tty_token);
987                                 return (error);
988                         }
989                         /* check again for safety */
990                         if ((tp->t_state & TS_ISOPEN) == 0) {
991                                 /* adjust for data copied in but not written */
992                                 ap->a_uio->uio_resid += cc;
993                                 lwkt_reltoken(&tty_token);
994                                 return (EIO);
995                         }
996                 }
997                 while (cc > 0) {
998                         if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
999                            (tp->t_canq.c_cc > 0 || !(tp->t_lflag&ICANON))) {
1000                                 wakeup(TSA_HUP_OR_INPUT(tp));
1001                                 goto block;
1002                         }
1003                         (*linesw[tp->t_line].l_rint)(*cp++, tp);
1004                         cnt++;
1005                         cc--;
1006                 }
1007                 cc = 0;
1008         }
1009         lwkt_reltoken(&tty_token);
1010         return (0);
1011 block:
1012         /*
1013          * Come here to wait for slave to open, for space
1014          * in outq, or space in rawq, or an empty canq.
1015          */
1016         if ((tp->t_state & TS_CONNECTED) == 0) {
1017                 /* adjust for data copied in but not written */
1018                 ap->a_uio->uio_resid += cc;
1019                 lwkt_reltoken(&tty_token);
1020                 return (EIO);
1021         }
1022         if (ap->a_ioflag & IO_NDELAY) {
1023                 /* adjust for data copied in but not written */
1024                 ap->a_uio->uio_resid += cc;
1025                 if (cnt == 0) {
1026                         lwkt_reltoken(&tty_token);
1027                         return (EWOULDBLOCK);
1028                 }
1029                 lwkt_reltoken(&tty_token);
1030                 return (0);
1031         }
1032         error = tsleep(TSA_PTC_WRITE(tp), PCATCH, "ptcout", 0);
1033         if (error) {
1034                 /* adjust for data copied in but not written */
1035                 ap->a_uio->uio_resid += cc;
1036                 lwkt_reltoken(&tty_token);
1037                 return (error);
1038         }
1039         goto again;
1040 }
1041
1042 /*ARGSUSED*/
1043 static  int
1044 ptyioctl(struct dev_ioctl_args *ap)
1045 {
1046         cdev_t dev = ap->a_head.a_dev;
1047         struct tty *tp = dev->si_tty;
1048         struct pt_ioctl *pti = dev->si_drv1;
1049         u_char *cc = tp->t_cc;
1050         int stop, error;
1051
1052         lwkt_gettoken(&tty_token);
1053         if (dev_dflags(dev) & D_MASTER) {
1054                 switch (ap->a_cmd) {
1055
1056                 case TIOCGPGRP:
1057                         /*
1058                          * We avoid calling ttioctl on the controller since,
1059                          * in that case, tp must be the controlling terminal.
1060                          */
1061                         *(int *)ap->a_data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
1062                         lwkt_reltoken(&tty_token);
1063                         return (0);
1064
1065                 case TIOCPKT:
1066                         if (*(int *)ap->a_data) {
1067                                 if (pti->pt_flags & PF_UCNTL) {
1068                                         lwkt_reltoken(&tty_token);
1069                                         return (EINVAL);
1070                                 }
1071                                 pti->pt_flags |= PF_PKT;
1072                         } else
1073                                 pti->pt_flags &= ~PF_PKT;
1074                         lwkt_reltoken(&tty_token);
1075                         return (0);
1076
1077                 case TIOCUCNTL:
1078                         if (*(int *)ap->a_data) {
1079                                 if (pti->pt_flags & PF_PKT) {
1080                                         lwkt_reltoken(&tty_token);
1081                                         return (EINVAL);
1082                                 }
1083                                 pti->pt_flags |= PF_UCNTL;
1084                         } else
1085                                 pti->pt_flags &= ~PF_UCNTL;
1086                         lwkt_reltoken(&tty_token);
1087                         return (0);
1088
1089                 case TIOCREMOTE:
1090                         if (*(int *)ap->a_data)
1091                                 pti->pt_flags |= PF_REMOTE;
1092                         else
1093                                 pti->pt_flags &= ~PF_REMOTE;
1094                         ttyflush(tp, FREAD|FWRITE);
1095                         lwkt_reltoken(&tty_token);
1096                         return (0);
1097
1098 #ifdef UNIX98_PTYS
1099                 case TIOCISPTMASTER:
1100                         if ((pti->pt_flags2 & PF_UNIX98) && (pti->devc == dev)) {
1101                                 lwkt_reltoken(&tty_token);
1102                                 return (0);
1103                         } else {
1104                                 lwkt_reltoken(&tty_token);
1105                                 return (EINVAL);
1106                         }
1107                 }
1108 #endif
1109
1110                 /*
1111                  * The rest of the ioctls shouldn't be called until 
1112                  * the slave is open.
1113                  */
1114                 if ((tp->t_state & TS_ISOPEN) == 0) {
1115                         lwkt_reltoken(&tty_token);
1116                         return (EAGAIN);
1117                 }
1118
1119                 switch (ap->a_cmd) {
1120 #ifdef COMPAT_43
1121                 case TIOCSETP:
1122                 case TIOCSETN:
1123 #endif
1124                 case TIOCSETD:
1125                 case TIOCSETA:
1126                 case TIOCSETAW:
1127                 case TIOCSETAF:
1128                         /*
1129                          * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
1130                          * ttywflush(tp) will hang if there are characters in
1131                          * the outq.
1132                          */
1133                         ndflush(&tp->t_outq, tp->t_outq.c_cc);
1134                         break;
1135
1136                 case TIOCSIG:
1137                         if (*(unsigned int *)ap->a_data >= NSIG ||
1138                             *(unsigned int *)ap->a_data == 0) {
1139                                 lwkt_reltoken(&tty_token);
1140                                 return(EINVAL);
1141                         }
1142                         if ((tp->t_lflag&NOFLSH) == 0)
1143                                 ttyflush(tp, FREAD|FWRITE);
1144                         pgsignal(tp->t_pgrp, *(unsigned int *)ap->a_data, 1);
1145                         if ((*(unsigned int *)ap->a_data == SIGINFO) &&
1146                             ((tp->t_lflag&NOKERNINFO) == 0))
1147                                 ttyinfo(tp);
1148                         lwkt_reltoken(&tty_token);
1149                         return(0);
1150                 }
1151         }
1152         if (ap->a_cmd == TIOCEXT) {
1153                 /*
1154                  * When the EXTPROC bit is being toggled, we need
1155                  * to send an TIOCPKT_IOCTL if the packet driver
1156                  * is turned on.
1157                  */
1158                 if (*(int *)ap->a_data) {
1159                         if (pti->pt_flags & PF_PKT) {
1160                                 pti->pt_send |= TIOCPKT_IOCTL;
1161                                 ptcwakeup(tp, FREAD);
1162                         }
1163                         tp->t_lflag |= EXTPROC;
1164                 } else {
1165                         if ((tp->t_lflag & EXTPROC) &&
1166                             (pti->pt_flags & PF_PKT)) {
1167                                 pti->pt_send |= TIOCPKT_IOCTL;
1168                                 ptcwakeup(tp, FREAD);
1169                         }
1170                         tp->t_lflag &= ~EXTPROC;
1171                 }
1172                 lwkt_reltoken(&tty_token);
1173                 return(0);
1174         }
1175         error = (*linesw[tp->t_line].l_ioctl)(tp, ap->a_cmd, ap->a_data,
1176                                               ap->a_fflag, ap->a_cred);
1177         if (error == ENOIOCTL)
1178                  error = ttioctl(tp, ap->a_cmd, ap->a_data, ap->a_fflag);
1179         if (error == ENOIOCTL) {
1180                 if (pti->pt_flags & PF_UCNTL &&
1181                     (ap->a_cmd & ~0xff) == UIOCCMD(0)) {
1182                         if (ap->a_cmd & 0xff) {
1183                                 pti->pt_ucntl = (u_char)ap->a_cmd;
1184                                 ptcwakeup(tp, FREAD);
1185                         }
1186                         lwkt_reltoken(&tty_token);
1187                         return (0);
1188                 }
1189                 error = ENOTTY;
1190         }
1191         /*
1192          * If external processing and packet mode send ioctl packet.
1193          */
1194         if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
1195                 switch(ap->a_cmd) {
1196                 case TIOCSETA:
1197                 case TIOCSETAW:
1198                 case TIOCSETAF:
1199 #ifdef COMPAT_43
1200                 case TIOCSETP:
1201                 case TIOCSETN:
1202 #endif
1203 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1204                 case TIOCSETC:
1205                 case TIOCSLTC:
1206                 case TIOCLBIS:
1207                 case TIOCLBIC:
1208                 case TIOCLSET:
1209 #endif
1210                         pti->pt_send |= TIOCPKT_IOCTL;
1211                         ptcwakeup(tp, FREAD);
1212                 default:
1213                         break;
1214                 }
1215         }
1216         stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
1217                 && CCEQ(cc[VSTART], CTRL('q'));
1218         if (pti->pt_flags & PF_NOSTOP) {
1219                 if (stop) {
1220                         pti->pt_send &= ~TIOCPKT_NOSTOP;
1221                         pti->pt_send |= TIOCPKT_DOSTOP;
1222                         pti->pt_flags &= ~PF_NOSTOP;
1223                         ptcwakeup(tp, FREAD);
1224                 }
1225         } else {
1226                 if (!stop) {
1227                         pti->pt_send &= ~TIOCPKT_DOSTOP;
1228                         pti->pt_send |= TIOCPKT_NOSTOP;
1229                         pti->pt_flags |= PF_NOSTOP;
1230                         ptcwakeup(tp, FREAD);
1231                 }
1232         }
1233         lwkt_reltoken(&tty_token);
1234         return (error);
1235 }
1236
1237
1238 static void ptc_drvinit (void *unused);
1239
1240 #ifdef UNIX98_PTYS
1241 SYSCTL_INT(_kern, OID_AUTO, pty_debug, CTLFLAG_RW, &pty_debug_level,
1242                 0, "Change pty debug level");
1243 #endif
1244
1245 static void
1246 ptc_drvinit(void *unused)
1247 {
1248         int i;
1249
1250 #ifdef UNIX98_PTYS
1251         /*
1252          * Unix98 pty stuff.
1253          * Create the clonable base device.
1254          */
1255         make_autoclone_dev(&ptc_ops, &DEVFS_CLONE_BITMAP(pty), ptyclone,
1256             0, 0, 0666, "ptmx");
1257 #endif
1258
1259         for (i = 0; i < 256; i++) {
1260                 ptyinit(i);
1261         }
1262 }
1263
1264 SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL)