🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.amiga.tech
Article #2569

Re: Urgent Help Needed.

#2569
From: Andrew Thomas
Date: Thu, 07 Dec 1989 02:54
144 lines
4503 bytes
I don't know how to do it on the amiga, but here is a method which
works on BSD, SunOS, Ultrix.  I tried to reply by mail but it bounced.
This code is guaranteed not at all.  No claim is made to it either.
Do what you will.

------------------- cbreak.c -----------------------
/* cbreak.c  written by Andrew Thomas
   andrewt@watsnew.waterloo.edu

   If you have ideas on how to make this more portable, I am keen to
   hear them.  I make no guarantees, no claims, no copyrights.
*/

#include	<sgtty.h>
#include	<signal.h>
#include	<stdio.h>
#include	<sys/file.h>
#include	<sys/ioctl.h>

/*  WARNING:  If this file is compiled with gcc (or any ansi compiler)
    	      you must privide the -traditional option, or modify the
	      header files to adhere to ansi standard.
*/

/* The call you really want to use from here is the call to
   get_a_key(noecho,interrupt_status).  If noecho is non-zero, then
   the keys will not be echoed as they are typed.  Interrupt_status is
   explained in more detail later on.
*/

static	int		cbreak_on = 0;
static	int		tty = 0;
static	int		tty_set = 0;
static	int		cbreak_int_status = 0;
static	struct sgttyb	tty_desc;

void cbreak();
void nocbreak();

void cbreak_ignoresignal ()
{
}

void cbreak_killsignal ()
{
  nocbreak ();
  exit (1);
}

void cbreak_stopsignal ()
{
  nocbreak ();
  kill (getpid(), SIGSTOP);
  if (cbreak_on) cbreak(cbreak_on-1);
}

/* interrupt_status tells the system what to do with SIGTSTP, SIGTERM and
   SIGINT
   interrupt status is one of 0, 1, or 2:
   0: do nothing to alter the interrupts, or if interrupt status was
      changed before, make interrupts perform the default action.
   1: make interrupts cause a clean exit, resetting the interrupt status
      on exit and reentry
   2: ignore interrupts.
*/

void cbreak_open_tty (interrupt_status)
int	interrupt_status;
{
  tty_set = 1;
  tty = fileno (stdin);
  if (ioctl (tty, TIOCGETP, &tty_desc) == -1)
    perror ("ioctl: TIOCGETP");

  if (interrupt_status == 0 && cbreak_int_status != 0)
    {
      signal (SIGTSTP, SIG_DFL);
      signal (SIGTERM, SIG_DFL);
      signal (SIGINT, SIG_DFL);
    }
  else if (interrupt_status == 1)
    {
      signal (SIGTSTP, cbreak_stopsignal);
      signal (SIGTERM, cbreak_killsignal);
      signal (SIGINT, cbreak_killsignal);
    }      
  else if (interrupt_status == 2)
    {
      signal (SIGTSTP, cbreak_ignoresignal);
      signal (SIGTERM, cbreak_ignoresignal);
      signal (SIGINT, cbreak_ignoresignal);
    }      
  cbreak_int_status = interrupt_status;
}

/* noecho, if non-zero, causes the key stroke not to be echoed */

void cbreak (noecho, interrupt_status)
int	noecho, interrupt_status;
{
  if (!tty_set || interrupt_status != cbreak_int_status)
    cbreak_open_tty (interrupt_status);
  tty_desc.sg_flags |= CBREAK;
  if (noecho) tty_desc.sg_flags &= ~ECHO;
  if (ioctl (tty, TIOCSETN, &tty_desc) == -1)
    perror ("cbreak: ioctl: TIOCSETN");
}

void nocbreak ()
{
  if (!tty_set) cbreak_open_tty (cbreak_int_status);
  tty_desc.sg_flags &= ~CBREAK;
  tty_desc.sg_flags |= ECHO;
  if (ioctl (tty, TIOCSETN, &tty_desc) == -1)
    perror ("nocbreak: ioctl: TIOCSETN");
}

/* get a keystroke in cbreak mode, echoed or not echoed, with actions on
   interrupts specified.   Clear the stdin buffer first.  This is a
   bit of a kluge.  Suggestions welcome.
*/

char get_a_key (noecho, interrupt_status)
int	noecho, interrupt_status;
{
  char	x;

  while (stdin->_cnt > 0) if ((x=getchar()) != '\n') return (x);

  cbreak (noecho, interrupt_status);
  cbreak_on = 1+(noecho?1:0);
  x = getchar();
  nocbreak ();
  cbreak_on = 0;
  return (x);
}
--------------------------------------------------

Hope this helps.
--

Andrew Thomas
andrewt@watsnew.waterloo.edu	Systems Design Eng.	University of Waterloo
"If a million people do a stupid thing, it's still a stupid thing." - Opus
Technical Details
Message-ID: <ANDREWT.89Dec6215431@watsnew.waterloo.edu>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!watserv1!watcgl!andrewt
References: <1083@unsvax.NEVADA.EDU> <81705@linus.UUCP>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!watserv1!watcgl!andrewt
From: andrewt@watsnew.waterloo.edu (Andrew Thomas)
Newsgroups: comp.sys.amiga.tech
Subject: Re: Urgent Help Needed.
Message-ID: <ANDREWT.89Dec6215431@watsnew.waterloo.edu>
Date: 7 Dec 89 02:54:31 GMT
References: <1083@unsvax.NEVADA.EDU> <81705@linus.UUCP>
Sender: daemon@watcgl.waterloo.edu
Organization: University of Waterloo, Waterloo, Ontario, Canada
Lines: 144
In-reply-to: duncant@mbunix.mitre.org's message of 4 Dec 89 02:12:18 GMT