kernel - Fix pty registration, memory leak
[dragonfly.git] / sys / kern / tty_pty.c
CommitLineData
984263bc
MD
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 $
8683f632 35 * $DragonFly: src/sys/kern/tty_pty.c,v 1.21 2008/08/13 10:29:38 swildner Exp $
984263bc
MD
36 */
37
38/*
39 * Pseudo-teletype Driver
fef8985e 40 * (Actually two drivers, requiring two dev_ops structures)
984263bc 41 */
1f2de5d4 42#include "use_pty.h" /* XXX */
984263bc 43#include "opt_compat.h"
1f2de5d4 44
984263bc
MD
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>
895c1f85 51#include <sys/priv.h>
984263bc
MD
52#include <sys/tty.h>
53#include <sys/conf.h>
54#include <sys/fcntl.h>
984263bc
MD
55#include <sys/kernel.h>
56#include <sys/vnode.h>
57#include <sys/signalvar.h>
58#include <sys/malloc.h>
335dda38 59#include <sys/device.h>
e43a034f 60#include <sys/thread2.h>
2c1e28dd 61#include <sys/devfs.h>
c578a286
AH
62#include <sys/stat.h>
63#include <sys/sysctl.h>
cd29885a 64
c578a286 65#define UNIX98_PTYS 1
984263bc
MD
66
67MALLOC_DEFINE(M_PTY, "ptys", "pty data structures");
68
402ed7e1
RG
69static void ptsstart (struct tty *tp);
70static void ptsstop (struct tty *tp, int rw);
71static void ptcwakeup (struct tty *tp, int flag);
72static void ptyinit (int n);
8acdf1cf
MD
73static int filt_ptcread (struct knote *kn, long hint);
74static void filt_ptcrdetach (struct knote *kn);
75static int filt_ptcwrite (struct knote *kn, long hint);
76static void filt_ptcwdetach (struct knote *kn);
984263bc
MD
77
78static d_open_t ptsopen;
79static d_close_t ptsclose;
80static d_read_t ptsread;
81static d_write_t ptswrite;
82static d_ioctl_t ptyioctl;
83static d_open_t ptcopen;
84static d_close_t ptcclose;
85static d_read_t ptcread;
86static d_write_t ptcwrite;
8acdf1cf 87static d_kqfilter_t ptckqfilter;
c578a286
AH
88
89#ifdef UNIX98_PTYS
90DEVFS_DECLARE_CLONE_BITMAP(pty);
91
cd29885a 92static d_clone_t ptyclone;
c578a286
AH
93
94static int pty_debug_level = 0;
530c8749
AH
95
96static 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,
530c8749
AH
103 .d_kqfilter = ttykqfilter,
104 .d_revoke = ttyrevoke
105};
106
107static 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,
8acdf1cf 114 .d_kqfilter = ptckqfilter,
530c8749
AH
115 .d_revoke = ttyrevoke
116};
5d40c1cd 117#endif
984263bc
MD
118
119#define CDEV_MAJOR_S 5
fef8985e
MD
120static 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,
a32446b7
MD
127 .d_kqfilter = ttykqfilter,
128 .d_revoke = ttyrevoke
984263bc
MD
129};
130
131#define CDEV_MAJOR_C 6
fef8985e
MD
132static 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,
8acdf1cf 139 .d_kqfilter = ptckqfilter,
a32446b7 140 .d_revoke = ttyrevoke
984263bc
MD
141};
142
143#define BUFSIZ 100 /* Chunk size iomoved to/from user */
144
145struct pt_ioctl {
146 int pt_flags;
c578a286 147 int pt_flags2;
5b22f1a7 148 struct kqinfo pt_kqr, pt_kqw;
984263bc
MD
149 u_char pt_send;
150 u_char pt_ucntl;
151 struct tty pt_tty;
b13267a5 152 cdev_t devs, devc;
984263bc
MD
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
c578a286
AH
162#define PF_UNIX98 0x01
163#define PF_SOPEN 0x02
164#define PF_MOPEN 0x04
165
166static int
167ptydebug(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
984263bc
MD
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 */
188static void
c972a82f 189ptyinit(int n)
984263bc 190{
b13267a5 191 cdev_t devs, devc;
984263bc
MD
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
e7b4468c 199 pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO);
fef8985e 200 pt->devs = devs = make_dev(&pts_ops, n,
984263bc 201 0, 0, 0666, "tty%c%r", names[n / 32], n % 32);
fef8985e 202 pt->devc = devc = make_dev(&ptc_ops, n,
984263bc
MD
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;
4062d050
MD
207 devs->si_flags |= SI_OVERRIDE; /* uid, gid, perms from dev */
208 devc->si_flags |= SI_OVERRIDE; /* uid, gid, perms from dev */
984263bc
MD
209 pt->pt_tty.t_dev = devs;
210 ttyregister(&pt->pt_tty);
211}
212
c578a286 213#ifdef UNIX98_PTYS
cd29885a
MD
214static int
215ptyclone(struct dev_clone_args *ap)
216{
217 int unit;
218 struct pt_ioctl *pt;
219
c578a286
AH
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);
cd29885a 228
c578a286
AH
229 if (unit < 0) {
230 ap->a_dev = NULL;
cd29885a 231 return 1;
c578a286 232 }
cd29885a
MD
233
234 pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO);
cd29885a 235
530c8749 236 pt->devc = ap->a_dev = make_only_dev(&ptc98_ops, unit, ap->a_cred->cr_ruid,
c578a286 237 0, 0600, "ptm/%d", unit);
530c8749 238 pt->devs = make_dev(&pts98_ops, unit, ap->a_cred->cr_ruid, GID_TTY, 0620,
c578a286
AH
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 */
cd29885a
MD
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;
c578a286
AH
247 pt->pt_flags2 |= PF_UNIX98;
248
cd29885a
MD
249 ttyregister(&pt->pt_tty);
250
251 return 0;
252}
5d40c1cd 253#endif
cd29885a 254
984263bc
MD
255/*ARGSUSED*/
256static int
fef8985e 257ptsopen(struct dev_open_args *ap)
984263bc 258{
b13267a5 259 cdev_t dev = ap->a_head.a_dev;
1fd87d54 260 struct tty *tp;
984263bc 261 int error;
984263bc
MD
262 struct pt_ioctl *pti;
263
984263bc
MD
264 if (!dev->si_drv1)
265 ptyinit(minor(dev));
266 if (!dev->si_drv1)
cd29885a 267 return(ENXIO);
984263bc
MD
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;
895c1f85 277 } else if ((tp->t_state & TS_XCLUDE) && priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) {
984263bc 278 return (EBUSY);
fef8985e 279 } else if (pti->pt_prison != ap->a_cred->cr_prison) {
984263bc
MD
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) {
fef8985e 285 if (ap->a_oflags & FNONBLOCK)
984263bc 286 break;
377d4740 287 error = ttysleep(tp, TSA_CARR_ON(tp), PCATCH, "ptsopn", 0);
984263bc
MD
288 if (error)
289 return (error);
290 }
41cf5266 291 tp->t_state &= ~TS_ZOMBIE;
984263bc
MD
292 error = (*linesw[tp->t_line].l_open)(dev, tp);
293 if (error == 0)
294 ptcwakeup(tp, FREAD|FWRITE);
cd29885a 295
c578a286
AH
296#ifdef UNIX98_PTYS
297 /*
298 * Unix98 pty stuff.
299 * On open of the slave, we set the corresponding flag in the common
300 * struct.
301 */
302 ptydebug(1, "ptsopen=%s | unix98? %s\n", dev->si_name,
303 (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
304
305 if ((!error) && (pti->pt_flags2 & PF_UNIX98)) {
306 pti->pt_flags2 |= PF_SOPEN;
cd29885a
MD
307 }
308#endif
309
984263bc
MD
310 return (error);
311}
312
313static int
fef8985e 314ptsclose(struct dev_close_args *ap)
984263bc 315{
b13267a5 316 cdev_t dev = ap->a_head.a_dev;
1fd87d54 317 struct tty *tp;
c578a286 318 struct pt_ioctl *pti = dev->si_drv1;
984263bc 319 int err;
ddac2002 320 int uminor_no;
c578a286
AH
321
322 tp = dev->si_tty;
ddac2002 323 uminor_no = dev->si_uminor;
c578a286
AH
324 err = (*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
325 ptsstop(tp, FREAD|FWRITE);
847ff8ce
SG
326 (void) ttyclose(tp); /* clears t_state */
327 tp->t_state |= TS_ZOMBIE;
c578a286
AH
328
329#ifdef UNIX98_PTYS
330 /*
331 * Unix98 pty stuff.
332 * On close of the slave, we unset the corresponding flag, and if the master
333 * isn't open anymore, we destroy the slave and unset the unit.
334 */
335 ptydebug(1, "ptsclose=%s | unix98? %s\n", dev->si_name,
336 (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
337
338 if (pti->pt_flags2 & PF_UNIX98) {
339 pti->pt_flags2 &= ~PF_SOPEN;
340 KKASSERT((pti->pt_flags2 & PF_SOPEN) == 0);
341 ptydebug(1, "master open? %s\n",
342 (pti->pt_flags2 & PF_MOPEN)?"yes":"no");
343
ddac2002
MD
344 if (!(pti->pt_flags2 & PF_SOPEN) &&
345 !(pti->pt_flags2 & PF_MOPEN)) {
cd29885a 346 destroy_dev(dev);
ddac2002
MD
347 devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(pty),
348 uminor_no);
349 ttyunregister(&pti->pt_tty);
350 kfree(pti, M_PTY);
cd29885a
MD
351 }
352 }
353#endif
c578a286 354
984263bc
MD
355 return (err);
356}
357
358static int
fef8985e 359ptsread(struct dev_read_args *ap)
984263bc 360{
b13267a5 361 cdev_t dev = ap->a_head.a_dev;
984263bc 362 struct proc *p = curproc;
1fd87d54
RG
363 struct tty *tp = dev->si_tty;
364 struct pt_ioctl *pti = dev->si_drv1;
08f2f1bb
SS
365 struct lwp *lp;
366
984263bc
MD
367 int error = 0;
368
08f2f1bb
SS
369 lp = curthread->td_lwp;
370
984263bc
MD
371again:
372 if (pti->pt_flags & PF_REMOTE) {
373 while (isbackground(p, tp)) {
374 if (SIGISMEMBER(p->p_sigignore, SIGTTIN) ||
08f2f1bb 375 SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) ||
984263bc
MD
376 p->p_pgrp->pg_jobc == 0 || p->p_flag & P_PPWAIT)
377 return (EIO);
378 pgsignal(p->p_pgrp, SIGTTIN, 1);
377d4740 379 error = ttysleep(tp, &lbolt, PCATCH, "ptsbg", 0);
984263bc
MD
380 if (error)
381 return (error);
382 }
383 if (tp->t_canq.c_cc == 0) {
fef8985e 384 if (ap->a_ioflag & IO_NDELAY)
984263bc 385 return (EWOULDBLOCK);
377d4740 386 error = ttysleep(tp, TSA_PTS_READ(tp), PCATCH,
984263bc
MD
387 "ptsin", 0);
388 if (error)
389 return (error);
390 goto again;
391 }
fef8985e 392 while (tp->t_canq.c_cc > 1 && ap->a_uio->uio_resid > 0)
0ced1954 393 if (ureadc(clist_getc(&tp->t_canq), ap->a_uio) < 0) {
984263bc
MD
394 error = EFAULT;
395 break;
396 }
397 if (tp->t_canq.c_cc == 1)
0ced1954 398 clist_getc(&tp->t_canq);
984263bc
MD
399 if (tp->t_canq.c_cc)
400 return (error);
401 } else
402 if (tp->t_oproc)
fef8985e 403 error = (*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag);
984263bc
MD
404 ptcwakeup(tp, FWRITE);
405 return (error);
406}
407
408/*
409 * Write to pseudo-tty.
410 * Wakeups of controlling tty will happen
411 * indirectly, when tty driver calls ptsstart.
412 */
413static int
fef8985e 414ptswrite(struct dev_write_args *ap)
984263bc 415{
b13267a5 416 cdev_t dev = ap->a_head.a_dev;
1fd87d54 417 struct tty *tp;
984263bc
MD
418
419 tp = dev->si_tty;
420 if (tp->t_oproc == 0)
421 return (EIO);
fef8985e 422 return ((*linesw[tp->t_line].l_write)(tp, ap->a_uio, ap->a_ioflag));
984263bc
MD
423}
424
425/*
426 * Start output on pseudo-tty.
427 * Wake up process selecting or sleeping for input from controlling tty.
428 */
429static void
c972a82f 430ptsstart(struct tty *tp)
984263bc 431{
1fd87d54 432 struct pt_ioctl *pti = tp->t_dev->si_drv1;
984263bc
MD
433
434 if (tp->t_state & TS_TTSTOP)
435 return;
436 if (pti->pt_flags & PF_STOPPED) {
437 pti->pt_flags &= ~PF_STOPPED;
438 pti->pt_send = TIOCPKT_START;
439 }
440 ptcwakeup(tp, FREAD);
441}
442
443static void
c972a82f 444ptcwakeup(struct tty *tp, int flag)
984263bc 445{
984263bc 446 if (flag & FREAD) {
984263bc 447 wakeup(TSA_PTC_READ(tp));
5b22f1a7 448 KNOTE(&tp->t_rkq.ki_note, 0);
984263bc
MD
449 }
450 if (flag & FWRITE) {
984263bc 451 wakeup(TSA_PTC_WRITE(tp));
5b22f1a7 452 KNOTE(&tp->t_wkq.ki_note, 0);
984263bc
MD
453 }
454}
455
456static int
fef8985e 457ptcopen(struct dev_open_args *ap)
984263bc 458{
b13267a5 459 cdev_t dev = ap->a_head.a_dev;
1fd87d54 460 struct tty *tp;
984263bc
MD
461 struct pt_ioctl *pti;
462
463 if (!dev->si_drv1)
464 ptyinit(minor(dev));
465 if (!dev->si_drv1)
466 return(ENXIO);
4062d050
MD
467 pti = dev->si_drv1;
468 if (pti->pt_prison && pti->pt_prison != ap->a_cred->cr_prison)
469 return(EBUSY);
984263bc
MD
470 tp = dev->si_tty;
471 if (tp->t_oproc)
472 return (EIO);
473 tp->t_oproc = ptsstart;
474 tp->t_stop = ptsstop;
475 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
476 tp->t_lflag &= ~EXTPROC;
fef8985e 477 pti->pt_prison = ap->a_cred->cr_prison;
984263bc
MD
478 pti->pt_flags = 0;
479 pti->pt_send = 0;
480 pti->pt_ucntl = 0;
4062d050 481
cd65363e 482 pti->devs->si_uid = ap->a_cred->cr_uid;
4062d050
MD
483 pti->devs->si_gid = 0;
484 pti->devs->si_perms = 0600;
485 pti->devc->si_uid = ap->a_cred->cr_uid;
486 pti->devc->si_gid = 0;
487 pti->devc->si_perms = 0600;
488
c578a286
AH
489#ifdef UNIX98_PTYS
490 /*
491 * Unix98 pty stuff.
492 * On open of the master, we set the corresponding flag in the common
493 * struct.
494 */
495 ptydebug(1, "ptcopen=%s (master) | unix98? %s\n", dev->si_name,
496 (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
497
498 if (pti->pt_flags2 & PF_UNIX98) {
499 pti->pt_flags2 |= PF_MOPEN;
500 }
501#endif
502
984263bc
MD
503 return (0);
504}
505
506static int
fef8985e 507ptcclose(struct dev_close_args *ap)
984263bc 508{
b13267a5 509 cdev_t dev = ap->a_head.a_dev;
1fd87d54 510 struct tty *tp;
c578a286 511 struct pt_ioctl *pti = dev->si_drv1;
ddac2002 512 int uminor_no;
984263bc
MD
513
514 tp = dev->si_tty;
ddac2002 515 uminor_no = dev->si_uminor;
984263bc
MD
516 (void)(*linesw[tp->t_line].l_modem)(tp, 0);
517
c578a286
AH
518#ifdef UNIX98_PTYS
519 /*
520 * Unix98 pty stuff.
521 * On close of the master, we unset the corresponding flag in the common
522 * struct asap.
523 */
524 pti->pt_flags2 &= ~PF_MOPEN;
525#endif
526
984263bc
MD
527 /*
528 * XXX MDMBUF makes no sense for ptys but would inhibit the above
529 * l_modem(). CLOCAL makes sense but isn't supported. Special
530 * l_modem()s that ignore carrier drop make no sense for ptys but
531 * may be in use because other parts of the line discipline make
532 * sense for ptys. Recover by doing everything that a normal
533 * ttymodem() would have done except for sending a SIGHUP.
534 */
535 if (tp->t_state & TS_ISOPEN) {
536 tp->t_state &= ~(TS_CARR_ON | TS_CONNECTED);
537 tp->t_state |= TS_ZOMBIE;
538 ttyflush(tp, FREAD | FWRITE);
539 }
984263bc 540 tp->t_oproc = 0; /* mark closed */
4062d050
MD
541
542 pti = dev->si_drv1;
543 pti->pt_prison = NULL;
544 pti->devs->si_uid = 0;
545 pti->devs->si_gid = 0;
546 pti->devs->si_perms = 0666;
547 pti->devc->si_uid = 0;
548 pti->devc->si_gid = 0;
549 pti->devc->si_perms = 0666;
550
c578a286
AH
551#ifdef UNIX98_PTYS
552 /*
553 * Unix98 pty stuff.
554 * On close of the master, we destroy the master and, if no slaves are open,
555 * we destroy the slave device and unset the unit.
556 */
557 ptydebug(1, "ptcclose=%s (master) | unix98? %s\n", dev->si_name,
558 (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
559 if (pti->pt_flags2 & PF_UNIX98) {
560 KKASSERT((pti->pt_flags2 & PF_MOPEN) == 0);
561 destroy_dev(dev);
562 pti->devc = NULL;
563
564 if (!(pti->pt_flags2 & PF_SOPEN)) {
565 ptydebug(1, "ptcclose: slaves are not open\n");
566 destroy_dev(pti->devs);
ddac2002
MD
567 devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(pty),
568 uminor_no);
569 ttyunregister(&pti->pt_tty);
570 kfree(pti, M_PTY);
cd29885a 571 }
cd29885a
MD
572 }
573#endif
c578a286 574
984263bc
MD
575 return (0);
576}
577
578static int
fef8985e 579ptcread(struct dev_read_args *ap)
984263bc 580{
b13267a5 581 cdev_t dev = ap->a_head.a_dev;
1fd87d54 582 struct tty *tp = dev->si_tty;
984263bc
MD
583 struct pt_ioctl *pti = dev->si_drv1;
584 char buf[BUFSIZ];
585 int error = 0, cc;
586
587 /*
588 * We want to block until the slave
589 * is open, and there's something to read;
590 * but if we lost the slave or we're NBIO,
591 * then return the appropriate error instead.
592 */
593 for (;;) {
594 if (tp->t_state&TS_ISOPEN) {
595 if (pti->pt_flags&PF_PKT && pti->pt_send) {
fef8985e 596 error = ureadc((int)pti->pt_send, ap->a_uio);
984263bc
MD
597 if (error)
598 return (error);
599 if (pti->pt_send & TIOCPKT_IOCTL) {
e54488bb
MD
600 cc = (int)szmin(ap->a_uio->uio_resid,
601 sizeof(tp->t_termios));
984263bc 602 uiomove((caddr_t)&tp->t_termios, cc,
fef8985e 603 ap->a_uio);
984263bc
MD
604 }
605 pti->pt_send = 0;
606 return (0);
607 }
608 if (pti->pt_flags&PF_UCNTL && pti->pt_ucntl) {
fef8985e 609 error = ureadc((int)pti->pt_ucntl, ap->a_uio);
984263bc
MD
610 if (error)
611 return (error);
612 pti->pt_ucntl = 0;
613 return (0);
614 }
615 if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
616 break;
617 }
618 if ((tp->t_state & TS_CONNECTED) == 0)
619 return (0); /* EOF */
fef8985e 620 if (ap->a_ioflag & IO_NDELAY)
984263bc 621 return (EWOULDBLOCK);
377d4740 622 error = tsleep(TSA_PTC_READ(tp), PCATCH, "ptcin", 0);
984263bc
MD
623 if (error)
624 return (error);
625 }
626 if (pti->pt_flags & (PF_PKT|PF_UCNTL))
fef8985e
MD
627 error = ureadc(0, ap->a_uio);
628 while (ap->a_uio->uio_resid > 0 && error == 0) {
e54488bb
MD
629 cc = q_to_b(&tp->t_outq, buf,
630 (int)szmin(ap->a_uio->uio_resid, BUFSIZ));
984263bc
MD
631 if (cc <= 0)
632 break;
e54488bb 633 error = uiomove(buf, (size_t)cc, ap->a_uio);
984263bc
MD
634 }
635 ttwwakeup(tp);
636 return (error);
637}
638
639static void
c972a82f 640ptsstop(struct tty *tp, int flush)
984263bc
MD
641{
642 struct pt_ioctl *pti = tp->t_dev->si_drv1;
643 int flag;
644
645 /* note: FLUSHREAD and FLUSHWRITE already ok */
646 if (flush == 0) {
647 flush = TIOCPKT_STOP;
648 pti->pt_flags |= PF_STOPPED;
649 } else
650 pti->pt_flags &= ~PF_STOPPED;
651 pti->pt_send |= flush;
652 /* change of perspective */
653 flag = 0;
654 if (flush & FREAD)
655 flag |= FWRITE;
656 if (flush & FWRITE)
657 flag |= FREAD;
658 ptcwakeup(tp, flag);
659}
660
8acdf1cf
MD
661/*
662 * kqueue ops for pseudo-terminals.
663 */
664static struct filterops ptcread_filtops =
4c91dbc9 665 { FILTEROP_ISFD, NULL, filt_ptcrdetach, filt_ptcread };
8acdf1cf 666static struct filterops ptcwrite_filtops =
4c91dbc9 667 { FILTEROP_ISFD, NULL, filt_ptcwdetach, filt_ptcwrite };
8acdf1cf
MD
668
669static int
670ptckqfilter(struct dev_kqfilter_args *ap)
671{
672 cdev_t dev = ap->a_head.a_dev;
673 struct knote *kn = ap->a_kn;
674 struct tty *tp = dev->si_tty;
675 struct klist *klist;
676
677 ap->a_result = 0;
678 switch (kn->kn_filter) {
679 case EVFILT_READ:
5b22f1a7 680 klist = &tp->t_rkq.ki_note;
8acdf1cf
MD
681 kn->kn_fop = &ptcread_filtops;
682 break;
683 case EVFILT_WRITE:
5b22f1a7 684 klist = &tp->t_wkq.ki_note;
8acdf1cf
MD
685 kn->kn_fop = &ptcwrite_filtops;
686 break;
687 default:
b287d649 688 ap->a_result = EOPNOTSUPP;
8acdf1cf
MD
689 return (0);
690 }
691
692 kn->kn_hook = (caddr_t)dev;
5b22f1a7 693 knote_insert(klist, kn);
8acdf1cf
MD
694 return (0);
695}
696
697static int
698filt_ptcread (struct knote *kn, long hint)
699{
700 struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
701 struct pt_ioctl *pti = ((cdev_t)kn->kn_hook)->si_drv1;
702
847ff8ce
SG
703 if (tp->t_state & TS_ZOMBIE) {
704 kn->kn_flags |= EV_EOF;
705 return (1);
706 }
707
8acdf1cf
MD
708 if ((tp->t_state & TS_ISOPEN) &&
709 ((tp->t_outq.c_cc && (tp->t_state & TS_TTSTOP) == 0) ||
710 ((pti->pt_flags & PF_PKT) && pti->pt_send) ||
711 ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))) {
712 kn->kn_data = tp->t_outq.c_cc;
713 return(1);
714 } else {
715 return(0);
716 }
717}
718
719static int
720filt_ptcwrite (struct knote *kn, long hint)
721{
722 struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
723 struct pt_ioctl *pti = ((cdev_t)kn->kn_hook)->si_drv1;
724
847ff8ce
SG
725 if (tp->t_state & TS_ZOMBIE) {
726 kn->kn_flags |= EV_EOF;
727 return (1);
728 }
729
8acdf1cf
MD
730 if (tp->t_state & TS_ISOPEN &&
731 ((pti->pt_flags & PF_REMOTE) ?
732 (tp->t_canq.c_cc == 0) :
733 ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) ||
734 (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON))))) {
735 kn->kn_data = tp->t_canq.c_cc + tp->t_rawq.c_cc;
736 return(1);
737 } else {
738 return(0);
739 }
740}
741
742static void
743filt_ptcrdetach (struct knote *kn)
744{
745 struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
746
5b22f1a7 747 knote_remove(&tp->t_rkq.ki_note, kn);
8acdf1cf
MD
748}
749
750static void
751filt_ptcwdetach (struct knote *kn)
752{
753 struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
754
5b22f1a7 755 knote_remove(&tp->t_wkq.ki_note, kn);
8acdf1cf
MD
756}
757
758/*
759 * I/O ops
760 */
984263bc 761static int
fef8985e 762ptcwrite(struct dev_write_args *ap)
984263bc 763{
b13267a5 764 cdev_t dev = ap->a_head.a_dev;
1fd87d54
RG
765 struct tty *tp = dev->si_tty;
766 u_char *cp = 0;
767 int cc = 0;
984263bc
MD
768 u_char locbuf[BUFSIZ];
769 int cnt = 0;
770 struct pt_ioctl *pti = dev->si_drv1;
771 int error = 0;
772
773again:
774 if ((tp->t_state&TS_ISOPEN) == 0)
775 goto block;
776 if (pti->pt_flags & PF_REMOTE) {
777 if (tp->t_canq.c_cc)
778 goto block;
fef8985e 779 while ((ap->a_uio->uio_resid > 0 || cc > 0) &&
984263bc
MD
780 tp->t_canq.c_cc < TTYHOG - 1) {
781 if (cc == 0) {
e54488bb
MD
782 cc = (int)szmin(ap->a_uio->uio_resid, BUFSIZ);
783 cc = imin(cc, TTYHOG - 1 - tp->t_canq.c_cc);
984263bc 784 cp = locbuf;
e54488bb 785 error = uiomove(cp, (size_t)cc, ap->a_uio);
984263bc
MD
786 if (error)
787 return (error);
788 /* check again for safety */
789 if ((tp->t_state & TS_ISOPEN) == 0) {
790 /* adjust as usual */
fef8985e 791 ap->a_uio->uio_resid += cc;
984263bc
MD
792 return (EIO);
793 }
794 }
795 if (cc > 0) {
796 cc = b_to_q((char *)cp, cc, &tp->t_canq);
797 /*
798 * XXX we don't guarantee that the canq size
799 * is >= TTYHOG, so the above b_to_q() may
800 * leave some bytes uncopied. However, space
801 * is guaranteed for the null terminator if
802 * we don't fail here since (TTYHOG - 1) is
803 * not a multiple of CBSIZE.
804 */
805 if (cc > 0)
806 break;
807 }
808 }
809 /* adjust for data copied in but not written */
fef8985e 810 ap->a_uio->uio_resid += cc;
0ced1954 811 clist_putc(0, &tp->t_canq);
984263bc
MD
812 ttwakeup(tp);
813 wakeup(TSA_PTS_READ(tp));
814 return (0);
815 }
fef8985e 816 while (ap->a_uio->uio_resid > 0 || cc > 0) {
984263bc 817 if (cc == 0) {
e54488bb 818 cc = (int)szmin(ap->a_uio->uio_resid, BUFSIZ);
984263bc 819 cp = locbuf;
e54488bb 820 error = uiomove(cp, (size_t)cc, ap->a_uio);
984263bc
MD
821 if (error)
822 return (error);
823 /* check again for safety */
824 if ((tp->t_state & TS_ISOPEN) == 0) {
825 /* adjust for data copied in but not written */
fef8985e 826 ap->a_uio->uio_resid += cc;
984263bc
MD
827 return (EIO);
828 }
829 }
830 while (cc > 0) {
831 if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
832 (tp->t_canq.c_cc > 0 || !(tp->t_lflag&ICANON))) {
833 wakeup(TSA_HUP_OR_INPUT(tp));
834 goto block;
835 }
836 (*linesw[tp->t_line].l_rint)(*cp++, tp);
837 cnt++;
838 cc--;
839 }
840 cc = 0;
841 }
842 return (0);
843block:
844 /*
845 * Come here to wait for slave to open, for space
846 * in outq, or space in rawq, or an empty canq.
847 */
848 if ((tp->t_state & TS_CONNECTED) == 0) {
849 /* adjust for data copied in but not written */
fef8985e 850 ap->a_uio->uio_resid += cc;
984263bc
MD
851 return (EIO);
852 }
fef8985e 853 if (ap->a_ioflag & IO_NDELAY) {
984263bc 854 /* adjust for data copied in but not written */
fef8985e 855 ap->a_uio->uio_resid += cc;
984263bc
MD
856 if (cnt == 0)
857 return (EWOULDBLOCK);
858 return (0);
859 }
377d4740 860 error = tsleep(TSA_PTC_WRITE(tp), PCATCH, "ptcout", 0);
984263bc
MD
861 if (error) {
862 /* adjust for data copied in but not written */
fef8985e 863 ap->a_uio->uio_resid += cc;
984263bc
MD
864 return (error);
865 }
866 goto again;
867}
868
869/*ARGSUSED*/
870static int
fef8985e 871ptyioctl(struct dev_ioctl_args *ap)
984263bc 872{
b13267a5 873 cdev_t dev = ap->a_head.a_dev;
1fd87d54
RG
874 struct tty *tp = dev->si_tty;
875 struct pt_ioctl *pti = dev->si_drv1;
876 u_char *cc = tp->t_cc;
984263bc
MD
877 int stop, error;
878
335dda38 879 if (dev_dflags(dev) & D_MASTER) {
fef8985e 880 switch (ap->a_cmd) {
984263bc
MD
881
882 case TIOCGPGRP:
883 /*
884 * We avoid calling ttioctl on the controller since,
885 * in that case, tp must be the controlling terminal.
886 */
fef8985e 887 *(int *)ap->a_data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
984263bc
MD
888 return (0);
889
890 case TIOCPKT:
fef8985e 891 if (*(int *)ap->a_data) {
984263bc
MD
892 if (pti->pt_flags & PF_UCNTL)
893 return (EINVAL);
894 pti->pt_flags |= PF_PKT;
895 } else
896 pti->pt_flags &= ~PF_PKT;
897 return (0);
898
899 case TIOCUCNTL:
fef8985e 900 if (*(int *)ap->a_data) {
984263bc
MD
901 if (pti->pt_flags & PF_PKT)
902 return (EINVAL);
903 pti->pt_flags |= PF_UCNTL;
904 } else
905 pti->pt_flags &= ~PF_UCNTL;
906 return (0);
907
908 case TIOCREMOTE:
fef8985e 909 if (*(int *)ap->a_data)
984263bc
MD
910 pti->pt_flags |= PF_REMOTE;
911 else
912 pti->pt_flags &= ~PF_REMOTE;
913 ttyflush(tp, FREAD|FWRITE);
914 return (0);
c578a286
AH
915
916 case TIOCISPTMASTER:
917 if ((pti->pt_flags2 & PF_UNIX98) && (pti->devc == dev))
918 return (0);
919 else
920 return (EINVAL);
984263bc
MD
921 }
922
923 /*
924 * The rest of the ioctls shouldn't be called until
925 * the slave is open.
926 */
927 if ((tp->t_state & TS_ISOPEN) == 0)
928 return (EAGAIN);
929
fef8985e 930 switch (ap->a_cmd) {
984263bc
MD
931#ifdef COMPAT_43
932 case TIOCSETP:
933 case TIOCSETN:
934#endif
935 case TIOCSETD:
936 case TIOCSETA:
937 case TIOCSETAW:
938 case TIOCSETAF:
939 /*
940 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
941 * ttywflush(tp) will hang if there are characters in
942 * the outq.
943 */
944 ndflush(&tp->t_outq, tp->t_outq.c_cc);
945 break;
946
947 case TIOCSIG:
fef8985e
MD
948 if (*(unsigned int *)ap->a_data >= NSIG ||
949 *(unsigned int *)ap->a_data == 0)
984263bc
MD
950 return(EINVAL);
951 if ((tp->t_lflag&NOFLSH) == 0)
952 ttyflush(tp, FREAD|FWRITE);
fef8985e
MD
953 pgsignal(tp->t_pgrp, *(unsigned int *)ap->a_data, 1);
954 if ((*(unsigned int *)ap->a_data == SIGINFO) &&
984263bc
MD
955 ((tp->t_lflag&NOKERNINFO) == 0))
956 ttyinfo(tp);
957 return(0);
958 }
959 }
fef8985e 960 if (ap->a_cmd == TIOCEXT) {
984263bc
MD
961 /*
962 * When the EXTPROC bit is being toggled, we need
963 * to send an TIOCPKT_IOCTL if the packet driver
964 * is turned on.
965 */
fef8985e 966 if (*(int *)ap->a_data) {
984263bc
MD
967 if (pti->pt_flags & PF_PKT) {
968 pti->pt_send |= TIOCPKT_IOCTL;
969 ptcwakeup(tp, FREAD);
970 }
971 tp->t_lflag |= EXTPROC;
972 } else {
973 if ((tp->t_lflag & EXTPROC) &&
974 (pti->pt_flags & PF_PKT)) {
975 pti->pt_send |= TIOCPKT_IOCTL;
976 ptcwakeup(tp, FREAD);
977 }
978 tp->t_lflag &= ~EXTPROC;
979 }
980 return(0);
981 }
fef8985e
MD
982 error = (*linesw[tp->t_line].l_ioctl)(tp, ap->a_cmd, ap->a_data,
983 ap->a_fflag, ap->a_cred);
984263bc 984 if (error == ENOIOCTL)
fef8985e 985 error = ttioctl(tp, ap->a_cmd, ap->a_data, ap->a_fflag);
984263bc
MD
986 if (error == ENOIOCTL) {
987 if (pti->pt_flags & PF_UCNTL &&
fef8985e
MD
988 (ap->a_cmd & ~0xff) == UIOCCMD(0)) {
989 if (ap->a_cmd & 0xff) {
990 pti->pt_ucntl = (u_char)ap->a_cmd;
984263bc
MD
991 ptcwakeup(tp, FREAD);
992 }
993 return (0);
994 }
995 error = ENOTTY;
996 }
997 /*
998 * If external processing and packet mode send ioctl packet.
999 */
1000 if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
fef8985e 1001 switch(ap->a_cmd) {
984263bc
MD
1002 case TIOCSETA:
1003 case TIOCSETAW:
1004 case TIOCSETAF:
1005#ifdef COMPAT_43
1006 case TIOCSETP:
1007 case TIOCSETN:
1008#endif
1009#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1010 case TIOCSETC:
1011 case TIOCSLTC:
1012 case TIOCLBIS:
1013 case TIOCLBIC:
1014 case TIOCLSET:
1015#endif
1016 pti->pt_send |= TIOCPKT_IOCTL;
1017 ptcwakeup(tp, FREAD);
1018 default:
1019 break;
1020 }
1021 }
1022 stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
1023 && CCEQ(cc[VSTART], CTRL('q'));
1024 if (pti->pt_flags & PF_NOSTOP) {
1025 if (stop) {
1026 pti->pt_send &= ~TIOCPKT_NOSTOP;
1027 pti->pt_send |= TIOCPKT_DOSTOP;
1028 pti->pt_flags &= ~PF_NOSTOP;
1029 ptcwakeup(tp, FREAD);
1030 }
1031 } else {
1032 if (!stop) {
1033 pti->pt_send &= ~TIOCPKT_DOSTOP;
1034 pti->pt_send |= TIOCPKT_NOSTOP;
1035 pti->pt_flags |= PF_NOSTOP;
1036 ptcwakeup(tp, FREAD);
1037 }
1038 }
1039 return (error);
1040}
1041
1042
402ed7e1 1043static void ptc_drvinit (void *unused);
984263bc 1044
c578a286
AH
1045#ifdef UNIX98_PTYS
1046SYSCTL_INT(_kern, OID_AUTO, pty_debug, CTLFLAG_RW, &pty_debug_level,
1047 0, "Change pty debug level");
1048#endif
1049
984263bc 1050static void
c972a82f 1051ptc_drvinit(void *unused)
984263bc 1052{
cd29885a 1053 int i;
cd29885a 1054
c578a286
AH
1055#ifdef UNIX98_PTYS
1056 /*
1057 * Unix98 pty stuff.
1058 * Create the clonable base device.
1059 */
1060 make_autoclone_dev(&ptc_ops, &DEVFS_CLONE_BITMAP(pty), ptyclone,
1061 0, 0, 0666, "ptmx");
cd29885a 1062#endif
c578a286 1063
cd29885a
MD
1064 for (i = 0; i < 256; i++) {
1065 ptyinit(i);
1066 }
984263bc
MD
1067}
1068
1069SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL)