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);
}