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
--- 16 unchanged lines hidden (view full) ---
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)tty_pty.c 8.4 (Berkeley) 2/20/95
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sys/kern/tty_pty.c 130262 2004-06-09 10:16:14Z phk $");
34
35/*
36 * Pseudo-teletype Driver
37 * (Actually two drivers, requiring two entries in 'cdevsw')
38 */
39#include "opt_compat.h"
40#include "opt_tty.h"
41#include <sys/param.h>
--- 114 unchanged lines hidden (view full) ---
156 devs->si_drv1 = devc->si_drv1 = pt;
157 devs->si_tty = devc->si_tty = pt->pt_tty;
158 pt->pt_tty->t_dev = devs;
159 return (devc);
160}
161
162/*ARGSUSED*/
163static int
164ptsopen(dev_t dev, int flag, int devtype, struct thread *td)
165{
166 struct tty *tp;
167 int error;
168 struct pt_ioctl *pti;
169
170 if (!dev->si_drv1)
171 return(ENXIO);
172 pti = dev->si_drv1;
--- 21 unchanged lines hidden (view full) ---
194 }
195 error = ttyld_open(tp, dev);
196 if (error == 0)
197 ptcwakeup(tp, FREAD|FWRITE);
198 return (error);
199}
200
201static int
202ptsclose(dev_t dev, int flag, int mode, struct thread *td)
203{
204 struct tty *tp;
205 int err;
206
207 tp = dev->si_tty;
208 err = ttyld_close(tp, flag);
209 (void) ttyclose(tp);
210 return (err);
211}
212
213static int
214ptsread(dev_t dev, struct uio *uio, int flag)
215{
216 struct thread *td = curthread;
217 struct proc *p = td->td_proc;
218 struct tty *tp = dev->si_tty;
219 struct pt_ioctl *pti = dev->si_drv1;
220 struct pgrp *pg;
221 int error = 0;
222
--- 46 unchanged lines hidden (view full) ---
269}
270
271/*
272 * Write to pseudo-tty.
273 * Wakeups of controlling tty will happen
274 * indirectly, when tty driver calls ptsstart.
275 */
276static int
277ptswrite(dev_t dev, struct uio *uio, int flag)
278{
279 struct tty *tp;
280
281 tp = dev->si_tty;
282 if (tp->t_oproc == 0)
283 return (EIO);
284 return (ttyld_write(tp, uio, flag));
285}
286
287/*
288 * Start output on pseudo-tty.
289 * Wake up process selecting or sleeping for input from controlling tty.
290 */
291static void
292ptsstart(struct tty *tp)
293{
294 struct pt_ioctl *pti = tp->t_dev->si_drv1;
295
296 if (tp->t_state & TS_TTSTOP)
297 return;
298 if (pti->pt_flags & PF_STOPPED) {
299 pti->pt_flags &= ~PF_STOPPED;
300 pti->pt_send = TIOCPKT_START;
301 }
302 ptcwakeup(tp, FREAD);
303}
304
305static void
306ptcwakeup(struct tty *tp, int flag)
307{
308 struct pt_ioctl *pti = tp->t_dev->si_drv1;
309
310 if (flag & FREAD) {
311 selwakeuppri(&pti->pt_selr, TTIPRI);
312 wakeup(TSA_PTC_READ(tp));
313 }
314 if (flag & FWRITE) {
315 selwakeuppri(&pti->pt_selw, TTOPRI);
316 wakeup(TSA_PTC_WRITE(tp));
317 }
318}
319
320static int
321ptcopen(dev_t dev, int flag, int devtype, struct thread *td)
322{
323 struct tty *tp;
324 struct pt_ioctl *pti;
325
326 if (!dev->si_drv1)
327 ptyinit(dev);
328 if (!dev->si_drv1)
329 return(ENXIO);
--- 9 unchanged lines hidden (view full) ---
339 pti->pt_prison = td->td_ucred->cr_prison;
340 pti->pt_flags = 0;
341 pti->pt_send = 0;
342 pti->pt_ucntl = 0;
343 return (0);
344}
345
346static int
347ptcclose(dev_t dev, int flags, int fmt, struct thread *td)
348{
349 struct tty *tp;
350
351 tp = dev->si_tty;
352 (void)ttyld_modem(tp, 0);
353
354 /*
355 * XXX MDMBUF makes no sense for ptys but would inhibit the above
--- 9 unchanged lines hidden (view full) ---
365 ttyflush(tp, FREAD | FWRITE);
366 }
367
368 tp->t_oproc = 0; /* mark closed */
369 return (0);
370}
371
372static int
373ptcread(dev_t dev, struct uio *uio, int flag)
374{
375 struct tty *tp = dev->si_tty;
376 struct pt_ioctl *pti = dev->si_drv1;
377 char buf[BUFSIZ];
378 int error = 0, cc;
379
380 /*
381 * We want to block until the slave
--- 41 unchanged lines hidden (view full) ---
423 break;
424 error = uiomove(buf, cc, uio);
425 }
426 ttwwakeup(tp);
427 return (error);
428}
429
430static void
431ptsstop(struct tty *tp, int flush)
432{
433 struct pt_ioctl *pti = tp->t_dev->si_drv1;
434 int flag;
435
436 /* note: FLUSHREAD and FLUSHWRITE already ok */
437 if (flush == 0) {
438 flush = TIOCPKT_STOP;
439 pti->pt_flags |= PF_STOPPED;
--- 5 unchanged lines hidden (view full) ---
445 if (flush & FREAD)
446 flag |= FWRITE;
447 if (flush & FWRITE)
448 flag |= FREAD;
449 ptcwakeup(tp, flag);
450}
451
452static int
453ptcpoll(dev_t dev, int events, struct thread *td)
454{
455 struct tty *tp = dev->si_tty;
456 struct pt_ioctl *pti = dev->si_drv1;
457 int revents = 0;
458 int s;
459
460 if ((tp->t_state & TS_CONNECTED) == 0)
461 return (events &
--- 31 unchanged lines hidden (view full) ---
493 selrecord(td, &pti->pt_selw);
494 }
495 splx(s);
496
497 return (revents);
498}
499
500static int
501ptcwrite(dev_t dev, struct uio *uio, int flag)
502{
503 struct tty *tp = dev->si_tty;
504 u_char *cp = 0;
505 int cc = 0;
506 u_char locbuf[BUFSIZ];
507 int cnt = 0;
508 struct pt_ioctl *pti = dev->si_drv1;
509 int error = 0;
--- 91 unchanged lines hidden (view full) ---
601 uio->uio_resid += cc;
602 return (error);
603 }
604 goto again;
605}
606
607/*ARGSUSED*/
608static int
609ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
610{
611 struct tty *tp = dev->si_tty;
612 struct pt_ioctl *pti = dev->si_drv1;
613 u_char *cc = tp->t_cc;
614 int stop, error;
615
616 if (devsw(dev)->d_open == ptcopen) {
617 switch (cmd) {
--- 149 unchanged lines hidden (view full) ---
767 pti->pt_send |= TIOCPKT_NOSTOP;
768 pti->pt_flags |= PF_NOSTOP;
769 ptcwakeup(tp, FREAD);
770 }
771 }
772 return (error);
773}
774
775static void
776pty_clone(void *arg, char *name, int namelen, dev_t *dev)
777{
778 int u;
779
780 if (*dev != NODEV)
781 return;
782 if (bcmp(name, "pty", 3) != 0)
783 return;
784 if (name[5] != '\0')
--- 17 unchanged lines hidden (view full) ---
802 return;
803 *dev = make_dev(&ptc_cdevsw, u,
804 UID_ROOT, GID_WHEEL, 0666, "pty%c%r", names[u / 32], u % 32);
805 (*dev)->si_flags |= SI_CHEAPCLONE;
806 return;
807}
808
809static void
810ptc_drvinit(void *unused)
811{
812
813 EVENTHANDLER_REGISTER(dev_clone, pty_clone, 0, 1000);
814}
815
816SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL)
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
--- 16 unchanged lines hidden (view full) ---
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)tty_pty.c 8.4 (Berkeley) 2/20/95
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sys/kern/tty_pty.c 130262 2004-06-09 10:16:14Z phk $");
34
35/*
36 * Pseudo-teletype Driver
37 * (Actually two drivers, requiring two entries in 'cdevsw')
38 */
39#include "opt_compat.h"
40#include "opt_tty.h"
41#include <sys/param.h>
--- 114 unchanged lines hidden (view full) ---
156 devs->si_drv1 = devc->si_drv1 = pt;
157 devs->si_tty = devc->si_tty = pt->pt_tty;
158 pt->pt_tty->t_dev = devs;
159 return (devc);
160}
161
162/*ARGSUSED*/
163static int
164ptsopen(dev_t dev, int flag, int devtype, struct thread *td)
165{
166 struct tty *tp;
167 int error;
168 struct pt_ioctl *pti;
169
170 if (!dev->si_drv1)
171 return(ENXIO);
172 pti = dev->si_drv1;
--- 21 unchanged lines hidden (view full) ---
194 }
195 error = ttyld_open(tp, dev);
196 if (error == 0)
197 ptcwakeup(tp, FREAD|FWRITE);
198 return (error);
199}
200
201static int
202ptsclose(dev_t dev, int flag, int mode, struct thread *td)
203{
204 struct tty *tp;
205 int err;
206
207 tp = dev->si_tty;
208 err = ttyld_close(tp, flag);
209 (void) ttyclose(tp);
210 return (err);
211}
212
213static int
214ptsread(dev_t dev, struct uio *uio, int flag)
215{
216 struct thread *td = curthread;
217 struct proc *p = td->td_proc;
218 struct tty *tp = dev->si_tty;
219 struct pt_ioctl *pti = dev->si_drv1;
220 struct pgrp *pg;
221 int error = 0;
222
--- 46 unchanged lines hidden (view full) ---
269}
270
271/*
272 * Write to pseudo-tty.
273 * Wakeups of controlling tty will happen
274 * indirectly, when tty driver calls ptsstart.
275 */
276static int
277ptswrite(dev_t dev, struct uio *uio, int flag)
278{
279 struct tty *tp;
280
281 tp = dev->si_tty;
282 if (tp->t_oproc == 0)
283 return (EIO);
284 return (ttyld_write(tp, uio, flag));
285}
286
287/*
288 * Start output on pseudo-tty.
289 * Wake up process selecting or sleeping for input from controlling tty.
290 */
291static void
292ptsstart(struct tty *tp)
293{
294 struct pt_ioctl *pti = tp->t_dev->si_drv1;
295
296 if (tp->t_state & TS_TTSTOP)
297 return;
298 if (pti->pt_flags & PF_STOPPED) {
299 pti->pt_flags &= ~PF_STOPPED;
300 pti->pt_send = TIOCPKT_START;
301 }
302 ptcwakeup(tp, FREAD);
303}
304
305static void
306ptcwakeup(struct tty *tp, int flag)
307{
308 struct pt_ioctl *pti = tp->t_dev->si_drv1;
309
310 if (flag & FREAD) {
311 selwakeuppri(&pti->pt_selr, TTIPRI);
312 wakeup(TSA_PTC_READ(tp));
313 }
314 if (flag & FWRITE) {
315 selwakeuppri(&pti->pt_selw, TTOPRI);
316 wakeup(TSA_PTC_WRITE(tp));
317 }
318}
319
320static int
321ptcopen(dev_t dev, int flag, int devtype, struct thread *td)
322{
323 struct tty *tp;
324 struct pt_ioctl *pti;
325
326 if (!dev->si_drv1)
327 ptyinit(dev);
328 if (!dev->si_drv1)
329 return(ENXIO);
--- 9 unchanged lines hidden (view full) ---
339 pti->pt_prison = td->td_ucred->cr_prison;
340 pti->pt_flags = 0;
341 pti->pt_send = 0;
342 pti->pt_ucntl = 0;
343 return (0);
344}
345
346static int
347ptcclose(dev_t dev, int flags, int fmt, struct thread *td)
348{
349 struct tty *tp;
350
351 tp = dev->si_tty;
352 (void)ttyld_modem(tp, 0);
353
354 /*
355 * XXX MDMBUF makes no sense for ptys but would inhibit the above
--- 9 unchanged lines hidden (view full) ---
365 ttyflush(tp, FREAD | FWRITE);
366 }
367
368 tp->t_oproc = 0; /* mark closed */
369 return (0);
370}
371
372static int
373ptcread(dev_t dev, struct uio *uio, int flag)
374{
375 struct tty *tp = dev->si_tty;
376 struct pt_ioctl *pti = dev->si_drv1;
377 char buf[BUFSIZ];
378 int error = 0, cc;
379
380 /*
381 * We want to block until the slave
--- 41 unchanged lines hidden (view full) ---
423 break;
424 error = uiomove(buf, cc, uio);
425 }
426 ttwwakeup(tp);
427 return (error);
428}
429
430static void
431ptsstop(struct tty *tp, int flush)
432{
433 struct pt_ioctl *pti = tp->t_dev->si_drv1;
434 int flag;
435
436 /* note: FLUSHREAD and FLUSHWRITE already ok */
437 if (flush == 0) {
438 flush = TIOCPKT_STOP;
439 pti->pt_flags |= PF_STOPPED;
--- 5 unchanged lines hidden (view full) ---
445 if (flush & FREAD)
446 flag |= FWRITE;
447 if (flush & FWRITE)
448 flag |= FREAD;
449 ptcwakeup(tp, flag);
450}
451
452static int
453ptcpoll(dev_t dev, int events, struct thread *td)
454{
455 struct tty *tp = dev->si_tty;
456 struct pt_ioctl *pti = dev->si_drv1;
457 int revents = 0;
458 int s;
459
460 if ((tp->t_state & TS_CONNECTED) == 0)
461 return (events &
--- 31 unchanged lines hidden (view full) ---
493 selrecord(td, &pti->pt_selw);
494 }
495 splx(s);
496
497 return (revents);
498}
499
500static int
501ptcwrite(dev_t dev, struct uio *uio, int flag)
502{
503 struct tty *tp = dev->si_tty;
504 u_char *cp = 0;
505 int cc = 0;
506 u_char locbuf[BUFSIZ];
507 int cnt = 0;
508 struct pt_ioctl *pti = dev->si_drv1;
509 int error = 0;
--- 91 unchanged lines hidden (view full) ---
601 uio->uio_resid += cc;
602 return (error);
603 }
604 goto again;
605}
606
607/*ARGSUSED*/
608static int
609ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
610{
611 struct tty *tp = dev->si_tty;
612 struct pt_ioctl *pti = dev->si_drv1;
613 u_char *cc = tp->t_cc;
614 int stop, error;
615
616 if (devsw(dev)->d_open == ptcopen) {
617 switch (cmd) {
--- 149 unchanged lines hidden (view full) ---
767 pti->pt_send |= TIOCPKT_NOSTOP;
768 pti->pt_flags |= PF_NOSTOP;
769 ptcwakeup(tp, FREAD);
770 }
771 }
772 return (error);
773}
774
775static void
776pty_clone(void *arg, char *name, int namelen, dev_t *dev)
777{
778 int u;
779
780 if (*dev != NODEV)
781 return;
782 if (bcmp(name, "pty", 3) != 0)
783 return;
784 if (name[5] != '\0')
--- 17 unchanged lines hidden (view full) ---
802 return;
803 *dev = make_dev(&ptc_cdevsw, u,
804 UID_ROOT, GID_WHEEL, 0666, "pty%c%r", names[u / 32], u % 32);
805 (*dev)->si_flags |= SI_CHEAPCLONE;
806 return;
807}
808
809static void
810ptc_drvinit(void *unused)
811{
812
813 EVENTHANDLER_REGISTER(dev_clone, pty_clone, 0, 1000);
814}
815
816SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL)