📄 ckutio.c
字号:
/* leave ttopen() with an error condition. */ lkf = 0; /* Check lock */ if (xlocal > 0) { int xx; int xpid; if ((xx = ttlock(ttname)) < 0) { /* Can't lock it. */ debug(F111,"ttopen ttlock fails",ttname,xx); /* WARNING - This close() can hang if tty is an empty socket... */ close(ttyfd); /* Close the device. */ ttyfd = -1; /* Erase its file descriptor. */ signal(SIGINT,occt); /* Put old SIGINT back. */ if (xx == -2) { /* If lockfile says device in use, */#ifndef NOUUCP debug(F111,"ttopen reading lockfile pid",flfnam,xx); priv_on(); xpid = ttrpid(flfnam); /* Try to read pid from lockfile */ priv_off(); /* Turn privs back off. */ if (xpid > -1) { /* If we got a pid */ printf("Locked by process %d\n",xpid); /* tell them. */ } else if (*flfnam) { char *p = malloc(280); /* Print a directory listing. *//* Note: priv_on() won't help here, because we do not pass privs along to to inferior processes, in this case ls. So if the real user does not have directory-listing access to the lockfile directory, this will result in something like "not found". That's why we try this only as a last resort.*/ if (p) { /* If we got the space... */ extern char *DIRCMD; sprintf(p,"%s %s",DIRCMD,flfnam); zsyscmd(p); /* Get listing. */ if (p) { /* free the space */ free(p); p = NULL; } } }#endif /* NOUUCP */ return(-5); /* Code for device in use */ } else return(-3); /* Access denied */ } else lkf = 1; }/* Got the line, now set the desired value for local. */ if (*lcl != 0) *lcl = xlocal;/* Some special stuff for v7... */#ifdef V7#ifndef MINIX if (kmem[TTY] < 0) { /* If open, then skip this. */ qaddr[TTY] = initrawq(ttyfd); /* Init the queue. */ if ((kmem[TTY] = open("/dev/kmem", 0)) < 0) { fprintf(stderr, "Can't read /dev/kmem in ttopen.\n"); perror("/dev/kmem"); exit(1); } }#endif /* !MINIX */#endif /* V7 *//* No failure returns after this point */#ifdef ultrix ioctl(ttyfd, TIOCMODEM, &temp);#ifdef TIOCSINUSE if (xlocal && ioctl(ttyfd, TIOCSINUSE, NULL) < 0) { fprintf(stderr, "Can't set in-use flag on %s.\n",ttname); perror("TIOCSINUSE"); }#endif /* TIOCSINUSE */#endif /* ultrix *//* Get tty device settings */#ifdef BSD44ORPOSIX /* POSIX */ tcgetattr(ttyfd,&ttold); debug(F101,"ttopen tcgetattr ttold.c_lflag","",ttold.c_lflag); tcgetattr(ttyfd,&ttraw); tcgetattr(ttyfd,&tttvt);#else /* BSD, V7, and all others */#ifdef ATTSV /* AT&T UNIX */ ioctl(ttyfd,TCGETA,&ttold); debug(F101,"ttopen ioctl TCGETA ttold.c_lflag","",ttold.c_lflag); ioctl(ttyfd,TCGETA,&ttraw); ioctl(ttyfd,TCGETA,&tttvt);#else#ifdef BELLV10 ioctl(ttyfd,TIOCGETP,&ttold); debug(F101,"ttopen BELLV10 ttold.sg_flags","",ttold.sg_flags); ioctl(ttyfd,TIOCGDEV,&tdold); debug(F101,"ttopen BELLV10 tdold.flags","",tdold.flags);#else gtty(ttyfd,&ttold); debug(F101,"ttopen gtty ttold.sg_flags","",ttold.sg_flags);#endif /* BELLV10 */#ifdef sony_news /* Sony NEWS */ if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { /* Get console Kanji mode */ perror("ttopen error getting Kanji mode"); debug(F101,"ttopen error getting Kanji mode","",0); km_ext = -1; /* Make sure this stays undefined. */ }#endif /* sony_news */#ifdef TIOCGETC tcharf = 0; /* In remote mode, also get */ if (xlocal == 0) { /* special characters */ if (ioctl(ttyfd,TIOCGETC,&tchold) < 0) { debug(F100,"ttopen TIOCGETC failed","",0); } else { tcharf = 1; /* It worked. */ ioctl(ttyfd,TIOCGETC,&tchnoi); /* Get another copy */ debug(F100,"ttopen TIOCGETC ok","",0); } } #else debug(F100,"ttopen TIOCGETC not defined","",0);#endif /* TIOCGETC */#ifdef TIOCGLTC ltcharf = 0; /* In remote mode, also get */ if (xlocal == 0) { /* local special characters */ if (ioctl(ttyfd,TIOCGLTC,<chold) < 0) { debug(F100,"ttopen TIOCGLTC failed","",0); } else { ltcharf = 1; /* It worked. */ ioctl(ttyfd,TIOCGLTC,<chnoi); /* Get another copy */ debug(F100,"ttopen TIOCGLTC ok","",0); } } #else debug(F100,"ttopen TIOCGLTC not defined","",0);#endif /* TIOCGLTC */#ifdef TIOCLGET lmodef = 0; if (ioctl(ttyfd,TIOCLGET,&lmode) < 0) { debug(F100,"ttopen TIOCLGET failed","",0); } else { lmodef = 1; debug(F100,"ttopen TIOCLGET ok","",0); }#endif /* TIOCLGET */#ifdef BELLV10 ioctl(ttyfd,TIOCGETP,&ttraw); ioctl(ttyfd,TIOCGETP,&tttvt);#else gtty(ttyfd,&ttraw); /* And a copy of it for packets*/ gtty(ttyfd,&tttvt); /* And one for virtual tty service */#endif /* BELLV10 */#endif /* ATTSV */#endif /* BSD44ORPOSIX *//* Section for changing line discipline. It's restored in ttres(). */#ifdef AIXRS#ifndef AIX41 { union txname ld_name; int ld_idx = 0; ttld = 0; do { ld_name.tx_which = ld_idx++; ioctl(ttyfd, TXGETCD, &ld_name); if (!strncmp(ld_name.tx_name, "rts", 3)) ttld |= 1; } while (*ld_name.tx_name); debug(F101,"AIX line discipline","",ttld); }#endif /* AIX41 */#endif /* AIXRS */#ifdef BSD41/* For 4.1BSD only, force "old" tty driver, new one botches TANDEM. */ { int k; ioctl(ttyfd, TIOCGETD, &ttld); /* Get and save line discipline */ debug(F101,"4.1bsd line discipline","",ttld); k = OTTYDISC; /* Switch to "old" discipline */ k = ioctl(ttyfd, TIOCSETD, &k); debug(F101,"4.1bsd tiocsetd","",k); }#endif /* BSD41 */#ifdef aegis /* This was previously done before the last two TCGETA or gtty above, * in both the ATTSV and not-ATTSV case. If it is not okay to have only * one copy if it here instead, give us a shout! */ sio_$control((short)ttyfd, sio_$raw_nl, false, st); if (xlocal) { /* ignore breaks from local line */ sio_$control((short)ttyfd, sio_$int_enable, false, st); sio_$control((short)ttyfd, sio_$quit_enable, false, st); }#endif /* aegis */#ifdef VXVE ttraw.c_line = 0; /* STTY line 0 for VX/VE */ tttvt.c_line = 0; /* STTY line 0 for VX/VE */ ioctl(ttyfd,TCSETA,&ttraw);#endif /* vxve *//* If O_NDELAY was used during open(), then remove it now. */#ifdef O_NDELAY if (fcntl(ttyfd, F_GETFL, 0) & O_NDELAY) {#ifndef aegis if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0 ) perror("Can't unset O_NDELAY");#endif /* aegis */ /* Some systems, notably Xenix (don't know how common this is in * other systems), need special treatment to get rid of the O_NDELAY * behaviour on read() with respect to carrier presence (i.e. read() * returning 0 when carrier absent), even though the above fcntl() * is enough to make read() wait for input when carrier is present. * This magic, in turn, requires CLOCAL for working when the carrier * is absent. But if xlocal == 0, presumably you already have CLOCAL * or you have a carrier, otherwise you wouldn't be running this. */#ifdef ATTSV#ifdef BSD44#ifdef __bsdi__ if (xlocal) ttraw.c_cflag |= CLOCAL;#else#ifdef __FreeBSD__ if (xlocal) ttraw.c_cflag |= CLOCAL;#endif /* __FreeBSD__ */#endif /* __bsdi__ */ if (tcsetattr(ttyfd, TCSADRAIN, &ttraw) < 0) perror("tcsetattr");#else /* !BSD44 */ if (xlocal) { ttraw.c_cflag |= CLOCAL; ioctl(ttyfd, TCSETA, &ttraw); }#endif /* BSD44 */#endif /* ATTSV */#ifndef NOCOTFMC /* = NO Close(Open()) To Force Mode Change *//* Reportedly lets uugetty grab the device in SCO UNIX 3.2 / XENIX 2.3 */ close( priv_opn(ttname, O_RDWR) ); /* Magic to force change. */#endif /* NOCOTFMC */ }#endif /* O_NDELAY *//* Instruct the system how to treat the carrier, and set a few other tty * parameters. * * This also undoes the temporary setting of CLOCAL that may have been done * for the close(open()) above (except in Xenix). Also throw in ~ECHO, to * prevent the other end of the line from sitting there talking to itself, * producing garbage when the user performs a connect. * * SCO Xenix unfortunately seems to ignore the actual state of CLOCAL. * Now it thinks CLOCAL is always on. It seems the only real solution for * Xenix is to switch between the lower and upper case device names. * * This section may at some future time expand into setting a complete * collection of tty parameters, or call a function shared with ttpkt()/ * ttvt() that does so. On the other hand, the initial parameters are not * that important, since ttpkt() or ttvt() should always fix that before * any communication is done. Well, we'll see... */ if (xlocal) { curcarr = -2; carrctl(&ttraw, ttcarr == CAR_ON);#ifdef COHERENT#define SVORPOSIX#endif /* COHERENT */#ifdef SVORPOSIX ttraw.c_lflag &= ~ECHO; ttold.c_lflag &= ~ECHO;#ifdef BSD44ORPOSIX tcsetattr(ttyfd, TCSADRAIN, &ttraw);#else ioctl(ttyfd, TCSETA, &ttraw);#endif /* BSD44ORPOSIX */#else /* BSD, etc */ ttraw.sg_flags &= ~ECHO; ttold.sg_flags &= ~ECHO;#ifdef BELLV10 ioctl(ttyfd,TIOCSETP,&ttraw);#else stty(ttyfd,&ttraw);#endif /* BELLV10 */#endif /* SVORPOSIX */#ifdef COHERENT#undef SVORPOSIX#endif /* COHERENT */ /* ttflui(); */ /* This fails for some reason. */ } /* Get current speed */#ifndef BEBOX ttspeed = ttgspd();#else ttspeed = 19200;#endif /* !BEBOX */ debug(F101,"ttopen ttspeed","",ttspeed); /* Done, make entries in debug log, restore Ctrl-C trap, and return. */ debug(F101,"ttopen, ttyfd","",ttyfd); debug(F101," lcl","",*lcl); debug(F111," lock file",flfnam,lkf); signal(SIGINT,occt); return(0);}/* D O _ O P E N -- Do the right kind of open() call for the tty. */intdo_open(ttname) char *ttname; {#ifndef O_NDELAY /* O_NDELAY not defined */ return(priv_opn(ttname,2));#else /* O_NDELAY defined */#ifdef ATT7300/* Open comms line without waiting for carrier so initial call does not hang because state of "modem" is likely unknown at the initial call -jrd. If this is needed for the getty stuff to work, and the open would not work without O_NDELAY when getty is still on, then this special case is ok. Otherwise, get rid of it. -ske*/ return(priv_opn(ttname, O_RDWR | O_NDELAY));#else /* !ATT7300 */ /* Normal case. Use O_NDELAY according to SET CARRIER. See ttscarr(). */ return(priv_opn(ttname, O_RDWR | ((ttcarr != CAR_ON) ? O_NDELAY : 0) ));#endif /* !ATT7300 */#endif /* O_NDELAY */}/* T T C L O S -- Close the TTY, releasing any lock. */intttclos(foo) int foo; { /* Arg req'd for signal() prototype */ int xx, x = 0; debug(F101,"ttclos ttyfd","",ttyfd); if (ttyfd < 0) return(0); /* Wasn't open. */ if (ttfdflg) /* If we inherited ttyfd from */ return(0); /* another process, don't close it. */ tvtflg = 0; /* (some day get rid of this...) */#ifdef NETCONN if (netconn) { /* If it's a network connection. */ debug(F100,"ttclos closing net","",0); netclos(); /* Let the network module close it. */ netconn = 0; /* No more network connection. */ debug(F101,"ttclos ttyfd after netclos","",ttyfd); return(0); }#endif /* NETCONN */ if (xlocal) { /* We're closing a SET LINE device */#ifdef FT21 /* Fortune 2.1-specific items ... */ ioctl(ttyfd,TIOCHPCL, NULL);#endif /* FT21 */#ifdef ultrix /* Ultrix-specific items ... */#ifdef TIOCSINUSE /* Unset the INUSE flag that we set in ttopen() */ ioctl(ttyfd, TIOCSINUSE, NULL);#endif /* TIOCSINUSE */ ioctl(ttyfd, TIOCNMODEM, &x);#ifdef COMMENT /* What was this? */ ioctl(ttyfd, TIOCNCAR, NULL);#endif /* COMMENT */#endif /* ultrix */ debug(F100,"ttclos about to call ttunlck","",0); if (ttunlck()) /* Release uucp-style lock */ fprintf(stderr,"Warning, problem releasing lock\r\n"); } if ( xlocal#ifdef NOFDZERO || ttyfd > 0#endif /* NOFDZERO */ ) { saval = signal(SIGALRM,timerh); /* Enable timer interrupt. */ xx = alarm(8); /* Allow 8 seconds for this. */ debug(F101,"ttclos alarm","",xx); if (#ifdef CK_POSIX_SIG sigsetjmp(sjbuf,1)#else setjmp(sjbuf)#endif /* CK_POSIX_SIG */ ) { /* Timer went off? */ x = -1; } else { /* What we're really trying to do */ debug(F100,"ttclos calling tthang()","",0); tthang(); /* Hang up first, then... */ debug(F100,"ttclos calling ttres()","",0); ttres(); /* Reset device modes. */ } debug(F101,"ttclos about to call close","",ttyfd); close(ttyfd); /* Close the device. */ x = 1; ttimoff(); /* Turn off timer. */ if (x < 0) { fprintf(stderr,"?Timed out closing device: %s\n",ttnmsv); debug(F100,"ttclos timed out","",0); } }/* For bidirectional lines, restore getty if it was there before. */ if (xlocal) {#ifdef ACUCNTRL /* 4.3BSD acucntrl() method. */ acucntrl("enable",ttnmsv); /* Enable getty on the device. */#else#ifdef ATT7300 /* ATT UNIX PC (3B1, 7300) method. */ if (attmodem & DOGETY) /* Was getty(1m) running before us? */ ongetty(ttnmsv); /* Yes, restart getty on tty line */ attmodem &= ~DOGETY; /* No phone in use, getty restored */#endif /* ATT7300 */#endif /* System-dependent getty-restoring methods */ }#ifdef sony_news km_ext = -1; /* Invalidate device's Kanji-mode */#endif /* sony_news */ ttyfd = -1; /* Invalidate the file descriptor. */ debug(F100,"ttclos done","",0); return(0);}/* T T H A N G -- Hangup phone line or network connection. *//* Returns: 0 if it does nothing. 1 if it believes that it hung up successfully. -1 if it believes that the hangup attempt failed
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -