#include "expect_cf.h"
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_FCNTL_H
# include <sys/fcntl.h>
#else
# include <fcntl.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include <signal.h>
#include <setjmp.h>
#include <sys/file.h>
#define EXP_AVOID_INCLUDING_TCL_H 1
#include "expect_comm.h"
#include "exp_rename.h"
#include "exp_pty.h"
#include <errno.h>
void debuglog();
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#ifdef O_NOCTTY
#define RDWR ((O_RDWR)|(O_NOCTTY))
#else
#define RDWR O_RDWR
#endif
static int locked = FALSE;
static char lock[] = "/tmp/ptylock.XXXX";
static char locksrc[50] = "/tmp/expect.pid";
static int i_read_errno;
static jmp_buf env;
static int env_valid = FALSE;
static RETSIGTYPE
sigalarm_handler(n)
int n;
{
#ifdef REARM_SIG
signal(SIGALRM,sigalarm_handler);
#endif
if (env_valid) longjmp(env,1);
}
static int
i_read(fd,buffer,length,timeout)
int fd;
char *buffer;
int length;
int timeout;
{
int cc = -2;
alarm(timeout);
if (1 != setjmp(env)) {
env_valid = TRUE;
cc = read(fd,buffer,length);
}
env_valid = FALSE;
i_read_errno = errno;
alarm(0);
return(cc);
}
static RETSIGTYPE (*oldAlarmHandler)();
static RETSIGTYPE (*oldHupHandler)();
static time_t current_time;
int
exp_pty_test_start()
{
int lfd;
oldAlarmHandler = signal(SIGALRM,sigalarm_handler);
#ifndef O_NOCTTY
oldAlarmHandler = signal(SIGHUP,SIG_IGN);
#endif
time(¤t_time);
sprintf(locksrc,"/tmp/expect.%d",getpid());
(void) unlink(locksrc);
if (-1 == (lfd = creat(locksrc,0777))) {
static char buf[256];
exp_pty_error = buf;
sprintf(exp_pty_error,"can't create %s, errno = %d\n",locksrc, errno);
return(-1);
}
close(lfd);
return 0;
}
void
exp_pty_test_end()
{
signal(SIGALRM,oldAlarmHandler);
#ifndef O_NOCTTY
signal(SIGALRM,oldHupHandler);
#endif
(void) unlink(locksrc);
}
int
exp_pty_test(master_name,slave_name,bank,num)
char *master_name;
char *slave_name;
int bank;
char *num;
{
int master, slave;
int cc;
char c;
if (exp_pty_lock(bank,num) == 0) {
debuglog("pty master (%s) is locked...skipping\r\n",master_name);
return(-1);
}
if (0 > (master = open(master_name,RDWR))) return(-1);
#ifdef __QNX__
if (1) return master;
#endif
#ifdef HAVE_PTYTRAP
if (access(slave_name, R_OK|W_OK) != 0) {
debuglog("could not open slave for pty master (%s)...skipping\r\n",
master_name);
(void) close(master);
return -1;
}
return(master);
#else
if (0 > (slave = open(slave_name,RDWR))) {
(void) close(master);
return -1;
}
(void) close(slave);
cc = i_read(master,&c,1,10);
(void) close(master);
if (!(cc == 0 || cc == -1)) {
debuglog("%s slave open, skipping\r\n",slave_name);
locked = FALSE;
return -1;
}
if (0 > (master = open(master_name,RDWR))) return(-1);
if (0 > (slave = open(slave_name,RDWR))) {
(void) close(master);
return -1;
}
(void) close(master);
cc = i_read(slave,&c,1,10);
(void) close(slave);
if (!(cc == 0 || cc == -1)) {
debuglog("%s master open, skipping\r\n",master_name);
return -1;
}
debuglog("using master pty %s\n",master_name);
return(open(master_name,RDWR));
#endif
}
void
exp_pty_unlock()
{
if (locked) {
(void) unlink(lock);
locked = FALSE;
}
}
int
exp_pty_lock(bank,num)
int bank;
char *num;
{
struct stat statbuf;
if (locked) {
unlink(lock);
locked = FALSE;
}
sprintf(lock,"/tmp/ptylock.%c%s",bank,num);
if ((0 == stat(lock,&statbuf)) &&
(statbuf.st_mtime+3600 < current_time)) {
(void) unlink(lock);
}
if (-1 == (link(locksrc,lock))) locked = FALSE;
else locked = TRUE;
return locked;
}