📄 ckutio.c
字号:
#ifdef HPUX9PLUS if (name.machine[5] == '8') hpis800 = 1; else hpis800 = 0; debug(F101,"sysinit hpis800","",hpis800);#endif /* HPUX9PLUS */ }#endif /* CK_UTSNAME */#ifdef CK_ENVIRONMENT { extern char tn_env_acct[], tn_env_disp[], tn_env_job[], tn_env_prnt[], tn_env_sys[], uidbuf[]; extern char * whoami(); char *p;#ifdef CKSENDUID uidbuf[0] = '\0';#ifdef IKSD if (!inserver) {#endif /* IKSD */ p = getenv("USER"); debug(F110,"sysinit uidbuf from USER",uidbuf,0); if (!p) { p = getenv("LOGNAME"); debug(F110,"sysinit uidbuf from LOGNAME",uidbuf,0); } if (!p) { p = whoami(); debug(F110,"sysinit uidbuf from whoami()",uidbuf,0); } if (p) ckstrncpy(uidbuf,p,UIDBUFLEN);#ifdef IKSD }#endif /* IKSD */ debug(F110,"sysinit final uidbuf",uidbuf,0);#endif /* CKSENDUID */ if (p = getenv("JOB")) ckstrncpy(tn_env_job,p,63); if (p = getenv("ACCT")) ckstrncpy(tn_env_acct,p,63); if (p = getenv("PRINTER")) ckstrncpy(tn_env_prnt,p,63); if (p = getenv("DISPLAY")) ckstrncpy(tn_env_disp,p,63);#ifdef aegis strcpy(tn_env_sys,"Aegis");#else#ifdef Plan9 strcpy(tn_env_sys,"Plan9");#else strcpy(tn_env_sys,"UNIX");#endif /* Plan9 */#endif /* aegis */ }#endif /* CK_ENVIRONMENT */#ifdef CK_SNDLOC { extern char * tn_loc; char *p; if (p = getenv("LOCATION")) if (tn_loc = (char *)malloc((int)strlen(p)+1)) strcpy(tn_loc,p); }#endif /* CK_SNDLOC */ ckstrncpy(startupdir, zgtdir(), CKMAXPATH); startupdir[CKMAXPATH] = '\0'; x = strlen(startupdir); if (x <= 0) { startupdir[0] = '/'; startupdir[1] = '\0'; } else if (startupdir[x-1] != '/') { startupdir[x] = '/'; startupdir[x+1] = '\0'; } debug(F110,"sysinit startupdir",startupdir,0);#ifdef TTLEBUF le_init();#endif /* TTLEBUF */ return(0);}/* S Y S C L E A N U P -- System-dependent program cleanup. */intsyscleanup() {#ifdef F_SETFL if (iniflags > -1) fcntl(0,F_SETFL,iniflags); /* Restore stdin flags */#endif /* F_SETFL */#ifdef ultrix stty(0,&vanilla); /* Get sgtty info */#endif /* ultrix */#ifdef NETCMD if (ttpid) kill(ttpid,9);#endif /* NETCMD */ return(0);}/* T T O P E N -- Open a tty for exclusive access. *//* Call with: ttname: character string - device name or network host name. lcl: If called with lcl < 0, sets value of lcl as follows: 0: the terminal named by ttname is the job's controlling terminal. 1: the terminal named by ttname is not the job's controlling terminal. But watch out: if a line is already open, or if requested line can't be opened, then lcl remains (and is returned as) -1. modem: Less than zero: ttname is a network host name. Zero or greater: ttname is a terminal device name. Zero means a local connection (don't use modem signals). Positive means use modem signals. timo: 0 = no timer. nonzero = number of seconds to wait for open() to return before timing out. Returns: 0 on success -5 if device is in use -4 if access to device is denied -3 if access to lock directory denied -2 upon timeout waiting for device to open -1 on other error*/static int ttotmo = 0; /* Timeout flag *//* Flag kept here to avoid being clobbered by longjmp. */intttopen(ttname,lcl,modem,timo) char *ttname; int *lcl, modem, timo; {#ifdef BSD44#define ctermid(x) strcpy(x,"")#else#ifdef SVORPOSIX#ifndef CIE extern char *ctermid(); /* Wish they all had this! */#else /* CIE Regulus */#define ctermid(x) strcpy(x,"")#endif /* CIE */#endif /* SVORPOSIX */#endif /* BSD44 */#ifdef ultrix int temp = 0;#endif /* ultrix */ char *x; /* Worker string pointer */ int y;#ifndef pdp11#define NAMEFD /* Feature to allow name to be an open file descriptor */#endif /* pdp11 */#ifdef NAMEFD char *p; debug(F101,"ttopen telnetfd","",telnetfd);#endif /* NAMEFD */ debug(F111,"ttopen entry modem",ttname,modem); debug(F101," ttyfd","",ttyfd); debug(F101," lcl","",*lcl);#ifdef MAXNAMLEN debug(F100,"ttopen MAXNAMLEN defined","",0);#else debug(F100,"ttopen MAXNAMLEN *NOT* defined","",0);#endif#ifdef BSD4 debug(F100,"ttopen BSD4 defined","",0);#else debug(F100,"ttopen BSD4 *NOT* defined","",0);#endif /* BSD4 */#ifdef BSD42 debug(F100,"ttopen BSD42 defined","",0);#else debug(F100,"ttopen BSD42 *NOT* defined","",0);#endif /* BSD42 */#ifdef MYREAD debug(F100,"ttopen MYREAD defined","",0);#else debug(F100,"ttopen MYREAD *NOT* defined","",0);#endif /* MYREAD */ ttpmsk = 0xff; lockpid[0] = '\0'; if (ttyfd > -1) { /* if device already opened */ debug(F110,"ttopen ttname",ttname,0); debug(F110,"ttopen ttnmsv",ttnmsv,0); if (strncmp(ttname,ttnmsv,DEVNAMLEN)) /* are new & old names equal? */ ttclos(ttyfd); /* no, close old ttname, open new */ else /* else same, ignore this call, */ return(0); /* and return. */ } wasclosed = 0; ttpipe = 0; /* Assume it's not a pipe */ ttpty = 0;#ifdef NETCONN if (modem < 0) { /* modem < 0 = special code for net */ int x; ttmdm = modem; modem = -modem; /* Positive network type number */ fdflag = 0; /* Stdio not redirected. */ netconn = 1; /* And it's a network connection */ debug(F111,"ttopen net",ttname,modem);#ifdef NAMEFD for (p = ttname; isdigit(*p); p++) ; /* Check for all digits */ if (*p == '\0' && (telnetfd || x25fd)) { /* Avoid X.121 addresses */ ttyfd = atoi(ttname); /* Is there a way to test it's open? */ ttfdflg = 1; /* We got an open file descriptor */ debug(F111,"ttopen got open network fd",ttname,ttyfd); ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */ x = 1; /* Return code is "good". */ if (telnetfd) { ttnet = NET_TCPB; if (ttnproto != NP_TCPRAW) ttnproto = NP_TELNET;#ifdef SUNX25 } else if (x25fd) { ttnet = NET_SX25; ttnproto = NP_NONE;#endif /* SUNX25 */ } } else { /* Host name or address given */#ifdef NETPTY if (modem == NET_PTY) { int x; if (nopush) { debug(F100,"ttopen PTY: nopush","",0); return(-1); } ttnet = NET_PTY; ttnproto = NP_NONE; netconn = 1; /* but we don't use network i/o */ ttpty = 1; debug(F110,"ttopen PTY",ttname,0); x = do_pty(ttname); if (x > -1) { ckstrncpy(ttnmsv,ttname,DEVNAMLEN); xlocal = *lcl = 1; /* It's local */ } else { ttpty = 0; netconn = 0; } return(x); }#endif /* NETPTY */#ifdef NETCMD/* dup2() is not available on older System V platforms like AT&T 3Bx. For those systems we punt by not defining NETCMD, but we might be able to do better -- see workarounds for this problem in ckufio.c (search for dup2).*/ if (modem == NET_CMD) { if (nopush) { debug(F100,"ttopen pipe: nopush","",0); return(-1); } if (pipe(pipe0) || pipe(pipe1)) { perror("Pipe error"); return(-1); } ttpid = fork(); /* Make a fork */ switch (ttpid) { case -1: /* Error making fork */ close(pipe0[0]); close(pipe0[1]); close(pipe1[0]); close(pipe1[1]); perror("Fork error"); return(-1); case 0: /* Child. */ close(pipe0[0]); close(pipe1[1]); dup2(pipe0[1], 1); close(pipe0[1]); dup2(pipe1[0], 0); close(pipe1[0]); system(ttname); _exit(0); default: /* Parent */ close(pipe0[1]); close(pipe1[0]); fdin = pipe0[0]; /* Read from pipe */ fdout = pipe1[1]; /* Write to pipe */ ttout = fdopen(fdout,"w"); /* Get stream so we can */ if (!ttout) { /* make it unbuffered. */ perror("fdopen failure"); return(-1); } setbuf(ttout,NULL); ckstrncpy(ttnmsv,ttname,DEVNAMLEN); xlocal = *lcl = 1; /* It's local */ netconn = 1; /* Call it a network connection */ ttmdm = modem; /* Remember network type */ ttyfd = fdin; ttpipe = 1; return(0); } }#endif /* NETCMD */#endif /* NAMEFD */ x = netopen(ttname, lcl, modem); /* (see ckcnet.h) */ if (x > -1) { ckstrncpy(ttnmsv,ttname,DEVNAMLEN); } else netconn = 0;#ifdef NAMEFD }#endif /* NAMEFD */#ifdef sony_news /* Sony NEWS */ if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { /* Get Kanji mode */ perror("ttopen error getting Kanji mode (network)"); debug(F111,"ttopen error getting Kanji mode","network",0); km_ext = -1; /* Make sure this stays undefined. */ }#endif /* sony_news */ xlocal = *lcl = 1; /* Network connections are local. */ debug(F101,"ttopen net x","",x);#ifdef COMMENT/* Let netopen() do this */ if (x > -1 && !x25fd) x = tn_ini(); /* Initialize TELNET protocol */#endif /* COMMENT */ return(x); } else { /* Terminal device */#endif /* NETCONN */#ifdef NAMEFD/* This code lets you give Kermit an open file descriptor for a serial communication device, rather than a device name. Kermit assumes that the line is already open, locked, conditioned with the right parameters, etc.*/ for (p = ttname; isdigit(*p); p++) ; /* Check for all digits */ if (*p == '\0') { ttyfd = atoi(ttname); /* Is there a way to test it's open? */ debug(F111,"ttopen got open fd",ttname,ttyfd); ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */ if (ttyfd == 0) /* If it's stdio... */ xlocal = *lcl = 0; /* we're in remote mode */ else /* otherwise */ xlocal = *lcl = 1; /* local mode. */ netconn = 0; /* Assume it's not a network. */ tvtflg = 0; /* Might need to initialize modes. */ ttmdm = modem; /* Remember modem type. */ fdflag = 0; /* Stdio not redirected. */ ttfdflg = 1; /* Flag we were opened this way. */#ifdef sony_news /* Sony NEWS */ /* Get device Kanji mode */ if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { 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 */ return(0); /* Return success */ }#endif /* NAMEFD */#ifdef NETCONN }#endif /* NETCONN *//* Here we have to open a serial device of the given name. */ netconn = 0; /* So it's not a network connection */ occt = signal(SIGINT, cctrap); /* Set Control-C trap, save old one */ sigint_ign = 0; tvtflg = 0; /* Flag for use by ttvt(). */ /* 0 = ttvt not called yet for this device */ fdflag = (!isatty(0) || !isatty(1)); /* Flag for stdio redirected */ debug(F101,"ttopen fdflag","",fdflag); ttmdm = modem; /* Make this available to other fns */ xlocal = *lcl; /* Make this available to other fns *//* Code for handling bidirectional tty lines goes here. *//* Use specified method for turning off logins and suppressing getty. */#ifdef ACUCNTRL /* Should put call to priv_on() here, but that would be very risky! */ acucntrl("disable",ttname); /* acucntrl() program. */ /* and priv_off() here... */#else#ifdef ATT7300 if ((attmodem & DOGETY) == 0) /* offgetty() program. */ attmodem |= offgetty(ttname); /* Remember response. */#endif /* ATT7300 */#endif /* ACUCNTRL *//* In the following section, we open the tty device for read/write. If a modem has been specified via "set modem" prior to "set line" then the O_NDELAY parameter is used in the open, provided this symbol is defined (e.g. in fcntl.h), so that the program does not hang waiting for carrier (which in most cases won't be present because a connection has not been dialed yet). O_NDELAY is removed later on in ttopen(). It would make more sense to first determine if the line is local before doing this, but because ttyname() requires a file descriptor, we have to open it first. See do_open(). Now open the device using the desired treatment of carrier. If carrier is REQUIRED, then open could hang forever, so an optional timer is provided. If carrier is not required, the timer should never go off, and should do no harm...*/ ttotmo = 0; /* Flag no timeout */ debug(F101,"ttopen timo","",timo); debug(F101,"ttopen xlocal","",xlocal); if (timo > 0) { int xx; saval = signal(SIGALRM,timerh); /* Timed, set up timer. */ xx = alarm(timo); /* Timed open() */ debug(F101,"ttopen alarm","",xx); if (#ifdef CK_POSIX_SIG sigsetjmp(sjbuf,1)#else setjmp(sjbuf)#endif /* CK_POSIX_SIG */ ) { ttotmo = 1; /* Flag timeout. */ } else ttyfd = do_open(ttname); ttimoff(); debug(F111,"ttopen","modem",modem); debug(F101,"ttopen ttyfd","",ttyfd); debug(F101,"ttopen alarm return","",ttotmo); } else { errno = 0; ttyfd = do_open(ttname); } debug(F111,"ttopen ttyfd",ttname,ttyfd); if (ttyfd < 0) { /* If couldn't open, fail. */ debug(F101,"ttopen errno","",errno); if (errno > 0 && !quiet) perror(ttname); /* Print message */#ifdef ATT7300 if (attmodem & DOGETY) /* was getty(1m) running before us? */ ongetty(ttnmsv); /* yes, restart on tty line */ attmodem &= ~DOGETY; /* no phone in use, getty restored */#else#ifdef ACUCNTRL /* Should put call to priv_on() here, but that would be risky! */ acucntrl("enable",ttname); /* acucntrl() program. */ /* and priv_off() here... */#endif /* ACUNTRL */#endif /* ATT7300 */ signal(SIGINT,occt); /* Put old Ctrl-C trap back. */ if (errno == EACCES) { /* Device is protected against user */ debug(F110,"ttopen EACCESS",ttname,0); /* Return -4 */ return(-4); } else return(ttotmo ? -2 : -1); /* Otherwise -2 if timeout, or -1 */ }#ifdef Plan9 /* take this opportunity to open the control channel */ if (p9openttyctl(ttname) < 0)#else /* Make sure it's a real tty. */ if (!isatty(ttyfd) && strcmp(ttname,"/dev/null"))#endif /* Plan9 */ { fprintf(stderr,"%s is not a terminal device\n",ttname); debug(F111,"ttopen not a tty",ttname,errno); close(ttyfd); ttyfd = -1; wasclosed = 1; signal(SIGINT,occt); return(-1); }#ifdef aegis /* Apollo C runtime claims that console pads are tty devices, which * is reasonable, but they aren't any go
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -