kernel - Remove D_KQFILTER flag
[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 = {
d4b8aec4 97 { "pts98", 0, D_TTY },
530c8749
AH
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 = {
d4b8aec4 108 { "ptc98", 0, D_TTY | D_MASTER },
530c8749
AH
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 120static struct dev_ops pts_ops = {
d4b8aec4 121 { "pts", CDEV_MAJOR_S, D_TTY },
fef8985e
MD
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 132static struct dev_ops ptc_ops = {
d4b8aec4 133 { "ptc", CDEV_MAJOR_C, D_TTY | D_MASTER },
fef8985e
MD
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;
2281ff2e
MD
148 int pt_refs; /* Structural references interlock S/MOPEN */
149 int pt_uminor;
5b22f1a7 150 struct kqinfo pt_kqr, pt_kqw;
984263bc
MD
151 u_char pt_send;
152 u_char pt_ucntl;
153 struct tty pt_tty;
b13267a5 154 cdev_t devs, devc;
984263bc
MD
155 struct prison *pt_prison;
156};
157
158#define PF_PKT 0x08 /* packet mode */
159#define PF_STOPPED 0x10 /* user told stopped */
160#define PF_REMOTE 0x20 /* remote and flow controlled input */
161#define PF_NOSTOP 0x40
162#define PF_UCNTL 0x80 /* user control mode */
163
c578a286
AH
164#define PF_UNIX98 0x01
165#define PF_SOPEN 0x02
166#define PF_MOPEN 0x04
2281ff2e 167#define PF_TERMINATED 0x08
c578a286
AH
168
169static int
170ptydebug(int level, char *fmt, ...)
171{
172 __va_list ap;
173
174 __va_start(ap, fmt);
175 if (level <= pty_debug_level)
176 kvprintf(fmt, ap);
177 __va_end(ap);
178
179 return 0;
180}
181
984263bc
MD
182/*
183 * This function creates and initializes a pts/ptc pair
184 *
185 * pts == /dev/tty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv]
186 * ptc == /dev/pty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv]
187 *
188 * XXX: define and add mapping of upper minor bits to allow more
189 * than 256 ptys.
190 */
191static void
c972a82f 192ptyinit(int n)
984263bc 193{
b13267a5 194 cdev_t devs, devc;
984263bc
MD
195 char *names = "pqrsPQRS";
196 struct pt_ioctl *pt;
197
198 /* For now we only map the lower 8 bits of the minor */
199 if (n & ~0xff)
200 return;
201
e7b4468c 202 pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO);
fef8985e 203 pt->devs = devs = make_dev(&pts_ops, n,
984263bc 204 0, 0, 0666, "tty%c%r", names[n / 32], n % 32);
fef8985e 205 pt->devc = devc = make_dev(&ptc_ops, n,
984263bc
MD
206 0, 0, 0666, "pty%c%r", names[n / 32], n % 32);
207
208 devs->si_drv1 = devc->si_drv1 = pt;
209 devs->si_tty = devc->si_tty = &pt->pt_tty;
4062d050
MD
210 devs->si_flags |= SI_OVERRIDE; /* uid, gid, perms from dev */
211 devc->si_flags |= SI_OVERRIDE; /* uid, gid, perms from dev */
984263bc 212 pt->pt_tty.t_dev = devs;
2281ff2e 213 pt->pt_uminor = n;
984263bc
MD
214 ttyregister(&pt->pt_tty);
215}
216
c578a286 217#ifdef UNIX98_PTYS
cd29885a
MD
218static int
219ptyclone(struct dev_clone_args *ap)
220{
221 int unit;
222 struct pt_ioctl *pt;
223
c578a286
AH
224 /*
225 * Limit the number of unix98 pty (slave) devices to 1000, as
226 * the utmp(5) format only allows for 8 bytes for the tty,
227 * "pts/XXX".
228 * If this limit is reached, we don't clone and return error
229 * to devfs.
230 */
231 unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(pty), 1000);
cd29885a 232
c578a286
AH
233 if (unit < 0) {
234 ap->a_dev = NULL;
cd29885a 235 return 1;
c578a286 236 }
cd29885a
MD
237
238 pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO);
cd29885a 239
2281ff2e
MD
240 pt->devc = make_only_dev(&ptc98_ops, unit,
241 ap->a_cred->cr_ruid,
242 0, 0600, "ptm/%d", unit);
243 pt->devs = make_dev(&pts98_ops, unit,
244 ap->a_cred->cr_ruid,
245 GID_TTY, 0620, "pts/%d", unit);
246 ap->a_dev = pt->devc;
c578a286
AH
247
248 pt->devs->si_flags |= SI_OVERRIDE; /* uid, gid, perms from dev */
249 pt->devc->si_flags |= SI_OVERRIDE; /* uid, gid, perms from dev */
cd29885a
MD
250
251 pt->devs->si_drv1 = pt->devc->si_drv1 = pt;
252 pt->devs->si_tty = pt->devc->si_tty = &pt->pt_tty;
253 pt->pt_tty.t_dev = pt->devs;
c578a286 254 pt->pt_flags2 |= PF_UNIX98;
2281ff2e 255 pt->pt_uminor = unit;
c578a286 256
cd29885a
MD
257 ttyregister(&pt->pt_tty);
258
259 return 0;
260}
5d40c1cd 261#endif
cd29885a 262
2281ff2e
MD
263/*
264 * pti_hold() prevents the pti from being destroyed due to a termination
265 * while a pt*open() is blocked.
266 *
267 * This function returns non-zero if we cannot hold due to a termination
268 * interlock.
269 */
270static int
271pti_hold(struct pt_ioctl *pti)
272{
273 if (pti->pt_flags2 & PF_TERMINATED)
274 return(ENXIO);
275 ++pti->pt_refs;
276 return(0);
277}
278
279/*
280 * pti_done() releases the reference and checks to see if both sides have
281 * been closed on a unix98 pty, allowing us to destroy the device and
282 * release resources.
283 *
284 * We do not release resources on non-unix98 ptys. Those are left
285 * statically allocated.
286 */
287static void
288pti_done(struct pt_ioctl *pti)
289{
290 if (--pti->pt_refs == 0) {
291#ifdef UNIX98_PTYS
292 cdev_t dev;
293 int uminor_no;
294
295 /*
296 * Only unix09 ptys are freed up
297 */
298 if ((pti->pt_flags2 & PF_UNIX98) == 0)
299 return;
300
301 /*
302 * Interlock open attempts against termination by setting
303 * PF_TERMINATED. This allows us to block while cleaning
304 * out the device infrastructure.
449728b3
MD
305 *
306 * Do not terminate the tty if it still has a session
307 * association.
2281ff2e 308 */
449728b3
MD
309 if ((pti->pt_flags2 & (PF_SOPEN|PF_MOPEN)) == 0 &&
310 pti->pt_tty.t_session == NULL) {
2281ff2e
MD
311 pti->pt_flags2 |= PF_TERMINATED;
312 uminor_no = pti->pt_uminor;
313
314 if ((dev = pti->devs) != NULL) {
315 dev->si_drv1 = NULL;
316 pti->devs = NULL;
317 destroy_dev(dev);
318 }
319 if ((dev = pti->devc) != NULL) {
320 dev->si_drv1 = NULL;
321 pti->devc = NULL;
322 destroy_dev(dev);
323 }
324 ttyunregister(&pti->pt_tty);
325 devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(pty),
326 uminor_no);
327 kfree(pti, M_PTY);
328 }
329#endif
330 }
331}
332
984263bc
MD
333/*ARGSUSED*/
334static int
fef8985e 335ptsopen(struct dev_open_args *ap)
984263bc 336{
b13267a5 337 cdev_t dev = ap->a_head.a_dev;
1fd87d54 338 struct tty *tp;
984263bc 339 int error;
984263bc
MD
340 struct pt_ioctl *pti;
341
2281ff2e
MD
342 /*
343 * The pti will already be assigned by the clone code or
344 * pre-created if a non-unix 98 pty. If si_drv1 is NULL
345 * we are somehow racing a unix98 termination.
346 */
347 if (dev->si_drv1 == NULL)
cd29885a 348 return(ENXIO);
984263bc 349 pti = dev->si_drv1;
2281ff2e
MD
350 if (pti_hold(pti))
351 return(ENXIO);
984263bc
MD
352 tp = dev->si_tty;
353 if ((tp->t_state & TS_ISOPEN) == 0) {
354 ttychars(tp); /* Set up default chars */
355 tp->t_iflag = TTYDEF_IFLAG;
356 tp->t_oflag = TTYDEF_OFLAG;
357 tp->t_lflag = TTYDEF_LFLAG;
358 tp->t_cflag = TTYDEF_CFLAG;
359 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
895c1f85 360 } else if ((tp->t_state & TS_XCLUDE) && priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) {
2281ff2e 361 pti_done(pti);
984263bc 362 return (EBUSY);
fef8985e 363 } else if (pti->pt_prison != ap->a_cred->cr_prison) {
2281ff2e 364 pti_done(pti);
984263bc
MD
365 return (EBUSY);
366 }
367 if (tp->t_oproc) /* Ctrlr still around. */
368 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
369 while ((tp->t_state & TS_CARR_ON) == 0) {
fef8985e 370 if (ap->a_oflags & FNONBLOCK)
984263bc 371 break;
377d4740 372 error = ttysleep(tp, TSA_CARR_ON(tp), PCATCH, "ptsopn", 0);
2281ff2e
MD
373 if (error) {
374 pti_done(pti);
984263bc 375 return (error);
2281ff2e 376 }
984263bc 377 }
41cf5266 378 tp->t_state &= ~TS_ZOMBIE;
984263bc
MD
379 error = (*linesw[tp->t_line].l_open)(dev, tp);
380 if (error == 0)
381 ptcwakeup(tp, FREAD|FWRITE);
cd29885a 382
c578a286
AH
383#ifdef UNIX98_PTYS
384 /*
385 * Unix98 pty stuff.
386 * On open of the slave, we set the corresponding flag in the common
387 * struct.
388 */
389 ptydebug(1, "ptsopen=%s | unix98? %s\n", dev->si_name,
390 (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
391
2281ff2e 392 if (error == 0 && (pti->pt_flags2 & PF_UNIX98)) {
c578a286 393 pti->pt_flags2 |= PF_SOPEN;
cd29885a
MD
394 }
395#endif
2281ff2e 396 pti_done(pti);
cd29885a 397
984263bc
MD
398 return (error);
399}
400
401static int
fef8985e 402ptsclose(struct dev_close_args *ap)
984263bc 403{
b13267a5 404 cdev_t dev = ap->a_head.a_dev;
1fd87d54 405 struct tty *tp;
c578a286 406 struct pt_ioctl *pti = dev->si_drv1;
984263bc 407 int err;
c578a286 408
2281ff2e
MD
409 if (pti_hold(pti))
410 panic("ptsclose on terminated pti");
c578a286
AH
411 tp = dev->si_tty;
412 err = (*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
413 ptsstop(tp, FREAD|FWRITE);
847ff8ce
SG
414 (void) ttyclose(tp); /* clears t_state */
415 tp->t_state |= TS_ZOMBIE;
c578a286
AH
416
417#ifdef UNIX98_PTYS
418 /*
419 * Unix98 pty stuff.
420 * On close of the slave, we unset the corresponding flag, and if the master
421 * isn't open anymore, we destroy the slave and unset the unit.
422 */
423 ptydebug(1, "ptsclose=%s | unix98? %s\n", dev->si_name,
424 (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
425
426 if (pti->pt_flags2 & PF_UNIX98) {
427 pti->pt_flags2 &= ~PF_SOPEN;
428 KKASSERT((pti->pt_flags2 & PF_SOPEN) == 0);
429 ptydebug(1, "master open? %s\n",
430 (pti->pt_flags2 & PF_MOPEN)?"yes":"no");
cd29885a
MD
431 }
432#endif
2281ff2e 433 pti_done(pti);
984263bc
MD
434 return (err);
435}
436
437static int
fef8985e 438ptsread(struct dev_read_args *ap)
984263bc 439{
b13267a5 440 cdev_t dev = ap->a_head.a_dev;
984263bc 441 struct proc *p = curproc;
1fd87d54
RG
442 struct tty *tp = dev->si_tty;
443 struct pt_ioctl *pti = dev->si_drv1;
08f2f1bb
SS
444 struct lwp *lp;
445
984263bc
MD
446 int error = 0;
447
08f2f1bb
SS
448 lp = curthread->td_lwp;
449
984263bc
MD
450again:
451 if (pti->pt_flags & PF_REMOTE) {
452 while (isbackground(p, tp)) {
453 if (SIGISMEMBER(p->p_sigignore, SIGTTIN) ||
08f2f1bb 454 SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) ||
984263bc
MD
455 p->p_pgrp->pg_jobc == 0 || p->p_flag & P_PPWAIT)
456 return (EIO);
457 pgsignal(p->p_pgrp, SIGTTIN, 1);
377d4740 458 error = ttysleep(tp, &lbolt, PCATCH, "ptsbg", 0);
984263bc
MD
459 if (error)
460 return (error);
461 }
462 if (tp->t_canq.c_cc == 0) {
fef8985e 463 if (ap->a_ioflag & IO_NDELAY)
984263bc 464 return (EWOULDBLOCK);
377d4740 465 error = ttysleep(tp, TSA_PTS_READ(tp), PCATCH,
984263bc
MD
466 "ptsin", 0);
467 if (error)
468 return (error);
469 goto again;
470 }
fef8985e 471 while (tp->t_canq.c_cc > 1 && ap->a_uio->uio_resid > 0)
0ced1954 472 if (ureadc(clist_getc(&tp->t_canq), ap->a_uio) < 0) {
984263bc
MD
473 error = EFAULT;
474 break;
475 }
476 if (tp->t_canq.c_cc == 1)
0ced1954 477 clist_getc(&tp->t_canq);
984263bc
MD
478 if (tp->t_canq.c_cc)
479 return (error);
480 } else
481 if (tp->t_oproc)
fef8985e 482 error = (*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag);
984263bc
MD
483 ptcwakeup(tp, FWRITE);
484 return (error);
485}
486
487/*
488 * Write to pseudo-tty.
489 * Wakeups of controlling tty will happen
490 * indirectly, when tty driver calls ptsstart.
491 */
492static int
fef8985e 493ptswrite(struct dev_write_args *ap)
984263bc 494{
b13267a5 495 cdev_t dev = ap->a_head.a_dev;
1fd87d54 496 struct tty *tp;
984263bc
MD
497
498 tp = dev->si_tty;
499 if (tp->t_oproc == 0)
500 return (EIO);
fef8985e 501 return ((*linesw[tp->t_line].l_write)(tp, ap->a_uio, ap->a_ioflag));
984263bc
MD
502}
503
504/*
505 * Start output on pseudo-tty.
506 * Wake up process selecting or sleeping for input from controlling tty.
507 */
508static void
c972a82f 509ptsstart(struct tty *tp)
984263bc 510{
1fd87d54 511 struct pt_ioctl *pti = tp->t_dev->si_drv1;
984263bc
MD
512
513 if (tp->t_state & TS_TTSTOP)
514 return;
1c375cd1
MD
515 if (pti) {
516 if (pti->pt_flags & PF_STOPPED) {
517 pti->pt_flags &= ~PF_STOPPED;
518 pti->pt_send = TIOCPKT_START;
519 }
984263bc
MD
520 }
521 ptcwakeup(tp, FREAD);
522}
523
524static void
c972a82f 525ptcwakeup(struct tty *tp, int flag)
984263bc 526{
984263bc 527 if (flag & FREAD) {
984263bc 528 wakeup(TSA_PTC_READ(tp));
5b22f1a7 529 KNOTE(&tp->t_rkq.ki_note, 0);
984263bc
MD
530 }
531 if (flag & FWRITE) {
984263bc 532 wakeup(TSA_PTC_WRITE(tp));
5b22f1a7 533 KNOTE(&tp->t_wkq.ki_note, 0);
984263bc
MD
534 }
535}
536
537static int
fef8985e 538ptcopen(struct dev_open_args *ap)
984263bc 539{
b13267a5 540 cdev_t dev = ap->a_head.a_dev;
1fd87d54 541 struct tty *tp;
984263bc
MD
542 struct pt_ioctl *pti;
543
2281ff2e
MD
544 /*
545 * The pti will already be assigned by the clone code or
546 * pre-created if a non-unix 98 pty. If si_drv1 is NULL
547 * we are somehow racing a unix98 termination.
548 */
549 if (dev->si_drv1 == NULL)
984263bc 550 return(ENXIO);
4062d050 551 pti = dev->si_drv1;
2281ff2e
MD
552 if (pti_hold(pti))
553 return(ENXIO);
554 if (pti->pt_prison && pti->pt_prison != ap->a_cred->cr_prison) {
555 pti_done(pti);
4062d050 556 return(EBUSY);
2281ff2e 557 }
984263bc 558 tp = dev->si_tty;
2281ff2e
MD
559 if (tp->t_oproc) {
560 pti_done(pti);
984263bc 561 return (EIO);
2281ff2e 562 }
984263bc
MD
563 tp->t_oproc = ptsstart;
564 tp->t_stop = ptsstop;
565 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
566 tp->t_lflag &= ~EXTPROC;
fef8985e 567 pti->pt_prison = ap->a_cred->cr_prison;
984263bc
MD
568 pti->pt_flags = 0;
569 pti->pt_send = 0;
570 pti->pt_ucntl = 0;
4062d050 571
cd65363e 572 pti->devs->si_uid = ap->a_cred->cr_uid;
4062d050
MD
573 pti->devs->si_gid = 0;
574 pti->devs->si_perms = 0600;
575 pti->devc->si_uid = ap->a_cred->cr_uid;
576 pti->devc->si_gid = 0;
577 pti->devc->si_perms = 0600;
578
c578a286
AH
579#ifdef UNIX98_PTYS
580 /*
581 * Unix98 pty stuff.
582 * On open of the master, we set the corresponding flag in the common
583 * struct.
584 */
585 ptydebug(1, "ptcopen=%s (master) | unix98? %s\n", dev->si_name,
586 (pti->pt_flags2 & PF_UNIX98)?"yes":"no");
587
588 if (pti->pt_flags2 & PF_UNIX98) {
589 pti->pt_flags2 |= PF_MOPEN;
590 }
591#endif
2281ff2e 592 pti_done(pti);
c578a286 593
984263bc
MD
594 return (0);
595}
596
597static int
fef8985e 598ptcclose(struct dev_close_args *ap)
984263bc 599{
b13267a5 600 cdev_t dev = ap->a_head.a_dev;
1fd87d54 601 struct tty *tp;
c578a286 602 struct pt_ioctl *pti = dev->si_drv1;
2281ff2e
MD
603
604 if (pti_hold(pti))
605 panic("ptcclose on terminated pti");
984263bc
MD
606
607 tp = dev->si_tty;
608 (void)(*linesw[tp->t_line].l_modem)(tp, 0);
609
610 /*
611 * XXX MDMBUF makes no sense for ptys but would inhibit the above
612 * l_modem(). CLOCAL makes sense but isn't supported. Special
613 * l_modem()s that ignore carrier drop make no sense for ptys but
614 * may be in use because other parts of the line discipline make
615 * sense for ptys. Recover by doing everything that a normal
616 * ttymodem() would have done except for sending a SIGHUP.
617 */
618 if (tp->t_state & TS_ISOPEN) {
619 tp->t_state &= ~(TS_CARR_ON | TS_CONNECTED);
620 tp->t_state |= TS_ZOMBIE;
621 ttyflush(tp, FREAD | FWRITE);
622 }
984263bc 623 tp->t_oproc = 0; /* mark closed */
4062d050 624
2281ff2e
MD
625#ifdef UNIX98_PTYS
626 /*
627 * Unix98 pty stuff.
628 * On close of the master, we unset the corresponding flag in the common
629 * struct asap.
630 */
631 pti->pt_flags2 &= ~PF_MOPEN;
632#endif
633
4062d050
MD
634 pti->pt_prison = NULL;
635 pti->devs->si_uid = 0;
636 pti->devs->si_gid = 0;
637 pti->devs->si_perms = 0666;
638 pti->devc->si_uid = 0;
639 pti->devc->si_gid = 0;
640 pti->devc->si_perms = 0666;
641
2281ff2e 642 pti_done(pti);
984263bc
MD
643 return (0);
644}
645
646static int
fef8985e 647ptcread(struct dev_read_args *ap)
984263bc 648{
b13267a5 649 cdev_t dev = ap->a_head.a_dev;
1fd87d54 650 struct tty *tp = dev->si_tty;
984263bc
MD
651 struct pt_ioctl *pti = dev->si_drv1;
652 char buf[BUFSIZ];
653 int error = 0, cc;
654
655 /*
656 * We want to block until the slave
657 * is open, and there's something to read;
658 * but if we lost the slave or we're NBIO,
659 * then return the appropriate error instead.
660 */
661 for (;;) {
662 if (tp->t_state&TS_ISOPEN) {
663 if (pti->pt_flags&PF_PKT && pti->pt_send) {
fef8985e 664 error = ureadc((int)pti->pt_send, ap->a_uio);
984263bc
MD
665 if (error)
666 return (error);
667 if (pti->pt_send & TIOCPKT_IOCTL) {
e54488bb
MD
668 cc = (int)szmin(ap->a_uio->uio_resid,
669 sizeof(tp->t_termios));
984263bc 670 uiomove((caddr_t)&tp->t_termios, cc,
fef8985e 671 ap->a_uio);
984263bc
MD
672 }
673 pti->pt_send = 0;
674 return (0);
675 }
676 if (pti->pt_flags&PF_UCNTL && pti->pt_ucntl) {
fef8985e 677 error = ureadc((int)pti->pt_ucntl, ap->a_uio);
984263bc
MD
678 if (error)
679 return (error);
680 pti->pt_ucntl = 0;
681 return (0);
682 }
683 if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
684 break;
685 }
686 if ((tp->t_state & TS_CONNECTED) == 0)
687 return (0); /* EOF */
fef8985e 688 if (ap->a_ioflag & IO_NDELAY)
984263bc 689 return (EWOULDBLOCK);
377d4740 690 error = tsleep(TSA_PTC_READ(tp), PCATCH, "ptcin", 0);
984263bc
MD
691 if (error)
692 return (error);
693 }
694 if (pti->pt_flags & (PF_PKT|PF_UCNTL))
fef8985e
MD
695 error = ureadc(0, ap->a_uio);
696 while (ap->a_uio->uio_resid > 0 && error == 0) {
e54488bb
MD
697 cc = q_to_b(&tp->t_outq, buf,
698 (int)szmin(ap->a_uio->uio_resid, BUFSIZ));
984263bc
MD
699 if (cc <= 0)
700 break;
e54488bb 701 error = uiomove(buf, (size_t)cc, ap->a_uio);
984263bc
MD
702 }
703 ttwwakeup(tp);
704 return (error);
705}
706
707static void
c972a82f 708ptsstop(struct tty *tp, int flush)
984263bc
MD
709{
710 struct pt_ioctl *pti = tp->t_dev->si_drv1;
711 int flag;
712
713 /* note: FLUSHREAD and FLUSHWRITE already ok */
1c375cd1
MD
714 if (pti) {
715 if (flush == 0) {
716 flush = TIOCPKT_STOP;
717 pti->pt_flags |= PF_STOPPED;
718 } else {
719 pti->pt_flags &= ~PF_STOPPED;
720 }
721 pti->pt_send |= flush;
722 /* change of perspective */
723 }
984263bc
MD
724 flag = 0;
725 if (flush & FREAD)
726 flag |= FWRITE;
727 if (flush & FWRITE)
728 flag |= FREAD;
729 ptcwakeup(tp, flag);
730}
731
8acdf1cf
MD
732/*
733 * kqueue ops for pseudo-terminals.
734 */
735static struct filterops ptcread_filtops =
4c91dbc9 736 { FILTEROP_ISFD, NULL, filt_ptcrdetach, filt_ptcread };
8acdf1cf 737static struct filterops ptcwrite_filtops =
4c91dbc9 738 { FILTEROP_ISFD, NULL, filt_ptcwdetach, filt_ptcwrite };
8acdf1cf
MD
739
740static int
741ptckqfilter(struct dev_kqfilter_args *ap)
742{
743 cdev_t dev = ap->a_head.a_dev;
744 struct knote *kn = ap->a_kn;
745 struct tty *tp = dev->si_tty;
746 struct klist *klist;
747
748 ap->a_result = 0;
749 switch (kn->kn_filter) {
750 case EVFILT_READ:
5b22f1a7 751 klist = &tp->t_rkq.ki_note;
8acdf1cf
MD
752 kn->kn_fop = &ptcread_filtops;
753 break;
754 case EVFILT_WRITE:
5b22f1a7 755 klist = &tp->t_wkq.ki_note;
8acdf1cf
MD
756 kn->kn_fop = &ptcwrite_filtops;
757 break;
758 default:
b287d649 759 ap->a_result = EOPNOTSUPP;
8acdf1cf
MD
760 return (0);
761 }
762
763 kn->kn_hook = (caddr_t)dev;
5b22f1a7 764 knote_insert(klist, kn);
8acdf1cf
MD
765 return (0);
766}
767
768static int
769filt_ptcread (struct knote *kn, long hint)
770{
771 struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
772 struct pt_ioctl *pti = ((cdev_t)kn->kn_hook)->si_drv1;
773
847ff8ce
SG
774 if (tp->t_state & TS_ZOMBIE) {
775 kn->kn_flags |= EV_EOF;
776 return (1);
777 }
778
8acdf1cf
MD
779 if ((tp->t_state & TS_ISOPEN) &&
780 ((tp->t_outq.c_cc && (tp->t_state & TS_TTSTOP) == 0) ||
781 ((pti->pt_flags & PF_PKT) && pti->pt_send) ||
782 ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))) {
783 kn->kn_data = tp->t_outq.c_cc;
784 return(1);
785 } else {
786 return(0);
787 }
788}
789
790static int
791filt_ptcwrite (struct knote *kn, long hint)
792{
793 struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
794 struct pt_ioctl *pti = ((cdev_t)kn->kn_hook)->si_drv1;
795
847ff8ce
SG
796 if (tp->t_state & TS_ZOMBIE) {
797 kn->kn_flags |= EV_EOF;
798 return (1);
799 }
800
8acdf1cf
MD
801 if (tp->t_state & TS_ISOPEN &&
802 ((pti->pt_flags & PF_REMOTE) ?
803 (tp->t_canq.c_cc == 0) :
804 ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) ||
805 (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON))))) {
806 kn->kn_data = tp->t_canq.c_cc + tp->t_rawq.c_cc;
807 return(1);
808 } else {
809 return(0);
810 }
811}
812
813static void
814filt_ptcrdetach (struct knote *kn)
815{
816 struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
817
5b22f1a7 818 knote_remove(&tp->t_rkq.ki_note, kn);
8acdf1cf
MD
819}
820
821static void
822filt_ptcwdetach (struct knote *kn)
823{
824 struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
825
5b22f1a7 826 knote_remove(&tp->t_wkq.ki_note, kn);
8acdf1cf
MD
827}
828
829/*
830 * I/O ops
831 */
984263bc 832static int
fef8985e 833ptcwrite(struct dev_write_args *ap)
984263bc 834{
b13267a5 835 cdev_t dev = ap->a_head.a_dev;
1fd87d54
RG
836 struct tty *tp = dev->si_tty;
837 u_char *cp = 0;
838 int cc = 0;
984263bc
MD
839 u_char locbuf[BUFSIZ];
840 int cnt = 0;
841 struct pt_ioctl *pti = dev->si_drv1;
842 int error = 0;
843
844again:
845 if ((tp->t_state&TS_ISOPEN) == 0)
846 goto block;
847 if (pti->pt_flags & PF_REMOTE) {
848 if (tp->t_canq.c_cc)
849 goto block;
fef8985e 850 while ((ap->a_uio->uio_resid > 0 || cc > 0) &&
984263bc
MD
851 tp->t_canq.c_cc < TTYHOG - 1) {
852 if (cc == 0) {
e54488bb
MD
853 cc = (int)szmin(ap->a_uio->uio_resid, BUFSIZ);
854 cc = imin(cc, TTYHOG - 1 - tp->t_canq.c_cc);
984263bc 855 cp = locbuf;
e54488bb 856 error = uiomove(cp, (size_t)cc, ap->a_uio);
984263bc
MD
857 if (error)
858 return (error);
859 /* check again for safety */
860 if ((tp->t_state & TS_ISOPEN) == 0) {
861 /* adjust as usual */
fef8985e 862 ap->a_uio->uio_resid += cc;
984263bc
MD
863 return (EIO);
864 }
865 }
866 if (cc > 0) {
867 cc = b_to_q((char *)cp, cc, &tp->t_canq);
868 /*
869 * XXX we don't guarantee that the canq size
870 * is >= TTYHOG, so the above b_to_q() may
871 * leave some bytes uncopied. However, space
872 * is guaranteed for the null terminator if
873 * we don't fail here since (TTYHOG - 1) is
874 * not a multiple of CBSIZE.
875 */
876 if (cc > 0)
877 break;
878 }
879 }
880 /* adjust for data copied in but not written */
fef8985e 881 ap->a_uio->uio_resid += cc;
0ced1954 882 clist_putc(0, &tp->t_canq);
984263bc
MD
883 ttwakeup(tp);
884 wakeup(TSA_PTS_READ(tp));
885 return (0);
886 }
fef8985e 887 while (ap->a_uio->uio_resid > 0 || cc > 0) {
984263bc 888 if (cc == 0) {
e54488bb 889 cc = (int)szmin(ap->a_uio->uio_resid, BUFSIZ);
984263bc 890 cp = locbuf;
e54488bb 891 error = uiomove(cp, (size_t)cc, ap->a_uio);
984263bc
MD
892 if (error)
893 return (error);
894 /* check again for safety */
895 if ((tp->t_state & TS_ISOPEN) == 0) {
896 /* adjust for data copied in but not written */
fef8985e 897 ap->a_uio->uio_resid += cc;
984263bc
MD
898 return (EIO);
899 }
900 }
901 while (cc > 0) {
902 if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
903 (tp->t_canq.c_cc > 0 || !(tp->t_lflag&ICANON))) {
904 wakeup(TSA_HUP_OR_INPUT(tp));
905 goto block;
906 }
907 (*linesw[tp->t_line].l_rint)(*cp++, tp);
908 cnt++;
909 cc--;
910 }
911 cc = 0;
912 }
913 return (0);
914block:
915 /*
916 * Come here to wait for slave to open, for space
917 * in outq, or space in rawq, or an empty canq.
918 */
919 if ((tp->t_state & TS_CONNECTED) == 0) {
920 /* adjust for data copied in but not written */
fef8985e 921 ap->a_uio->uio_resid += cc;
984263bc
MD
922 return (EIO);
923 }
fef8985e 924 if (ap->a_ioflag & IO_NDELAY) {
984263bc 925 /* adjust for data copied in but not written */
fef8985e 926 ap->a_uio->uio_resid += cc;
984263bc
MD
927 if (cnt == 0)
928 return (EWOULDBLOCK);
929 return (0);
930 }
377d4740 931 error = tsleep(TSA_PTC_WRITE(tp), PCATCH, "ptcout", 0);
984263bc
MD
932 if (error) {
933 /* adjust for data copied in but not written */
fef8985e 934 ap->a_uio->uio_resid += cc;
984263bc
MD
935 return (error);
936 }
937 goto again;
938}
939
940/*ARGSUSED*/
941static int
fef8985e 942ptyioctl(struct dev_ioctl_args *ap)
984263bc 943{
b13267a5 944 cdev_t dev = ap->a_head.a_dev;
1fd87d54
RG
945 struct tty *tp = dev->si_tty;
946 struct pt_ioctl *pti = dev->si_drv1;
947 u_char *cc = tp->t_cc;
984263bc
MD
948 int stop, error;
949
335dda38 950 if (dev_dflags(dev) & D_MASTER) {
fef8985e 951 switch (ap->a_cmd) {
984263bc
MD
952
953 case TIOCGPGRP:
954 /*
955 * We avoid calling ttioctl on the controller since,
956 * in that case, tp must be the controlling terminal.
957 */
fef8985e 958 *(int *)ap->a_data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
984263bc
MD
959 return (0);
960
961 case TIOCPKT:
fef8985e 962 if (*(int *)ap->a_data) {
984263bc
MD
963 if (pti->pt_flags & PF_UCNTL)
964 return (EINVAL);
965 pti->pt_flags |= PF_PKT;
966 } else
967 pti->pt_flags &= ~PF_PKT;
968 return (0);
969
970 case TIOCUCNTL:
fef8985e 971 if (*(int *)ap->a_data) {
984263bc
MD
972 if (pti->pt_flags & PF_PKT)
973 return (EINVAL);
974 pti->pt_flags |= PF_UCNTL;
975 } else
976 pti->pt_flags &= ~PF_UCNTL;
977 return (0);
978
979 case TIOCREMOTE:
fef8985e 980 if (*(int *)ap->a_data)
984263bc
MD
981 pti->pt_flags |= PF_REMOTE;
982 else
983 pti->pt_flags &= ~PF_REMOTE;
984 ttyflush(tp, FREAD|FWRITE);
985 return (0);
c578a286
AH
986
987 case TIOCISPTMASTER:
988 if ((pti->pt_flags2 & PF_UNIX98) && (pti->devc == dev))
989 return (0);
990 else
991 return (EINVAL);
984263bc
MD
992 }
993
994 /*
995 * The rest of the ioctls shouldn't be called until
996 * the slave is open.
997 */
998 if ((tp->t_state & TS_ISOPEN) == 0)
999 return (EAGAIN);
1000
fef8985e 1001 switch (ap->a_cmd) {
984263bc
MD
1002#ifdef COMPAT_43
1003 case TIOCSETP:
1004 case TIOCSETN:
1005#endif
1006 case TIOCSETD:
1007 case TIOCSETA:
1008 case TIOCSETAW:
1009 case TIOCSETAF:
1010 /*
1011 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
1012 * ttywflush(tp) will hang if there are characters in
1013 * the outq.
1014 */
1015 ndflush(&tp->t_outq, tp->t_outq.c_cc);
1016 break;
1017
1018 case TIOCSIG:
fef8985e
MD
1019 if (*(unsigned int *)ap->a_data >= NSIG ||
1020 *(unsigned int *)ap->a_data == 0)
984263bc
MD
1021 return(EINVAL);
1022 if ((tp->t_lflag&NOFLSH) == 0)
1023 ttyflush(tp, FREAD|FWRITE);
fef8985e
MD
1024 pgsignal(tp->t_pgrp, *(unsigned int *)ap->a_data, 1);
1025 if ((*(unsigned int *)ap->a_data == SIGINFO) &&
984263bc
MD
1026 ((tp->t_lflag&NOKERNINFO) == 0))
1027 ttyinfo(tp);
1028 return(0);
1029 }
1030 }
fef8985e 1031 if (ap->a_cmd == TIOCEXT) {
984263bc
MD
1032 /*
1033 * When the EXTPROC bit is being toggled, we need
1034 * to send an TIOCPKT_IOCTL if the packet driver
1035 * is turned on.
1036 */
fef8985e 1037 if (*(int *)ap->a_data) {
984263bc
MD
1038 if (pti->pt_flags & PF_PKT) {
1039 pti->pt_send |= TIOCPKT_IOCTL;
1040 ptcwakeup(tp, FREAD);
1041 }
1042 tp->t_lflag |= EXTPROC;
1043 } else {
1044 if ((tp->t_lflag & EXTPROC) &&
1045 (pti->pt_flags & PF_PKT)) {
1046 pti->pt_send |= TIOCPKT_IOCTL;
1047 ptcwakeup(tp, FREAD);
1048 }
1049 tp->t_lflag &= ~EXTPROC;
1050 }
1051 return(0);
1052 }
fef8985e
MD
1053 error = (*linesw[tp->t_line].l_ioctl)(tp, ap->a_cmd, ap->a_data,
1054 ap->a_fflag, ap->a_cred);
984263bc 1055 if (error == ENOIOCTL)
fef8985e 1056 error = ttioctl(tp, ap->a_cmd, ap->a_data, ap->a_fflag);
984263bc
MD
1057 if (error == ENOIOCTL) {
1058 if (pti->pt_flags & PF_UCNTL &&
fef8985e
MD
1059 (ap->a_cmd & ~0xff) == UIOCCMD(0)) {
1060 if (ap->a_cmd & 0xff) {
1061 pti->pt_ucntl = (u_char)ap->a_cmd;
984263bc
MD
1062 ptcwakeup(tp, FREAD);
1063 }
1064 return (0);
1065 }
1066 error = ENOTTY;
1067 }
1068 /*
1069 * If external processing and packet mode send ioctl packet.
1070 */
1071 if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
fef8985e 1072 switch(ap->a_cmd) {
984263bc
MD
1073 case TIOCSETA:
1074 case TIOCSETAW:
1075 case TIOCSETAF:
1076#ifdef COMPAT_43
1077 case TIOCSETP:
1078 case TIOCSETN:
1079#endif
1080#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1081 case TIOCSETC:
1082 case TIOCSLTC:
1083 case TIOCLBIS:
1084 case TIOCLBIC:
1085 case TIOCLSET:
1086#endif
1087 pti->pt_send |= TIOCPKT_IOCTL;
1088 ptcwakeup(tp, FREAD);
1089 default:
1090 break;
1091 }
1092 }
1093 stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
1094 && CCEQ(cc[VSTART], CTRL('q'));
1095 if (pti->pt_flags & PF_NOSTOP) {
1096 if (stop) {
1097 pti->pt_send &= ~TIOCPKT_NOSTOP;
1098 pti->pt_send |= TIOCPKT_DOSTOP;
1099 pti->pt_flags &= ~PF_NOSTOP;
1100 ptcwakeup(tp, FREAD);
1101 }
1102 } else {
1103 if (!stop) {
1104 pti->pt_send &= ~TIOCPKT_DOSTOP;
1105 pti->pt_send |= TIOCPKT_NOSTOP;
1106 pti->pt_flags |= PF_NOSTOP;
1107 ptcwakeup(tp, FREAD);
1108 }
1109 }
1110 return (error);
1111}
1112
1113
402ed7e1 1114static void ptc_drvinit (void *unused);
984263bc 1115
c578a286
AH
1116#ifdef UNIX98_PTYS
1117SYSCTL_INT(_kern, OID_AUTO, pty_debug, CTLFLAG_RW, &pty_debug_level,
1118 0, "Change pty debug level");
1119#endif
1120
984263bc 1121static void
c972a82f 1122ptc_drvinit(void *unused)
984263bc 1123{
cd29885a 1124 int i;
cd29885a 1125
c578a286
AH
1126#ifdef UNIX98_PTYS
1127 /*
1128 * Unix98 pty stuff.
1129 * Create the clonable base device.
1130 */
1131 make_autoclone_dev(&ptc_ops, &DEVFS_CLONE_BITMAP(pty), ptyclone,
1132 0, 0, 0666, "ptmx");
cd29885a 1133#endif
c578a286 1134
cd29885a
MD
1135 for (i = 0; i < 256; i++) {
1136 ptyinit(i);
1137 }
984263bc
MD
1138}
1139
1140SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL)