[comp.unix.questions] To curse or not to curse

jules@iisat.UUCP (Jules d'Entremont) (06/05/89)

A friend of mine is converting some programs from Turbo Pascal 5.0 to
work in Unix C.  He's having difficulty translating a Turbo Pascal
function (getch ?) which reads in a character from the keyboard unechoed,
and without waiting for a carriage return.  I told him to use curses and
set cbreak() and noecho() modes.  He thinks he shouldn't have to invoke
curses for such a simple task.  Is there another way to do this?  What
is the best, most portable way to do it?

-- 
Jules d'Entremont	Phone: 454-5631 (Home)  465-5535 (Office)
UUCP:		{uunet,utai,watmath}!dalcs!iisat!jules
Bitnet/Uucp:	jules@iisat.uucp
Arpanet:	jules%iisat.uucp@uunet.uu.net

kucharsk@uts.amdahl.com (William Kucharski) (06/06/89)

Here's a program which demonstrates one way of doing things:

#include <stdio.h>
#include <termio.h>

main()
{
        int     a,c;
        char    ch[BUF];
        struct termio o,t;

	if (ioctl(0, TCGETA, &o))
		perror("ioctl: get");

        t = o;
        t.c_lflag = 0;		/* shut off everything */
        t.c_cc[VEOF] = 1;	/* MIN chars == 1 */

        if (ioctl(0, TCSETA, &t))
                perror("ioctl: set");

        for (a = 0; a < BUF; a++) {
                c = getc(stdin);
                ch[a] = (char) c;
                printf(".");
        }

	ch[BUF] = '\0';	/* NULL terminate it */

        printf("\n%s\n", ch);

        if (ioctl(0, TCSETA, &o))
                perror("ioctl: set back");
}

-- 
					William Kucharski

ARPA: kucharsk@uts.amdahl.com
UUCP: ...!{ames,decwrl,sun,uunet}!amdahl!kucharsk

Disclaimer:  The opinions expressed above are my own, and may not agree with
	     those of any other sentient being, not to mention those of my 
	     employer.  So there.

vijay@bradley.UUCP (06/07/89)

>Written  9:44 pm  Jun  4, 1989 by jules@iisat.UUCP
>/* ---------- "To curse or not to curse" ---------- */
>A friend of mine is converting some programs from Turbo Pascal 5.0 to
>work in Unix C.  He's having difficulty translating a Turbo Pascal
>function (getch ?) which reads in a character from the keyboard unechoed,
>and without waiting for a carriage return.  I told him to use curses and
>set cbreak() and noecho() modes.  He thinks he shouldn't have to invoke
>curses for such a simple task.  Is there another way to do this?  What
>is the best, most portable way to do it?
>
>-- 
>Jules d'Entremont	Phone: 454-5631 (Home)  465-5535 (Office)

>Written 12:46 pm  Jun  5, 1989 by kucharsk@uts.amdahl.com 
>Here's a program which demonstrates one way of doing things:
>
>#include <stdio.h>
>#include <termio.h>
          ^^^^^^^^^^^^^^^^???
>
>main()
>{
>    ...
>}

Where is the file termio.h? It is not there in /usr/include.
I am using UNIX 4.3 BSD

Thanx

=============================================================I 
  /    /                 E-mail: vijay@bradley.edu           I
 /    / *   *  ___               ...!uiucdcs!bradley!vijay   I
 /  /  /   /  /  /  /  / I===================================I
 //___/___/__/_\/__/__/  I "A duck walks in a drug store and 
         /           /   I  says. 'Give me a chapstick, and 
        /           /    I  put it on my bill!'" 
     __/         __/     I  - Judge Harry Stone, Night Court
===============================================================

jiii@visdc.UUCP (John E Van Deusen III) (06/07/89)

In article <36@iisat.UUCP> jules@iisat.UUCP (Jules d'Entremont) writes:
>
> ... converting some programs from Turbo Pascal 5.0 to work in  Unix C
> [and] having difficulty translating a Turbo Pascal function (getch ?)
> which reads in a character from the keyboard unechoed, ... without
> waiting for a carriage return. ...  What is the best, most portable
> way to do it?

There are two fundamental differences in the I/O handling of Pascal and
of UNIX/C.  First of all, Pascal does not really have a universal
standard I/O interface.  There have evolved many extensions to the
language, and (getch ?) is one of those.  As of the time I gave up in
disgust, scrapped thousands of lines of Pascal systems code, and started
using C exclusively; that function was not in common use.  If (getch ?)
works like getchar(3S) and returns a new line character to denote the
end of a line, then an emulation should be possible using ioctl(2).

A read(2) in C that has a positive return value provides no information
about the EOF status of the file.  In Pascal the return of the eof() and
eoln() functions must be available immediately after the file is reset
or read.  This is clearly untenable for purposes of terminal I/O,
because it requires prescient knowledge.  The solution that was adopted
is to cheat.  After the reset() of a terminal, the eof() and eoln()
functions return false.  Any read(x_char) that results in an EOF
condition, causes a blank to be assigned to x_char, and then eoln() and
eof() return true.  Because of this, Pascal can not distinguish a single
blank from an empty line or an empty file.  This does, however, enable a
function like (getch ?) to be implemented, since input can be stolen
from the Pascal input file without risking a change in the eof() or
eoln() returns.
--
John E Van Deusen III, PO Box 9283, Boise, ID  83707, (208) 343-1865

uunet!visdc!jiii

mhoffman@infocenter.UUCP (Mike Hoffman) (06/09/89)

in article <1cIi02Ph32aV01@amdahl.uts.amdahl.com>, kucharsk@uts.amdahl.com (William Kucharski) says:
> 
> Here's a program which demonstrates one way of doing things:
> 
> #include <stdio.h>
> #include <termio.h>
> 
> main()
> {
>         int     a,c;
>         char    ch[BUF];
>         struct termio o,t;
> 
> 	if (ioctl(0, TCGETA, &o))
> 		perror("ioctl: get");
> 
>         t = o;
>         t.c_lflag = 0;		/* shut off everything */
>         t.c_cc[VEOF] = 1;	/* MIN chars == 1 */
>
>            [rest of code deleted...]

This works OK on every system I've worked on, but I understand that
some unfortunate souls must work without the benefits of structure
assignment. To make the code more portable for those systems
without, a #define statement could indicate this capability:

          . . . 

#ifdef STRUCTURE_ASST
        t = o;                   /* copy structure in one swell foop */
#else
        t.c_iflag  = o.c_iflag;  /* copy element by element. . . */
        t.c_oflag  = o.c_oflag;
        t.c_cflag  = o.c_cflag;
        t.c_lflag  = 0;          /* inserting the desired changes */
        t.c_line   = o.c_line;
        *t.cc      = *o.cc;
        t.cc[VEOF] = 1;
#endif
          . . . [rest of code]


Michael J. Hoffman                                   Voice: (407)255-8116
Manufacturing Engineering                              FAX: (407)255-8186
Encore Computer Corporation                          Email: mhoffman
                                                    USnail: 100 N. Babcock St.
UUCP: {uunet,codas!novavax,sun,pur-ee}!gould!mhoffman       Melbourne, Fl 32935
"My opinions are my own and are not to be employed with those of my confuser."

brian@bradley.UUCP (06/13/89)

> /* Written  8:56 am  Jun  9, 1989 by mhoffman@infocenter.UUCP */
> This works OK on every system I've worked on, but I understand that
> some unfortunate souls must work without the benefits of structure
> assignment. To make the code more portable for those systems
> without, a #define statement could indicate this capability:
> 
>           . . . 
> 
> #ifdef STRUCTURE_ASST
>         t = o;                   /* copy structure in one swell foop */
> #else
>         t.c_iflag  = o.c_iflag;  /* copy element by element. . . */
>         t.c_oflag  = o.c_oflag;
>         t.c_cflag  = o.c_cflag;
>         t.c_lflag  = 0;          /* inserting the desired changes */
>         t.c_line   = o.c_line;
>         *t.cc      = *o.cc;
>         t.cc[VEOF] = 1;
> #endif
>           . . . [rest of code]

  Wouldn't this work just as well:

#ifdef STRUCTURE_ASST
	t = o;
#else
	(void) memcpy((char *) &t, (char *) &o, sizeof(t));
#endif


  Brian Michael Wendt       UUCP: {cepu,uiucdcs,noao}!bradley!brian
  Bradley University        ARPA: cepu!bradley!brian@seas.ucla.edu
  (309) 677-2335            ICBM: 40 40' N  89 34' W
  "Down, down in the basement, we hear the sound of machines..."

guy@auspex.auspex.com (Guy Harris) (06/29/89)

 >  Wouldn't this work just as well:
 >
 >#ifdef STRUCTURE_ASST
 >	t = o;
 >#else
 >	(void) memcpy((char *) &t, (char *) &o, sizeof(t));
 >#endif

Not if your implementation doesn't have "memcpy", which was added to
AT&T's UNIX C library *after* they added structure assignment to their
compiler....