Logo Search packages:      
Sourcecode: yiyantang version File versions  Download package

setty.c

/************************************************************************** 
 * yyt - Psuedo tty converts amoung different Chinese encodings.
 *
 * Copyright (C) 2001 ha shao
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
 *
 **************************************************************************/

/* helper functions for setup tty. 
 * There is already a forkpty function in pty.h (libutil.a), so we
 * only handle tty mode setting here. 
 * */

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stropts.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>

#include "setty.h"
#include "yyt_util.h"

extern char *ptsname (int);

static struct termios save_termios;
static int ttysavefd = -1;

#undef RESET
#undef RAW
#undef CBREAK

static enum
{ RESET, RAW, CBREAK }
ttystate = RESET;

#if 0                   /* forkpty definition start here. */
int ptym_open (char *pts_name)
{
    int fdm;
    char *ptr;

    strcpy (pts_name, "/dev/ptmx");
    if ((fdm = open (pts_name, O_RDWR)) < 0)
      return (-1);

    if (grantpt (fdm) < 0)
    {
      close (fdm);
      return (-2);
    }
    if (unlockpt (fdm) < 0)
    {
      close (fdm);
      return (-3);
    }

    if ((ptr = ptsname (fdm)) == NULL)
    {
      close (fdm);
      return (-4);
    }
    strcpy (pts_name, ptr);
    return (fdm);
}

int ptys_open (int fdm, char *pts_name)
{
    int fds;

    if ((fds = open (pts_name, O_RDWR)) < 0)
    {
      close (fdm);
      return (-5);
    }
#if 0
    /* Damn! Linux won't do ptem! */
    if (ioctl (fds, I_PUSH, "ptem") < 0)
    {
      close (fdm);
      close (fds);
      return (-6);
    }
    if (ioctl (fds, I_PUSH, "ldterm") < 0)
    {
      close (fdm);
      close (fds);
      return (-7);
    }
    if (ioctl (fds, I_PUSH, "ttcompat") < 0)
    {
      close (fdm);
      close (fds);
      return (-8);
    }
#endif /* #if 0 for ptem in Linux */
    return (fds);
}


pid_t forkpty (int *ptrfdm, char *slave_name,
      const struct termios * slave_termios,
      const struct winsize * slave_winsize)
{
    int fdm, fds;
    pid_t pid;
    char pts_name[25];

    if ((fdm = ptym_open (pts_name)) < 0)
      err_sys ("can't open master pty: %s", pts_name);
    if (slave_name != NULL)
      strcpy (slave_name, pts_name);
    if ((pid = fork ()) < 0)
      return (-1);
    else if (pid == 0)
    {
      if (setsid () < 0)
          err_sys ("setsid error");

      if ((fds = ptys_open (fdm, pts_name)) < 0)
          err_sys ("can't open slave pty: %d\n", fds);

      //    close (fdm);
#if defined(TIOCSCTTY) && !defined(CIBAUD)
      if (ioctl (fds, TIOCSCTTY, (char *) 0) < 0)
          err_sys ("TIOCSCTTY error");
#endif /* TIOCSCTTY */

      if (slave_termios != NULL)
      {
          if (tcsetattr (fds, TCSANOW, slave_termios) < 0)
            err_sys ("tcsetattr error on slave pty");
      }
      if (slave_winsize != NULL)
      {
          if (ioctl (fds, TIOCSWINSZ, slave_winsize) < 0)
            err_sys ("TIOCSWINSZ error on slave pty");
      }
      if (dup2 (fds, STDIN_FILENO) != STDIN_FILENO)
          err_sys ("dup2 error to stdin");
      if (dup2 (fds, STDOUT_FILENO) != STDOUT_FILENO)
          err_sys ("dup2 error to stdout");
      if (dup2 (fds, STDERR_FILENO) != STDERR_FILENO)
          err_sys ("dup2 error to stderr");
      if (fds > STDERR_FILENO)
          close (fds);
      return (0);
    }
    else
    {
      *ptrfdm = fdm;
      return (pid);
    }
}

#endif /* End forkpty setup. */

int tty_raw (int fd)
{
    struct termios buf;

    if (tcgetattr (fd, &save_termios) < 0)
      return (-1);

    buf = save_termios;
    buf.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
    buf.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
    buf.c_cflag &= ~(CSIZE | PARENB);
    buf.c_cflag |= CS8;

    buf.c_oflag &= ~(OPOST);

    buf.c_cc[VMIN] = 1;
    buf.c_cc[VTIME] = 0;

    if (tcsetattr (fd, TCSAFLUSH, &buf) < 0)
      return (-1);
    ttystate = RAW;
    ttysavefd = fd;
    return (0);
}

int tty_reset (int fd)
{
    if (ttystate != CBREAK && ttystate != RAW)
      return (0);
    if (tcsetattr (fd, TCSAFLUSH, &save_termios) < 0)
      return (-1);
    ttystate = RESET;
    return (0);
}

void tty_atexit (void)
{
    if (ttysavefd >= 0)
      tty_reset (ttysavefd);
    printf ("exit...\n");
}

struct termios * tty_termios (void)
{
    return (&save_termios);
}

int tty_resize(int fds, const struct winsize * slave_winsize)
{
      int ret; 
      if ((ret = ioctl (fds, TIOCSWINSZ, slave_winsize)) < 0)
            err_sys ("TIOCSWINSZ error on slave pty");
      return ret;
}

/* vi: set ts=4:ws=4: */

Generated by  Doxygen 1.6.0   Back to index