I'm trying to implement small shell program in C which will read commands from stdin, parse them and execute. I faced with problem of handling Ctrl+C as in original shell - when you type several letters, or doesn't type anything, and then press Cntrl+C, shell just returns new prompt back:
user@user-pc:/$ some letters^C
user@user-pc:/$
Here is a simplified code to show my approach of doing that:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
char interruption;
void read_line(char **str)
{
char c;
int size;
int i;
c = 0;
size = 30;
i = -1;
*str = (char*)malloc(sizeof(char) * size + 1);
while (c != '\n' && !interruption)
{
i++;
if (i == size)
*str = realloc((void*)*str, (size_t)((size *= 2) + 1));
read(0, &c, 1);
(*str)[i] = c;
}
if (interruption)
{
free(*str);
*str = NULL;
interruption = 0;
}
else
(*str)[i] = '\0';
}
void handler(int sig_num)
{
(void)sig_num;
signal(SIGINT, handler);
interruption = 1;
printf("\ninterruption happened\n");
}
int main()
{
char *str;
signal(SIGINT, handler);
interruption = 0;
while (1)
{
str = NULL;
write(1, "%> ", 3);
read_line(&str);
if (str)
printf("parsing %s\n", str);
else
printf("skipping...\n");
}
return (0);
}
The problem in my approach is that after pressing Ctrl+C prompt does not return, because read() starts actually reading from input only when I press Enter. It is my school assignment and I can't use any functions except read() to read characters from stdin.
What is the right way to reproduce the behavior of shell in this case?