[comp.unix.programmer] Ignore <Ctrl-D>

cui@maccs.dcss.mcmaster.ca (Jun Cui) (03/12/91)

I'm doing a menu in C, and trying to ignore <Ctrl-d> <Ctrl-c> <Ctrl-z> etc. 
In other words, I would like the program not to be interrupted until user
select 'Quit' from the menu. (If I press <Ctrl-d> when the program is waiting
for user to select the menu, the program will go to infinite loop)

Any hints  would be appreciated.

jun
---
P.S. I'm not a supper user

jik@athena.mit.edu (Jonathan I. Kamens) (03/15/91)

In article <27DC2ABC.26018@maccs.dcss.mcmaster.ca>, cui@maccs.dcss.mcmaster.ca (Jun Cui) writes:
|> I'm doing a menu in C, and trying to ignore <Ctrl-d> <Ctrl-c> <Ctrl-z> etc. 
|> In other words, I would like the program not to be interrupted until user
|> select 'Quit' from the menu. (If I press <Ctrl-d> when the program is waiting
|> for user to select the menu, the program will go to infinite loop)

  First of all, the reason the program you're writing goes into an infinite
loop is that you're getting EOF from stdin and your program isn't dealing with
it properly.

  Most likely this is because you're assigning the return value of getchar to
a char (instead of to an int), so you don't notice when it returns EOF, since
EOF is a signed value and chars are often unsigned.  Either that, or it's
because you're not checking for EOF at all.  You should be.

  Second, there are a few ways to disable ^D ^C ^Z etc.  The first is to
change the special characters for the terminal (in order to disable those
characters).  The second is to put the terminal into a mode that ignores those
characters.  Check out the tty man page in section 4 of the manual (that's on
a BSD-like system; I don't know if it exists on SysV-like systems), or the
ioctl man page in section 2.  The third is to install signal handlers for
SIGINT and SIGTSTP so that you can just ignore those signals -- when the user
types ^C or ^Z, your program doesn't actually get a ^C or ^Z character, it
gets a SIGINT or SIGTSTP signal.

  Even if you change the special characters, or go into a different mode, or
install signal handlers for SIGINT and/or SIGTSTP, you still have to check for
EOF when reading from stdin.

  By the way, it is generally considered anti-social to ignore ^Z, unless
you're doing something like writing a "secure program" that people aren't
supposed to be able to escape from.  Your program should be smart enough to
suspend itself and start up again properly when the user continues it.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

dvldbg@cs.umu.se (Daniel Brahneborg) (03/25/91)

>I'm doing a menu in C, and trying to ignore <Ctrl-d> <Ctrl-c> <Ctrl-z> etc. 
>In other words, I would like the program not to be interrupted until user
>select 'Quit' from the menu. (If I press <Ctrl-d> when the program is waiting
>for user to select the menu, the program will go to infinite loop)

There are as far as I know two ways of doing this. The easiest way
is to use the signal(3) call, or maybe the underlying system
call, and tell it to ignore SIGSUSP, SIGINTR, SIGTERM, and a few others.
Or if you prefer, call one of your own routines.

The other way is to manupulate the terminal handler, which sends the
above mentioned signals. By calling ioctl(), you can set a lot of things,
which I leave you to discover for yourself.

Send a mail if it doesn't work, and I'll see what I can do to help you.

/Basic

goehring@gnu.ai.mit.edu (Not Marc Spencer) (03/26/91)

In article <1991Mar25.011538.11226@cs.umu.se> dvldbg@cs.umu.se (Daniel Brahneborg) writes:

   >I'm doing a menu in C, and trying to ignore <Ctrl-d> <Ctrl-c>
   ><Ctrl-z> etc.  In other words, I would like the program not to be
   >interrupted until user select 'Quit' from the menu. (If I press
   ><Ctrl-d> when the program is waiting for user to select the menu,
   >the program will go to infinite loop)

   There are as far as I know two ways of doing this. The easiest way
   is to use the signal(3) call, or maybe the underlying system call,
   and tell it to ignore SIGSUSP, SIGINTR, SIGTERM, and a few others.
   Or if you prefer, call one of your own routines.

this won't help, much.  at the very least even if you do catch sigint
it will still abort any i/o in progress.

   The other way is to manupulate the terminal handler, which sends
   the above mentioned signals. By calling ioctl(), you can set a lot
   of things, which I leave you to discover for yourself.

this will.  he needs to put the terminal into raw mode if he wants the
terminal handler not to produce signals, which is imho infinitely
better than trying to catch all those signals.
--
		  Help stamp out vi in our lifetime!
	Scott Goehring			goehring@gnu.ai.mit.edu
	On exile in Indianapolis, IN