#include <stdio.h>
#include <signal.h>
#if defined(SIGCLD) && !defined(SIGCHLD)
#define SIGCHLD SIGCLD
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <signal.h>
#include <setjmp.h>
#include "expect_cf.h"
#include "exp_rename.h"
#include "exp_tty_in.h"
#include "exp_pty.h"
void debuglog();
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
static char master_name[] = "/dev/ptyXX";
static char slave_name[] = "/dev/ttyXX";
static char *tty_type;
static char *tty_bank;
static char *tty_num;
char *exp_pty_slave_name;
char *exp_pty_error;
static void
pty_stty(s,name)
char *s;
char *name;
{
#define MAX_ARGLIST 10240
char buf[MAX_ARGLIST];
RETSIGTYPE (*old)();
#ifdef STTY_READS_STDOUT
sprintf(buf,"/bin/stty %s > %s",s,name);
#else
sprintf(buf,"/bin/stty %s < %s",s,name);
#endif
old = signal(SIGCHLD, SIG_DFL);
system(buf);
signal(SIGCHLD, old);
}
int exp_dev_tty;
static int knew_dev_tty;
#ifdef TIOCGWINSZ
static struct winsize winsize = {0, 0};
#endif
#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
static struct ttysize winsize = {0, 0};
#endif
exp_tty exp_tty_original;
#define GET_TTYTYPE 0
#define SET_TTYTYPE 1
static void
ttytype(request,fd,ttycopy,ttyinit,s)
int request;
int fd;
int ttycopy;
int ttyinit;
char *s;
{
static struct tchars tc;
static struct ltchars lc;
static struct winsize win;
static int lb;
static int l;
if (request == GET_TTYTYPE) {
if (-1 == ioctl(fd, TIOCGETP, (char *)&exp_tty_original)
|| -1 == ioctl(fd, TIOCGETC, (char *)&tc)
|| -1 == ioctl(fd, TIOCGETD, (char *)&l)
|| -1 == ioctl(fd, TIOCGLTC, (char *)&lc)
|| -1 == ioctl(fd, TIOCLGET, (char *)&lb)
|| -1 == ioctl(fd, TIOCGWINSZ, (char *)&win)) {
knew_dev_tty = FALSE;
exp_dev_tty = -1;
}
#ifdef TIOCGWINSZ
ioctl(fd,TIOCGWINSZ,&winsize);
#endif
#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
ioctl(fd,TIOCGSIZE,&winsize);
#endif
} else {
if (ttycopy && knew_dev_tty) {
(void) ioctl(fd, TIOCSETP, (char *)&exp_tty_current);
(void) ioctl(fd, TIOCSETC, (char *)&tc);
(void) ioctl(fd, TIOCSLTC, (char *)&lc);
(void) ioctl(fd, TIOCLSET, (char *)&lb);
(void) ioctl(fd, TIOCSETD, (char *)&l);
(void) ioctl(fd, TIOCSWINSZ, (char *)&win);
#ifdef TIOCSWINSZ
ioctl(fd,TIOCSWINSZ,&winsize);
#endif
#if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
ioctl(fd,TIOCGSIZE,&winsize);
#endif
}
#ifdef __CENTERLINE__
#undef DFLT_STTY
#define DFLT_STTY "sane"
#endif
#ifdef DFLT_STTY
if (ttyinit) {
pty_stty(DFLT_STTY,slave_name);
}
#endif
if (s) {
pty_stty(s,slave_name);
}
}
}
void
exp_init_pty()
{
tty_type = & slave_name[strlen("/dev/")];
tty_bank = &master_name[strlen("/dev/pty")];
tty_num = &master_name[strlen("/dev/ptyp")];
exp_dev_tty = open("/dev/tty",O_RDWR);
#if experimental
if (exp_dev_tty == -1) {
int master = getptymaster();
fcntl(master,F_SETFD,1);
setpgrp(0,0);
close(0);
close(1);
getptyslave(exp_get_var(exp_interp,"stty_init"));
close(2);
fcntl(0,F_DUPFD,2);
}
#endif
knew_dev_tty = (exp_dev_tty != -1);
if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0);
}
int
getptymaster()
{
int master = -1;
char *hex, *bank;
struct stat statbuf;
exp_pty_error = 0;
if (exp_pty_test_start() == -1) return -1;
for (bank = "pqrstuvwxyzPQRSTUVWXYZ";*bank;bank++) {
*tty_bank = *bank;
*tty_num = '0';
if (stat(master_name, &statbuf) < 0) break;
for (hex = "0123456789abcdef";*hex;hex++) {
*tty_num = *hex;
strcpy(slave_name,master_name);
*tty_type = 't';
master = exp_pty_test(master_name,slave_name,
*tty_bank,tty_num);
if (master >= 0) goto done;
}
}
done:
exp_pty_test_end();
exp_pty_slave_name = slave_name;
return(master);
}
void
exp_slave_control(master,control)
int master;
int control;
{
}
int
getptyslave(ttycopy,ttyinit,stty_args)
int ttycopy;
int ttyinit;
char *stty_args;
{
int slave;
if (0 > (slave = open(slave_name, O_RDWR))) return(-1);
if (0 == slave) {
fcntl(0,F_DUPFD,1);
fcntl(0,F_DUPFD,2);
}
ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args);
(void) exp_pty_unlock();
return(slave);
}
void
exp_pty_exit()
{
}