Terminal modes in Ultrix's System V emulation

Leo de Wit leo at philmds.UUCP
Tue Oct 4 05:48:07 AEST 1988


When porting a database application to Ultrix (Oracle dbms), I found
out we had to use System V libraries (grrr 8-), since the Oracle
libraries depended upon them. I don't want to discuss whether Oracle's
decision to not use the native libraries is a correct one (maybe some
other time 8-), but you can imagine some of our code had to be
rewritten (most of the Unix specific stuff had already been written
before we had Oracle running on Ultrix and were aware of this
problem).

The problem:
I want to read characters from a terminal, without echo and not having
to wait for a newline. After each character I might do some processing,
based on the character read. The old solution did something along the
lines of:

#include <sgtty.h>

    struct sgttyb newbuf, oldbuf; /* oldbuf needed for restoring afterwards */

    ioctl(0,TIOCGETP,&oldbuf);
    newbuf = oldbuf;
    newbuf.sg_flags &= ~ECHO;
    newbuf.sg_flags |= CBREAK;
    ioctl(0,TIOCSETP,&newbuf);

and now filedescriptor 0 is OK for my purposes (I can use stdio or whatever
from now on and all works great).

Using System V's terminal modes there seems to be no real equivalent of
'cbreak'; so I had to use non-canonical mode to be able to read on a
per character basis (right ?).  We don't have System V manuals around
and the Ultrix manuals weren't such great help on this point; most
things I found out using Sun manuals and include files (e.g.
termio(4V)). I got this far:

#include <sys/termio.h>

    struct termio newbuf, oldbuf; /* oldbuf needed for restoring afterwards */

    ioctl(0,TCGETA,&oldbuf);
    newbuf = oldbuf;
    newbuf.c_lflag &= ~(ECHO|ICANON);
    ioctl(0,TCSETA,&newbuf);

Input is indeed not echoed and on a per character basis. However, the
newlines printed to my terminal (using fd 1 via printf's) are not
translated; so I get a simple newline, instead of newline & carriage
return. I tried to solve this by specifying

    newbuf.c_oflag |= OPOST|ONLRET;

but setting this and reinspecting with TCGETA revealed that the OPOST
bit was cleared! (and of course the output again cluttered over the screen).
    Experimenting with ICANON and OPOST showed that whenever the ICANON
bit was off in the local flag, the OPOST bit was cleared in the output
flag, so it seems to be impossible to do post-processing whenever the
mode is non-canonical.
    I also tried ioctl's on filedescriptor 1, but they have the same
effect (setting fd 0 sets also fd 1 and vice versa, which is perhaps
reasonable if you consider they affect the same device).
    I also tried using TIOCSETP and sgttyb structs (they seem to be
defined in the include files if the symbol SYSTEM_FIVE is defined) but
to no avail.

I compile and link using the -Y flag of /bin/cc which should be
sufficient to select the correct parts of include files and the correct
libraries.  Any help is very much appreciated!


                                Leo.



More information about the Comp.unix.questions mailing list