scsh-0.5/scsh/tty1.c

140 lines
4.0 KiB
C

/* To do:
* - Replace explicit 8/24 splits with macros.
* - We need to pass the control-chars vecs in as Scheme
* strings, and test the length before doing the memcpy.
*/
/*
* Scheme48/scsh terminal control interface.
* Routines that require custom C support.
* Copyright (c) 1995 by Brian D. Carlstrom
* Re-written by Olin.
*/
#include <errno.h>
#include <unistd.h>
#include <stdio.h> /* ctermid decl */
#include <termios.h>
#include <string.h>
#include <sys/types.h>
#include "../scheme48.h"
/* This #include is for the #ifdef'd code in open_ctty() below, and
** is therefor ifdef'd identically.
*/
#if defined(TIOCSCTTY) && !defined(CIBAUD)
#include <sys/ioctl.h>
#endif
#include "tty1.h" /* Make sure the .h interface agrees with the code. */
/*****************************************************************************/
int scheme_tcgetattr(int fd, char *control_chars,
int *iflag_hi8, int *iflag_lo24,
int *oflag_hi8, int *oflag_lo24,
int *cflag_hi8, int *cflag_lo24,
int *lflag_hi8, int *lflag_lo24,
int *ispeed, int *ospeed)
{
struct termios t;
int result = tcgetattr(fd, &t);
if (result != -1) {
memcpy(control_chars, t.c_cc, NCCS);
*iflag_hi8 =t.c_iflag >> 24; *iflag_lo24=t.c_iflag & 0xffffff;
*oflag_hi8 =t.c_oflag >> 24; *oflag_lo24=t.c_oflag & 0xffffff;
*cflag_hi8 =t.c_cflag >> 24; *cflag_lo24=t.c_cflag & 0xffffff;
*lflag_hi8 =t.c_lflag >> 24; *lflag_lo24=t.c_lflag & 0xffffff;
*ispeed=cfgetispeed(&t);
*ospeed=cfgetospeed(&t);
}
return result;
}
int scheme_tcgetattrB(int fd, char *control_chars, scheme_value scmvec)
{
struct termios t;
int result = tcgetattr(fd, &t);
int *ivec = ADDRESS_AFTER_HEADER(scmvec, int);
if (result != -1) {
memcpy(control_chars, t.c_cc, NCCS);
ivec[0] = ENTER_FIXNUM(t.c_iflag >> 24);
ivec[1] = ENTER_FIXNUM(t.c_iflag & 0xffffff);
ivec[2] = ENTER_FIXNUM(t.c_oflag >> 24);
ivec[3] = ENTER_FIXNUM(t.c_oflag & 0xffffff);
ivec[4] = ENTER_FIXNUM(t.c_cflag >> 24);
ivec[5] = ENTER_FIXNUM(t.c_cflag & 0xffffff);
ivec[6] = ENTER_FIXNUM(t.c_lflag >> 24);
ivec[7] = ENTER_FIXNUM(t.c_lflag & 0xffffff);
ivec[8] = ENTER_FIXNUM(cfgetispeed(&t));
ivec[9] = ENTER_FIXNUM(cfgetospeed(&t));
}
return result;
}
/*****************************************************************************/
int scheme_tcsetattr(int fd, int option,
const char *control_chars,
int iflag_hi8, int iflag_lo24,
int oflag_hi8, int oflag_lo24,
int cflag_hi8, int cflag_lo24,
int lflag_hi8, int lflag_lo24,
int ispeed, int ospeed,
int min, int time)
{
struct termios t;
memcpy(t.c_cc, control_chars, NCCS);
/* This first clause of this conditional test will hopefully
** resolve the branch at compile time. However, since VMIN/VEOF
** and VTIME/VEOL are allowed by POSIX to colllide, we have to check.
** If they do collide, we set EOF & EOL in canonical mode, and MIN & TIME
** in raw mode. Ah, Unix.
*/
if( (VMIN != VEOF && VTIME != VEOL) || !(t.c_lflag & ICANON) ) {
t.c_cc[VMIN] = min;
t.c_cc[VTIME] = time;
}
t.c_iflag = (iflag_hi8 << 24) | iflag_lo24;
t.c_oflag = (oflag_hi8 << 24) | oflag_lo24;
t.c_cflag = (cflag_hi8 << 24) | cflag_lo24;
t.c_lflag = (lflag_hi8 << 24) | lflag_lo24;
cfsetispeed(&t, ispeed);
cfsetospeed(&t, ospeed);
return tcsetattr(fd, option, &t);
}
/*****************************************************************************/
int open_ctty(const char *ttyname, int flags)
{
int fd = open(ttyname, flags);
#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(__hpux)
/* 4.3+BSD way to acquire control tty. !CIBAUD rules out SunOS.
** This code stolen from Steven's *Advanced Prog. in the Unix Env.*
*/
if( (fd >= 0) && (ioctl(fd, TIOCSCTTY, (char *) 0) < 0) ) {
int e = errno;
close(fd);
errno = e;
return -1;
}
#endif
return fd;
}
char *scm_ctermid() { return ctermid(0); }