tty.c
来自「bbs server linux平台下软件源码」· C语言 代码 · 共 615 行 · 第 1/2 页
C
615 行
/* $Id: tty.c,v 1.1 2003/04/17 17:42:43 czz Exp $ *//* * TTY.C ------ Routines for pseudo terminal allocation. * Various platforms are supported. * * Copyright (C) 1992, 1993 Yongguang Zhang * All right reserved. (ygz@cs.purdue.edu) */#ifndef lintstatic char *rcs_id = "$Id: tty.c,v 1.1 2003/04/17 17:42:43 czz Exp $";#endif /* lint */#include "config.h"/* * Functions get_pty() and pty_search() in this file are adopted from * X11R5 xterm, copyrighted by DEC & MIT. */#ifdef hpux# define PTYCHAR1 "zyxwvutsrqp"# define PTYCHAR2 "fedcba9876543210"# define PTYDEV "/dev/ptym/ptyxx"# define TTYDEV "/dev/pty/ttyxx"#else /* !hpux */# define PTYCHAR1 "pqrstuvwxyzPQRSTUVWXYZ"# define PTYCHAR2 "0123456789abcdef"# define PTYDEV "/dev/ptyxx"# define TTYDEV "/dev/ttyxx"#endif /* !hpux */#ifdef SYSVextern char *ptsname();#endif#ifdef hpux# include <sys/utsname.h>#endifstatic char ptydev[32];static char ttydev[32];static int pty_search();/* This function opens up a pty master and stuffs its value into pty. * If it finds one, it returns a value of 0. If it does not find one, * it returns a value of !0. This routine is designed to be re-entrant, * so that if a pty master is found and later, we find that the slave * has problems, we can re-enter this function and get another one. */int get_pty(pty)int *pty;{ strcpy(ptydev, PTYDEV); strcpy(ttydev, TTYDEV);#if defined(SYSV) && defined(SYSV386) if (pty_search(pty) == 0) return 0;#endif /* SYSV && SYSV386 */#if (defined(att) || defined(ATT)) && (!defined(_SEQUENT_)) { if ((*pty = open("/dev/ptmx", O_RDWR)) < 0) return 1;# if defined(SVR4) || defined(SYSV386) strcpy(ttydev, ptsname(*pty));# endif return 0; }# define GET_PTY_DONE#endif /* ATT */#if defined(AIXV3) || defined(_IBMR2) { if ((*pty = open("/dev/ptc", O_RDWR)) < 0) return 1; strcpy(ttydev, (char *) ttyname(*pty)); return 0; }# define GET_PTY_DONE#endif#if defined(sgi) && (IRIX >= 4) { char *tty_name; tty_name = _getpty(pty, O_RDWR, 0622, 0); if (tty_name == 0) return 1; strcpy(ttydev, tty_name); return 0; }# define GET_PTY_DONE#endif#ifdef __convex__ { char *pty_name, *getpty(); while ((pty_name = getpty()) != NULL) { if ((*pty = open(pty_name, O_RDWR)) >= 0) { strcpy(ptydev, pty_name); strcpy(ttydev, pty_name); ttydev[5] = 't'; return 0; } } return 1; }# define GET_PTY_DONE#endif /* __convex__ */#if defined(sequent) || defined(_SEQUENT_) { char *sl[2], *ms[2]; *pty = getpseudotty(sl, ms); strcpy(ptydev, ms[0]); strcpy(ttydev, sl[0]); return (*pty >= 0 ? 0 : 1); }# define GET_PTY_DONE#endif /* sequent */#if (defined(sgi) && (IRIX == 3)) || (defined(umips) && defined (SYSTYPE_SYSV)) { struct stat fstat_buf; int tty; *pty = open("/dev/ptc", O_RDWR); if (*pty < 0 || (fstat(*pty, &fstat_buf)) < 0) { return (1); } sprintf(ttydev, "/dev/ttyq%d", minor(fstat_buf.st_rdev));# ifndef sgi sprintf(ptydev, "/dev/ptyq%d", minor(fstat_buf.st_rdev)); if ((*tty = open(ttydev, O_RDWR)) < 0) { close(*pty); return (1); }# endif /* !sgi */ /* * got one! */ return (0); }# define GET_PTY_DONE#endif /* sgi or umips */#ifndef GET_PTY_DONE return pty_search(pty);#endif}/* * Called from get_pty to iterate over likely pseudo terminals * we might allocate. Used on those systems that do not have * a functional interface for allocating a pty. * Returns 0 if found a pty, 1 if fails. */static int pty_search(pty)int *pty;{ static int devindex, letter = 0;#ifdef O_NOCTTY# define O_RDWRPTY (O_RDWR | O_NOCTTY)#else# define O_RDWRPTY (O_RDWR)#endif#ifdef CRAY for (; devindex < 256; devindex++) { sprintf(ttydev, "/dev/ttyp%03d", devindex); sprintf(ptydev, "/dev/pty/%03d", devindex); if ((*pty = open(ptydev, O_RDWRPTY)) >= 0) { /* * We need to set things up for our next entry * * into this function! */ (void) devindex++;# ifdef TIOCEXCL ioctl(*pty, TIOCEXCL, (char *) 0);# endif return 0; } }#else /* CRAY */ while (PTYCHAR1[letter]) { ttydev[strlen(ttydev) - 2] = PTYCHAR1[letter]; ptydev[strlen(ptydev) - 2] = PTYCHAR1[letter]; while (PTYCHAR2[devindex]) { ttydev[strlen(ttydev) - 1] = PTYCHAR2[devindex]; ptydev[strlen(ptydev) - 1] = PTYCHAR2[devindex]; if ((*pty = open(ptydev, O_RDWRPTY)) >= 0) { /* * We need to set things up for our next entry * * into this function! */# ifdef sun int dummy; ptydev[5] = 't'; chown(ptydev, 0, 0); chmod(ptydev, 0600); ptydev[5] = 'p'; if ((ioctl(*pty, TIOCGPGRP, &dummy) == -1) && errno == EIO) { (void) devindex++; return 0; } close(*pty);# else (void) devindex++;# ifdef TIOCEXCL ioctl(*pty, TIOCEXCL, (char *) 0);# endif return 0;# endif } devindex++; } devindex = 0; letter++; }#endif /* CRAY else */ /* * We were unable to allocate a pty master! Return an error * condition and let our caller terminate cleanly. */ return 1;}/* given master fildes, get the slave side tty */int get_tty(master, tty)int master;int *tty;{ int t;#if defined(POSIX) || defined(SVR4) || defined(__convex__) int pgrp = setsid();#else int pgrp = getpid();#endif#ifdef USE_PTYS setpgrp(); grantpt(master); unlockpt(master); if ((*tty = open(ptsname(master), O_RDWR)) < 0) return 1; /* error */ if (ioctl(*tty, I_PUSH, "ptem") < 0) return 1; /* error */# if !defined(SVR4) && !defined(SYSV386) if (!getenv("CONSEM") && ioctl(*tty, I_PUSH, "consem") < 0) { return 1;# endif if (ioctl(*tty, I_PUSH, "ldterm") < 0) return 1;# ifdef SVR4 if (ioctl(*tty, I_PUSH, "ttcompat") < 0) return 1;# endif#else /* ! USE_PTYS */# ifdef TIOCNOTTY t = open("/dev/tty", O_RDWR); if (t >= 0) { (void) ioctl(t, TIOCNOTTY, (char *) 0); (void) close(t); }# endif *tty = open(ttydev, O_RDWR); if (*tty < 0) { perror(ttydev); return 1; }# ifdef _POSIX_JOB_CONTROL if (tcsetpgrp(*tty, pgrp) < 0) {# endif# ifdef SYSV setpgrp();# else# ifdef TIOCSCTTY (void) setsid(); (void) ioctl(*tty, TIOCSCTTY, 0);# endif# ifdef TIOCSPGRP (void) ioctl(*tty, TIOCSPGRP, (char *) &pgrp);# endif setpgrp(0, 0); close(open(ttydev, O_WRONLY, 0)); setpgrp(0, pgrp);# endif /* SYSV */# ifdef _POSIX_JOB_CONTROL }# endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?