views:

1750

answers:

5

I want to capture the Control+D signal in my program and write a signal handler for it. How can I do that? I am working on C and using a linux system.

+1  A: 

CTRL+D is not a signal, it's EOF (End-Of-File). It closes the stdin pipe. If read(STDIN) returns 0, it means stdin closed, which means CTRL+D was hit (assuming there is a keyboard at the other end of the pipe).

e-t172
+1  A: 

As far as I know Ctrl-D is translated by the system to end of standard input so your app won't get any signal.

I think that the only way to intercept Ctrl-D is to work directly with the system api (like accessing tty)

Piotr Czapla
+11  A: 

As others have already said, to handle Control-D, handle "end of file"s.

Control-D is a piece of communication between the user and the pseudo-file that you see as stdin. It does not mean specifically "end of file", but more generally "flush the input I typed so far". Flushing means that any read() call on stdin in your program returns with the length of the input typed since the last flush. If the line is nonempty, the input becomes available to your program although the user did not type "return" yet. If the line is empty, then read() returns with zero, and that is interpreted as "end of file".

So when using Control-D to end a program, it only works at the beginning of a line, or if you do it twice (first time to flush, second time for read() to return zero).

Try it:

$ cat
foo
   (type Control-D once)
foofoo (read has returned "foo")
   (type Control-D again)
$
Pascal Cuoq
+2  A: 
sambowry
A: 

You can use poll() and watch for POLLHUP on fd #1, because the TTY layer translates ^D to EOF.

VEOF (^D) does not transformed to be an EOF. If You press VEOF the program will receive a partial buffer as Pascal Cuoq wrote.
sambowry