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