// Do system dependent initialization // This is called once, when the program starts int setup (void) { if (tty_setup() < 0) return -1; srandrand(); return 0; }
void slip_start(slipconn *sc) { int mfd, sfd, disc, sencap = 0; if (!open_pty_pair(&sc->masterfd, &sc->slavefd)) { perror("open_pty_pair"); exit(1); } tty_setup(sc); slip_setup(sc); interface_start(sc); }
int tty_open(uint8_t minor, uint16_t flag) { struct termios *t; /* FIXME : open/carrier logic is needed here, definitely before we enable ptys */ /* Minor == 0 means that it is the controlling tty of the process */ /* FIXME: need to propogate this minor change back into the file handle and inode somehow ??? */ if (!minor) minor = udata.u_ptab->p_tty; if (minor < 1 || minor > NUM_DEV_TTY + 1) { udata.u_error = ENODEV; return (-1); } /* Hung up but not yet cleared of users */ if (deadflag[minor]) { udata.u_error = ENXIO; return -1; } t = &ttydata[minor]; /* If there is no controlling tty for the process, establish it */ if (!udata.u_ptab->p_tty && !(flag & O_NOCTTY)) { udata.u_ptab->p_tty = minor; tty_pgrp[minor] = udata.u_ptab->p_pgrp; } tty_setup(minor); if ((t->c_cflag & CLOCAL) || (flag & O_NDELAY)) return 0; if (!tty_carrier(minor)) { if (psleep_flags(&t->c_cflag, flag)) return -1; } /* Carrier spiked ? */ if (deadflag[minor]) { udata.u_error = ENXIO; deadflag[minor] = 0; return -1; } return 0; }
int tty_ioctl(uint8_t minor, uint16_t request, char *data) { /* Data in User Space */ if (!minor) minor = udata.u_ptab->p_tty; if (minor < 1 || minor > NUM_DEV_TTY + 1) { udata.u_error = ENODEV; return -1; } if (deadflag[minor]) { udata.u_error = ENXIO; return -1; } switch (request) { case TCGETS: uput(&ttydata[minor], data, sizeof(struct termios)); break; case TCSETSW: /* We don't have an output queue really so for now drop through */ case TCSETS: case TCSETSF: uget(data, &ttydata[minor], sizeof(struct termios)); if (request == TCSETSF) clrq(&ttyinq[minor]); tty_setup(minor); break; case TIOCINQ: uput(&ttyinq[minor].q_count, data, 2); break; case TIOCFLUSH: clrq(&ttyinq[minor]); break; case TIOCHANGUP: tty_hangup(minor); return 0; default: udata.u_error = ENOTTY; return (-1); } return (0); }
int tty_open(uint8_t minor, uint16_t flag) { struct tty *t; if (minor > NUM_DEV_TTY) { udata.u_error = ENODEV; return -1; } t = &ttydata[minor]; /* Hung up but not yet cleared of users */ if (t->flag & TTYF_DEAD) { udata.u_error = ENXIO; return -1; } if (t->users) { t->users++; return 0; } tty_setup(minor); if ((t->termios.c_cflag & CLOCAL) || (flag & O_NDELAY)) goto out; /* FIXME: racy - need to handle IRQ driven carrier events safely */ if (!tty_carrier(minor)) { if (psleep_flags(&t->termios.c_cflag, flag)) return -1; } /* Carrier spiked ? */ if (t->flag & TTYF_DEAD) { udata.u_error = ENXIO; t->flag &= ~TTYF_DEAD; return -1; } out: t->users++; return 0; }
int tty_ioctl(uint8_t minor, uarg_t request, char *data) { /* Data in User Space */ struct tty *t; if (minor > NUM_DEV_TTY + 1) { udata.u_error = ENODEV; return -1; } t = &ttydata[minor]; if (t->flag & TTYF_DEAD) { udata.u_error = ENXIO; return -1; } jobcontrol_in(minor, t); switch (request) { case TCGETS: return uput(&t->termios, data, sizeof(struct termios)); break; case TCSETSF: clrq(&ttyinq[minor]); /* Fall through for now */ case TCSETSW: /* We don't have an output queue really so for now drop through */ case TCSETS: if (uget(data, &t->termios, sizeof(struct termios)) == -1) return -1; tty_setup(minor); break; case TIOCINQ: return uput(&ttyinq[minor].q_count, data, 2); case TIOCFLUSH: clrq(&ttyinq[minor]); break; case TIOCHANGUP: tty_hangup(minor); return 0; case TIOCOSTOP: t->flag |= TTYF_STOP; break; case TIOCOSTART: t->flag &= ~TTYF_STOP; break; case TIOCGWINSZ: return uput(&t->winsize, data, sizeof(struct winsize)); case TIOCSWINSZ: if (uget(&t->winsize, data, sizeof(struct winsize))) return -1; sgrpsig(t->pgrp, SIGWINCH); return 0; case TIOCGPGRP: return uputw(t->pgrp, data); #ifdef CONFIG_LEVEL_2 case TIOCSPGRP: /* Only applicable via controlling terminal */ if (minor != udata.u_ptab->p_tty) { udata.u_error = ENOTTY; return -1; } return tcsetpgrp(t, data); #endif default: udata.u_error = ENOTTY; return -1; } return 0; }
static void tek_init(PLStream *pls) { TekDev *dev; int xmin = 0; int xmax = TEKX; int ymin = 0; int ymax = TEKY; PLFLT pxlx = 4.771; PLFLT pxly = 4.653; pls->graphx = TEXT_MODE; /* Allocate and initialize device-specific data */ pls->dev = calloc(1, (size_t) sizeof(TekDev)); if (pls->dev == NULL) plexit("tek_init: Out of memory."); dev = (TekDev *) pls->dev; dev->curcolor = 1; dev->xold = PL_UNDEFINED; dev->yold = PL_UNDEFINED; plP_setpxl(pxlx, pxly); plP_setphy(xmin, xmax, ymin, ymax); /* Terminal/file initialization */ if (pls->termin) { pls->OutFile = stdout; tty_setup(); } else { plFamInit(pls); plOpenFile(pls); } switch (pls->dev_minor) { #ifdef PLD_tek4107 case tek4107: pls->graphx = GRAPHICS_MODE; fprintf(pls->OutFile, "\033%%!0"); /* set tek mode */ fprintf(pls->OutFile, "\033KN1"); /* clear the view */ fprintf(pls->OutFile, "\033LZ"); /* clear dialog buffer */ fprintf(pls->OutFile, "\033ML1"); /* set default color */ break; #endif /* PLD_tek4107 */ /* A sneaky hack: VLT sometimes has leftover panel information, causing * garbage at the beginning of a sequence of color fills. Since * there is no clear panel command, instead I set the fill color to the * same as background and issue an end panel command. */ #ifdef PLD_vlt case vlt:{ char fillcol[4]; tek_graph(pls); encode_int(fillcol, 0); fprintf(pls->OutFile, "\033MP%s\033LE", fillcol); break; } #endif /* PLD_vlt */ default: tek_graph(pls); } /* Initialize palette */ if ( pls->color & 0x01 ) { printf("\033TM111"); /* Switch to RGB colors */ setcmap(pls); } /* Finish initialization */ fprintf(pls->OutFile, VECTOR_MODE); /* Enter vector mode */ if (pls->termin) fprintf(pls->OutFile, CLEAR_VIEW);/* erase and home */ fflush(pls->OutFile); }