6

I was using the bc utility recently and Ctrl+C cannot be used to exit the program. Ctrl+C's interrupt signal is returned with the message use quit to exit. I can use EOF (Ctrl+D) or quit to exit.

I read thru the difference between ^Z and ^C. Technically, ^C should end the program (and most programs do abort on receiving the interrupt signal). But bc returns a message asking us to use quit instead.

I was wondering is there a specific advantage in this ?

A.B.
  • 92,275

3 Answers3

6

I was wondering is there a specific advantage in this?

Yes. If you call a long running function in bc, you can interrupt it using control+c and it will not exit bc itself but the function running inside of bc.

Here is an example of me doing that:

$ bc twins.b 
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 

typing 'twins (10)' will print all twin primes less than 10.
twins(10000000)
^C
Runtime error (func=primes, adr=113): interrupted execution
Interruption completed.
print "As you can see, bc is still running\n"
As you can see, bc is still running
5+7
12

If you want to see the twins function, download the bc source code, and look in Examples directory.

5

Ctrl+ C sends SIGINT (signal interupt), which makes a process to get interrupted (in other words it kills the process). Some programs can catch this signal and ignore it, which is the case with bc.

The Ctrl+ D character sends EOT (end of transmission) character. Receiving this signal has similar effect as if when a program was reading from file, and reached the end of that file. Effectively, bc is waiting for you to tell it that you have no more input to give.

As for why . . . it's up to the developers to specify how the program exits as well as how it interacts with users

  • 1
    Thank you for the answer. I was just curious if there was any specific advantage to going against the norm in terms of not terminating with ^C. Or, they just happened to code bc up this way without any specific reason. – Darshan Chaudhary Sep 26 '15 at 17:04
  • @DarshanChaudhary Technically ^C isn't a "norm", it kills a process, in a sort of rude manner. The advantage, at least in my understanding, of using ^D is that the program won't loose any data if killed abruptly. – Sergiy Kolodyazhnyy Sep 26 '15 at 18:52
  • The effect of control-D is to cause any data-input request that's expecting data from the console to receive whatever characters have been typed up to that point, even if that means they receive zero characters. Many programs assume that a request to read some number of bytes from a file will only yield zero bytes if there is an end-of-file condition, but control-D doesn't indicate "end-of-file" from the OS point of view--it merely forces all input received to date to be made available to the application. – supercat Sep 26 '15 at 20:41
  • @supercat that kind of doesn't make sense, because bc and cat seem to process the input immediately , they don't wait for ^D to make the input available to the applications, as you said. Perhaps i am missing something – Sergiy Kolodyazhnyy Sep 26 '15 at 20:48
  • @Serg: When a terminal is in "cooked" mode, either newline or control-D will force blocked I/O to proceed with the data that is available up to that point. A newline will be considered part of the data, while control-D will not. Write an application which calls fread from the console and outputs to stdout the number of bytes read along with the bytes themselves in hex then calls flush(stdout) and you should be able to see what's going on. Typing "HELLO" and a newline will make six bytes available to the program; typing "HELLO" and control-D will make five bytes available. – supercat Sep 27 '15 at 18:46
1

A script or an application can catch and prevent events and so intrinsically offer termination methods. Why the developers have done so, you need to ask yourself.


You can see a simple example in the following shell script:

# Call trapint function when recive SIGINT
trap trapint SIGINT

# trapint function:
function trapint {
 echo "*** SIGINT received ***"  # Print a message
 exit 0                          # Exit gracefully
}

Fabby
  • 35,075
A.B.
  • 92,275