📄 ckutio.c
字号:
debug(F111," ttname=CTTNAM",ttname,xlocal); /* If any of 0, 1, or 2 not redirected, we can use ttyname() to get */ /* the name of the controlling terminal... *//* Warning: on some UNIX systems (SVR4?), ttyname() reportedly opens /dev but never closes it. If it is called often enough, we run out of file descriptors and subsequent open()'s of other devices or files can fail.*/ } else if ((x0 = isatty(0)) || (x1 = isatty(1)) || isatty(2)) {#ifndef MINIX if (x0) x = ttyname(0); /* and compare it with the */ else if (x1) /* tty device name. */ x = ttyname(1); else x = ttyname(2); strncpy(cname,x,DEVNAMLEN); /* (copy from internal static buf) */ debug(F110," cname",x,0); x = ttyname(ttyfd); /* Gat real name of ttname. */ xlocal = (strncmp(x,cname,DEVNAMLEN) == 0) ? 0 : 1; /* Compare. */ debug(F111," ttyname",x,xlocal);#else xlocal = 1; /* Can't do this test in MINIX */#endif /* MINIX */ } else { /* Else, if stdin redirected... */#ifdef SVORPOSIX/* System V provides nice ctermid() function to get name of controlling tty */ ctermid(cname); /* Get name of controlling terminal */ debug(F110," ctermid",cname,0); x = ttyname(ttyfd); /* Compare with name of comm line. */ xlocal = (strncmp(x,cname,DEVNAMLEN) == 0) ? 0 : 1; debug(F111," ttyname",x,xlocal);#else/* Just assume local */ xlocal = 1;#endif /* SVORPOSIX */ debug(F101," redirected stdin","",xlocal); } }#ifndef NOFDZERO/* Note, the following code was added so that Unix "idle-line" snoopers *//* would not think Kermit was idle when it was transferring files, and *//* maybe log people out. */ if (xlocal == 0) { /* Remote mode */ if (fdflag == 0) { /* Standard i/o is not redirected */ debug(F100,"ttopen setting ttyfd = 0","",0); close(ttyfd); /* Use file descriptor 0 */ ttyfd = 0; } else { /* Standard i/o is redirected */ debug(F101,"ttopen stdio redirected","",ttyfd); } }#endif /* NOFDZERO *//* Now check if line is locked -- if so fail, else lock for ourselves *//* Note: After having done this, don't forget to delete the lock if you *//* 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); close(ttyfd); /* Close the device. */ ttyfd = -1; /* Erase its file descriptor. */ signal(SIGINT,occt); /* Put old SIGINT back. */ if (xx == -2) { /* If lockfile says tty is in use, */ char *p = malloc(200); /* print an ls -l listing */ if (p) { /* if we can get space... */ sprintf(p,"/bin/ls -l %s",flfnam); zsyscmd(p); /* Get listing. */ free(p); /* free the space */ xpid = ttrpid(flfnam); /* Try to read pid from lockfile */ priv_off(); /* Turn privs back off. */ if (xpid > -1) printf("pid = %d\n",xpid); /* show pid */ } 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#ifdef TIOCSINUSE if (xlocal && ioctl(ttyfd, TIOCSINUSE, NULL) < 0) { fprintf(stderr, "Can't set in-use flag on modem.\n"); 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 gtty(ttyfd,&ttold); debug(F101,"ttopen gtty ttold.sg_flags","",ttold.sg_flags);#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 */ gtty(ttyfd,&ttraw); /* And a copy of it for packets*/ gtty(ttyfd,&tttvt); /* And one for virtual tty service */#endif /* ATTSV */#endif /* BSD44ORPOSIX *//* Section for changing line discipline. It's restored in ttres(). */#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 tcsetattr(ttyfd, TCSADRAIN, &ttraw);#else if (xlocal) { ttraw.c_cflag |= CLOCAL; ioctl(ttyfd, TCSETA, &ttraw); }#endif /* BSD44 */#endif /* ATTSV */#ifndef SCO3R2#ifndef OXOS/* 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 /* OXOS */#endif /* SCO3R2 */ }#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 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; stty(ttyfd,&ttraw);#endif /* SVORPOSIX *//* ttflui(); This fails for some reason */ } /* Get current speed */ ttspeed = ttgspd(); 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 x = 0; debug(F101,"ttclos ttyfd","",ttyfd); if (ttyfd < 0) return(0); /* Wasn't open. */ if (ttfdflg) return(0); /* If we got ttyfd from another */ /* process, don't close it. */ tvtflg = 0;#ifdef NETCONN if (netconn) { /* Network connection. */ debug(F100,"ttclos closing net","",0); netclos(); /* Close it. */ netconn = 0; return(0); }#endif /* NETCONN */#ifdef FT21 if (xlocal) ioctl(ttyfd,TIOCHPCL, NULL);#endif /* FT21 */#ifdef ultrix if (xlocal) ioctl(ttyfd, TIOCNCAR, NULL);#endif /* ultrix */ if (xlocal) { debug(F100,"ttclos about to call ttunlck","",0); if (ttunlck()) /* Release uucp-style lock */ fprintf(stderr,"Warning, problem releasing lock\r\n"); debug(F100,"ttclos about to call ttres","",0); } if (ttyfd > 0) { int xx; saval = signal(SIGALRM,timerh); /* Enable timer interrupt. */ xx = alarm(5); /* Allow 5 seconds for this. */ debug(F101,"ttclos alarm","",xx); if (setjmp(sjbuf)) { /* Timer went off? */ x = -1; } else { /* What we're really trying to do */ if (xlocal) { tthang(); /* Hang up first, then... */ 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); } } ttyfd = -1; /* Invalidate the file descriptor. */#ifdef sony_news km_ext = -1; /* Invalidate device's Kanji-mode */#endif /* sony_news *//* For bidirectional lines, restore getty if it was there before. */#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 */ 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.*/#define HUPTIME 500 /* Milliseconds for hangup */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -