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