/* 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, 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); }