/* 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 #include /* ctermid decl */ #include #include #include #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 #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_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, s48_value scmvec) { struct termios t; int result = tcgetattr(fd, &t); // 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_fixnum(t.c_iflag >> 24)); S48_VECTOR_SET(scmvec, 1, s48_enter_fixnum(t.c_iflag & 0xffffff)); S48_VECTOR_SET(scmvec, 2, s48_enter_fixnum(t.c_oflag >> 24)); S48_VECTOR_SET(scmvec, 3, s48_enter_fixnum(t.c_oflag & 0xffffff)); S48_VECTOR_SET(scmvec, 4, s48_enter_fixnum(t.c_cflag >> 24)); S48_VECTOR_SET(scmvec, 5, s48_enter_fixnum(t.c_cflag & 0xffffff)); S48_VECTOR_SET(scmvec, 6, s48_enter_fixnum(t.c_lflag >> 24)); S48_VECTOR_SET(scmvec, 7, s48_enter_fixnum(t.c_lflag & 0xffffff)); S48_VECTOR_SET(scmvec, 8, s48_enter_fixnum(cfgetispeed(&t))); S48_VECTOR_SET(scmvec, 9, s48_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); }