1

I have encountered problems on signal handling when writing a shell-like program on C.
Here is the simplified version of my code:

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #define SIZE 255 void sig_handler(int sig){ if (sig == SIGINT) printf("\n[shell]$\n"); } int main() { char input[SIZE]; printf("[shell]$"); signal(SIGINT,sig_handler); while( gets(input) != NULL ){ // code of the shell including command interpreter and command execution printf("[shell]$"); } return 0; } 

When I run the program and try out SIGINT with command - "cat", the output shows as the following:

[shell]$ ^C (ctrl+C pressed for the first time) [shell]$ ^C (the input position go to the next line, which is unwanted) [shell]$ cat (I want it in the same line with [shell]$) ^C [shell]$ [shell]$ (duplicate printing occurs) 

I have tried to modify the function void sig_handler(int sig) by deleting the second \n. However, the situation becomes worse than before. The program doesn't automatically trigger the signal event on the first pressing of ctrl+C.

To clarify my problem, here are the two questions I ask:
1. How to make the input position on the same line with [shell]$ ?
2. How to solve the duplicate printing problem ?

2
  • 1
    Not sure about the duplicate thing, but you can make things print on the same line by removing the \n at the end of your printed string (although you might need to use fflush(stdout) to make it appear). Commented Oct 9, 2013 at 2:49
  • Thank you so much! For the dulicate problem, I have addressed it by creating another signal handling function without printf. Commented Oct 9, 2013 at 5:49

2 Answers 2

1

What @zneak said is true, you can use fflush and delete the second \n in sig_handler,

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #define SIZE 255 void sig_handler(int sig){ if (sig == SIGINT) printf("\n[shell]$"); fflush(stdout); } int main() { char input[SIZE]; printf("[shell]$"); fflush(stdout); signal(SIGINT,sig_handler); while( gets(input) != NULL ){ // code of the shell including command interpreter and command execution printf("[shell]$"); } return 0; } 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much! My program works as I want now.
1

First and foremost, printing from signal handler is a bad idea. Signal handler is like an interrupt handler - it happens asynchronously, it could be raised while being inside your standard library code and calling another stdlib routine might mess up with non-reentrant internals of it (imagine catching SIGINT while inside of printf() in your loop).

If you really want to output something from within, you better use raw write() call to stderr file descriptor.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.