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 + -
显示快捷键?