v.digit problems: STILL

Frank Davis 912/386-3889 FMD%TIFTON.BITNET at uga.cc.uga.edu
Tue Sep 20 16:32:45 EDT 1994


Hello David,

Nice job on the v.digit command.  Well, all that mapdev stuff, too.
Anyway, here's another one of my infamous, long, content-free mails:


On Thu, 15 Sep 1994 08:21:14 -0600 (MDT) David Gerdes said:
>> From jsoi at gis.joensuu.fi  Wed Sep 14 23:32:31 1994
>>
>> Hi !
>>
>> The problem with linux and v.digit is set_key.c-file. With linux you should
>us
>e
>> some bsd-stuff. Furthermore you have to add -lbsd when linkng v.digit
>>
>> There is still something wrong with linux and digitizing boards:
>> It works once (if it works at all) with same post configuration.
>> (/dev/ttyS0 etc.). If you try to use it another time the programs stops.
>>
>> I donno if it is v.digit or linux which causes this problem.
>>
>> Here is the set_key.c-file I got from Andy Burnett
>>
>> (I posted this to D. Gerdes also)
>>
>> Hope this helps you !


Hmmm.  I thought Linux was more like Sys V rev 4 rather than BSD.
Actually, I have no idea what it takes to make a *nix BSDish or
S5R4ish.  All this *nix is gnu to me. :*)

Being that I lean heavily towards ANSI C and POSIX, I made my changes
to set_key.c and flush_input.c in a much more portable manner.

Incidentally, I checked the mail archives for v.digit lock ups.
Apparently, from what I can tell, although I'm not sure, or certain,
the v.digit lock up is not unique to Linux/PCs.  One mail in Feb '94
describes a v.digit lock up on a Sun Sparc 10, which reads very similar
to the v.digit lock up described last week.

This is what I think happens:

Actually, I think the lock up problem is an infinite loop in flush_input.c.
flush_keyboard( ) calls the functions in set_key.c to flush the keyboard
buffer.  If I'm correct, the while (key_hit( buf )) goes into an infinite
loop waiting for a key to be pressed.   flush_keyboard( ) is called from
replot.c just after the "Wait. Replotting the Screen." message.  An infinite
wait loop would appear to lock the GRASS screen and the monitor.  I think
the EOL and EOF characters are redefined in set_keyboard( ) - which explains
why users can't seem to find any key to break out of the infinite
flush_keyboard( ) loop.

Here's my Linux POSIX implementation.  Also, please notice that no
additional libraries need to be linked with this solution:

    (For Linux/GRASS/PCs, just press the <ESC> key at the
     "Wait. Replotting the Screen." prompt.)

---------------------  src/mapdev/v.digit/flush_input.c  ------------
#include "vdigit.h"

#define LINUX_POSIX

#ifdef LINUX_POSIX

#include <termios.h>                          <==== include POSIX headers
#include <unistd.h>

void flush_keyboard( void );                  <==== ANSI C prototype

void flush_keyboard( void )
{
    tcflush( STDIN_FILENO, TCIFLUSH );         <==== do a POSIX flush
}

#else

...
...

#endif
------------------------------------------------------------------------



Now the new POSIX/ANSI C set_key.c code:

-------------------- src/mapdev/v.digit/set_key.c  ----------------------
/*
**  US Army Construction Engineering Research Lab
**  Written by GRASS 3.0 Summer of 88,  -mh
*/

/**************************
*
*  This file includes
*       set_keyboard()   -  set the keyboard up for key_hit()
*       unset_keyboard() -  set the keyboard back to original mode
*       key_hit()        -  will try to read a character from the keyboard.
*                       if a key has been hit and it is placed it in the passed
*                       in the buffer and a true value is returned.
*                       if no key has been hit return false 0.
*
**************************/

#define LINUX_POSIX


#ifdef LINUX_POSIX

#include <stdio.h>             <====== ANSI C/ POSIX headers
#include <unistd.h>
#include <termios.h>

#define   KEYBOARD   STDIN_FILENO       <=== define KEYBOARD more portably

int  set_keyboard( void );              <==== ANSI C protos
int  unset_keyboard( void );
int  key_hit( char * );

struct  termios  new_termio ;           <==== POSIX structs
struct  termios  old_termio ;

int  set_keyboard( void )
{

 /*
  * get the tty structure
  */

        if (tcgetattr( KEYBOARD, &old_termio) < 0)              <=== POSIX
                perror ("tcgetattr failed on old_termio");
        if (tcgetattr( KEYBOARD, &new_termio) < 0)              <=== POSIX
                perror ("tcgetattr failed on new_termio");

 /*
  *  change the settings
  */

        new_termio.c_lflag = 0 ;
        new_termio.c_cc›VEOF| = 0 ;
        new_termio.c_cc›VEOL| = 0 ;

 /*
  * now set the modes and flags
  */

        if (tcsetattr( KEYBOARD, TCSANOW, &new_termio) < 0)     <=== POSIX
                perror ("tcsetattr failed on new_termio");

        return (0);
}

int  unset_keyboard( void )
{

        if (tcsetattr( KEYBOARD, TCSANOW, &old_termio) < 0)     <=== POSIX
                perror ("tcsetattr failed on old_termio");

        return (0);
}

int  key_hit( char *buf )
{

        int     Keyhit ;

        if ( (Keyhit  =  read (0, buf, 1)) < 0 )
                perror (" read failed in key_hit\n") ;

        return (Keyhit) ;
}
#else

...
...

#endif
-------------------------------------------------------------------------


>If you dont want to go that way (or can't if they don't support Linux),
>getting a 16550 UART which has at least a small buffer, and setting your
>baud rate very slow, like 300 baud.  I don't know off hand how well the
>current digitizer interface works if it drops an occasional character.

More of my content free stuff follows (most everyone knows this stuff,
anyway).   One of the plusses for Linux is that it distributed w/ source.
Look in the /usr/src/linux/drivers/char/serial.c file to find out which
cards are supported in the kernel.  The Linux serial HOWTO has more info.

Best Regards,
Frank Davis
USDA-ARS, Tifton, GA
fmd at tifton.cpes.peachnet.edu



More information about the grass-user mailing list