139 lines
3.5 KiB
C
139 lines
3.5 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 <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. */
|
|
|
|
extern int errno;
|
|
|
|
/*****************************************************************************/
|
|
|
|
int scheme_tcgetattr(int fd, char *control_chars,
|
|
int *iflag,
|
|
int *oflag,
|
|
int *cflag,
|
|
int *lflag,
|
|
int *ispeed, int *ospeed)
|
|
{
|
|
struct termios t;
|
|
int result = tcgetattr(fd, &t);
|
|
|
|
if (result != -1) {
|
|
memcpy(control_chars, t.c_cc, NCCS);
|
|
*iflag =t.c_iflag;
|
|
*oflag =t.c_oflag;
|
|
*cflag =t.c_cflag;
|
|
*lflag =t.c_lflag;
|
|
*ispeed=cfgetispeed(&t);
|
|
*ospeed=cfgetospeed(&t);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int scheme_tcgetattrB(int fd, char *control_chars, s48_value scmvec)
|
|
{
|
|
struct termios t;
|
|
int result = tcgetattr(fd, &t);
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
S48_GC_PROTECT_1(scmvec);
|
|
// JMG int *ivec = ADDRESS_AFTER_HEADER(scmvec, int);
|
|
|
|
if (result != -1) {
|
|
memcpy(control_chars, t.c_cc, NCCS);
|
|
S48_VECTOR_SET(scmvec, 0, s48_enter_integer(t.c_iflag));
|
|
S48_VECTOR_SET(scmvec, 1, s48_enter_integer(t.c_oflag));
|
|
S48_VECTOR_SET(scmvec, 2, s48_enter_integer(t.c_cflag));
|
|
S48_VECTOR_SET(scmvec, 3, s48_enter_integer(t.c_lflag));
|
|
S48_VECTOR_SET(scmvec, 4, s48_enter_fixnum(cfgetispeed(&t)));
|
|
S48_VECTOR_SET(scmvec, 5, s48_enter_fixnum(cfgetospeed(&t)));
|
|
}
|
|
S48_GC_UNPROTECT();
|
|
return result;
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
int scheme_tcsetattr(int fd, int option,
|
|
const char *control_chars,
|
|
int iflag,
|
|
int oflag,
|
|
int cflag,
|
|
int lflag,
|
|
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;
|
|
t.c_oflag = oflag;
|
|
t.c_cflag = cflag;
|
|
t.c_lflag = lflag;
|
|
|
|
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); }
|