I wrote a small program to monitor keyboards found on /dev/input/event* It works great but I always get EAGAIN from my read() function. google says this is normal when open() is used and O_NONBLOCK mode. I know this is slightly offtopic but I was wondering if the centos gurus that also program know anything about this. My goal was to not be eating CPU cycles with a small program that just monitors key presses. With EAGAIN always coming in the process though small keeps waking up. Or perhaps there is another way to do this that I am not aware of. Thanks for any tips. Jerry #include <stdio.h> #include <errno.h> #include <fcntl.h> #include <signal.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <sys/stat.h> #include <linux/input.h> #include "smsignal.h" struct _msgnet_keycode { int keycode_value; char *keycode_str; int send_to_server; // .X will also send to server example: .4 says function 4 }; struct _msgnet_keycode msgnet_keycode[] = { {96, "KP_ENTER", 1}, // Keypad Enter Enter MUST be the first entry {28, "KP_ENTER", 1}, // Keypad Enter USB {14, "KP_BackSpace", 1}, // Keypad BS {55, "KP_Multiply", 1}, // Keypad * {98, "KP_Divide", 1}, // Keypad / {78, "KP_Plus", 1}, // Keypad + {74, "KP_Minus", 1}, // Keypad - {83, "KP_Period", 0}, // Keypad . {73, "KP_9", 0}, // Keypad 9 {72, "KP_8", 0}, // Keypad 8 {71, "KP_7", 0}, // Keypad 7 {77, "KP_6", 0}, // Keypad 6 {76, "KP_5", 0}, // Keypad 5 {75, "KP_4", 0}, // Keypad 4 {81, "KP_3", 0}, // Keypad 3 {80, "KP_2", 0}, // Keypad 2 {79, "KP_1", 0}, // Keypad 1 {82, "KP_0", 0}, // Keypad 0 {0, NULL} }; static int key_debug = 0; static int key_timeout = 0; /* incomplete command found so add KP_Enter and submit key presses */ static char keypad_buffer[200] = ""; #define FALSE (0) #define TRUE (1) /************************************************************ ** int main(int argc, char *argv[]) ** ************************************************************/ int main(int argc, char *argv[]) { int i; int fd; int bytes_read; int keycode; int done = FALSE; int any_keyboards; char *ptr; char *ptr_comma; #define MAX_KEY_WATCH (10) int fd[MAX_KEY_WATCH]; char input_name[200]; while(1) { done = FALSE; any_keyboards = FALSE; /* open all /dev/input/event devices */ for(i = 0; i < MAX_KEY_WATCH; i++) { sprintf(input_name, "/dev/input/event%d", i); fd[i] = open(input_name, O_RDONLY | O_NONBLOCK); if(fd[i] >= 0) { ioctl(fd[i], EVIOCGNAME (sizeof (input_name)), input_name); if(strstr(input_name, "Keyboard") || strstr(input_name, "1241:1203")) // Belkin keyboard { printf("Reading from (%d) %s\n", i, input_name); any_keyboards = TRUE; } else { close(fd[i]); fd[i] = -1; } } } if(any_keyboards == FALSE) { /* no keyboards found so sleep and try again */ sleep(10); } while(any_keyboards && done == FALSE) { int bytes_read; struct input_event event_keys[64]; for(i = 0; i < MAX_KEY_WATCH; i++) { if(fd[i] >= 0) { bytes_read = read(fd[i], event_keys, sizeof(event_keys)); if(bytes_read > 0) { /* there is a down event */ /* there is a UP event */ /* there is a UP event */ //printf("D %d %d %d\n", event_keys[0].type, event_keys[0].value, event_keys[0].code); //printf("U %d %d %d\n", event_keys[1].type, event_keys[1].value, event_keys[1].code); if(event_keys[0].type == 1 && event_keys[0].value == 1) { keycode = event_keys[0].code; for(find_key = 0; msgnet_keycode[find_key].keycode_str; find_key++) { if(msgnet_keycode[find_key].keycode_value == keycode) { KeyLog(find_key); break; } } } } else if(bytes_read < 0) { if(errno == EAGAIN) { /* EAGAIN is common on keyboard inputs */ /* but it HAPPENS ALOT */ } else { printf("Disconnect read=%d i=%d errno=%d\n", bytes_read, i, errno); sleep(2); done = TRUE; break; } } if(key_timeout) { KeyLog(0); /* KP_Enter */ } } } } for(i = 0; i < MAX_KEY_WATCH; i++) { if(fd[0] >= 0) { close(fd[i]); fd[0]= -1; } } } return(0); }