tags:

views:

552

answers:

4

I have started to study C. I'm using Linux console and I would like to do a program which outputs random characters until ESC is pressed. How can I make such a keyboard handler?

+1  A: 

getch() from Curses library perhaps? Also, you will need to use notimeout() to tell getch() not to wait for next keypress.

Andrejs Cainikovs
You should explicitly mention you're talking about the (N)curses library.
James Morris
Yes, sure. Updated. Thanks.
Andrejs Cainikovs
note: getch() from ncurses needs proper ncurses "screen" to be initialized, or it won't work.
ShinTakezou
You also have to initialize the library - which is a variation on what @ShinTakezou said.
Jonathan Leffler
A: 
#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <signal.h>

char * me = "Parent";

void sigkill(int signum)
{
    //printf("=== %s EXIT SIGNAL %d ===\n", me, signum);
    exit(0);
}

main()
{
    int pid = fork();
    signal(SIGINT, sigkill);
    signal(SIGQUIT, sigkill);
    signal(SIGTERM, sigkill);
    if(pid == 0) //IF CHILD
    {  
        int ch;
        me = "Child";
        while(1)
        {  
            ch = (rand() % 26) + 'A';   // limit range to ascii A-Z
            printf("%c",ch);
            fflush(stdout); // flush output buffer
            sleep(2);   // don't overwhelm
            if (1 == getppid())
            {  
                printf("=== CHILD EXIT SINCE PARENT DIED ===\n");
                exit(0);
            }
        }
        printf("==CHILD EXIT NORMAL==\n");
    }
    else //PARENT PROCESS
    {  
        int ch;
        if((ch = getchar())==27)
            kill(pid, SIGINT);
        //printf("==PARENT EXIT NORMAL (ch=%d)==\n", ch);
    }
    return(0);
}

In this program u will only need to press enter after esc char,because getchar()is a blocking function. Also u may remove or decrease sleep time for child process as ur need.

neo730
Except `getchar` waits for input, so no random characters will be outputted while `getchar` waits for user to press [enter].
James Morris
+1  A: 

change the tty settings for one key press:

int getch(void) {
      int c=0;

      struct termios org_opts, new_opts;
      int res=0;
          //-----  store old settings -----------
      res=tcgetattr(STDIN_FILENO, &org_opts);
      assert(res==0);
          //---- set new terminal parms --------
      memcpy(&new_opts, &org_opts, sizeof(new_opts));
      new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL);
      tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);
      c=getchar();
          //------  restore old settings ---------
      res=tcsetattr(STDIN_FILENO, TCSANOW, &org_opts);
      assert(res==0);
      return(c);
}
jim mcnamara
A: 
jschmier