ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
#include <stdio.h>
main() /* program which introduces keyboard input */
{
int number;
printf("Type in a number \n");
scanf("%d", &number);
printf("The number you typed was %d\n", number);
}
Sample Program Output
Type in a number
23
The number you typed was 23
For raspberry, running headless, I need to code sthg in C
that will monitor my keyboard.
No xinit, x11,... is installed.
Needing a Minimalist - Detecting key events in C ?
On the headless:
This is installed, but headless it has no meaning
$ whereis getty
getty: /sbin/getty /usr/share/man/man8/getty.8.gz
NO Tkinter - since it is intended for minimalist.
in C language, and not c++
getch is fine, -yeah, sure once you see what you type and logged. screen as well.
/*
Copyleft (ɔ) 2009 Kernc
This program is free software. It comes with absolutely no warranty whatsoever.
See COPYING for further information.
Project homepage: http://code.google.com/p/logkeys/
*/
#include <cstdio>
#include <cerrno>
#include <cwchar>
#include <cstring>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <csignal>
#include <error.h>
#include <netdb.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <linux/input.h>
#ifdef HAVE_CONFIG_H
# include <config.h> // include config produced from ./configure
#endif
#ifndef PACKAGE_VERSION
# define PACKAGE_VERSION "0.1.0" // if PACKAGE_VERSION wasn't defined in <config.h>
#endif
keyboard at:
/dev/input/by-path/*-kbd
Could you give hints to look into right direction?
In sh from dtelnet, the printf all the time flows the screen is only for terminals (e.g. xterm)
So I brought a modded version herewith in attachemnt.
Two questions?
1) cannot it be more lightweight and remove more
stuffs in the include about??
2) Is it possible that the keyboard remain working?
(you take over the dev and keyboard is not working any longer) ??
i.e. to read on the keyboard, but not block all inputs?
3) is it possible to avoid using Termios and use an even more lightweight method as I indicated above by reading directly on the /dev/input... and still minimalist?
(not blocking the keyboard)
I'm not sure of the exact purpose of what you want, but I did write a keylogger some time ago using code from ventriloctrl.
Code:
#include <linux/input.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char **argv)
{
if (argc < 2)
{
printf("usage: %s <device>\n", argv[0]);
return 1;
}
// !init
struct input_event ev;
// init
int fd = open(argv[1], O_RDONLY);
FILE * infile = fopen ( "/var/log/keys" , "a" );
unsigned int i = 0;
while (read(fd, &ev, sizeof(struct input_event)))
{
if (ev.type == 1 && ev.value != 0)
{
fprintf(infile, "%i\n", ev.code);
i++;
if (i == 5)
{
i=0;
fflush(infile);
}
}
}
return 0;
}
I don't think it can be more minimal. You'll have to add key parsing yourself.
but in your code you would need logkeys dependency ?
so that one has to do before?
sudo logkeys -s -m /home/user/keyboard.map -o /var/log/keys
I would try to avoid installing logkeys, I tried to understand teh logkey opensource, but could not make a much minimalist one, or find sthg very very light.
It must be not very difficult since the input is just here readable:
/dev/input/by-path/*kbd
FILE *fp;
In C, a simple p/f...open could make it (<-- no kinding) and fclose/pclose(fp);
this for instance is minimal and reads some data, but to understand it is another story...
Code:
#include <stdio.h>
#include <string.h>
int main(int argc, char * argv[]){
FILE * fp_in;
char * data;
fp_in = fopen("/dev/input/by-path/pci-0000:00:1a.0-usb-0:1.5:1.0-event-kbd" ,"r");
if(fp_in == NULL){
fprintf(stderr,"Failed to open input by id\n");
}
fp_in = fopen("/dev/input/by-path/pci-0000:00:1a.0-usb-0:1.5:1.0-event-kbd","r");
if(fp_in == NULL){
fprintf(stderr,"Failed to open input by path\n");
return 1;
}
while(1){
fscanf(fp_in,data,"%s");
fprintf(stderr,"%s",data);
}
return 0;
}
In my opinion, one shall use: EVIOCGUNIQ ioctl.
So far with EVIOCGUNIQ, you can directly access the /dev/input and avoid terminals/...
This solution may work, but I need to adapt it a bit. Furthermore it is not much minimalist.
Code:
#include <stdio.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <linux/input.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
static int fd;
static int own_dev = 1;
int grab = 1;
void catch_signal(int signal)
{
switch ( signal ) {
case SIGINT:
/* release device if needed */
if ( own_dev ) {
ioctl(fd, EVIOCGRAB, NULL);
own_dev = 0;
} else {
ioctl(fd, EVIOCGRAB, &grab);
own_dev = 1;
}
break;
case SIGSTOP:
case SIGQUIT:
exit(0);
break;
}
}
int main(int argc, char *argv[])
{
fd_set rfds;
int res;
int version = -1, ioret = -1;
unsigned numevs, c;
unsigned char read_buffer[sizeof(struct input_event)*3]; /* max 3 events per read */
struct input_event *currev;
char device_name[1024];
struct sigaction sighandler;
memset(&sighandler, 0, sizeof(sighandler));
sighandler.sa_handler = catch_signal;
sigaction(SIGINT, &sighandler, NULL);
sigaction(SIGQUIT, &sighandler, NULL);
if ( argc < 2 ) {
fprintf(stderr, "Device needed\n");
return -1;
}
FD_ZERO(&rfds);
fd = open(argv[1], O_RDONLY);
if ( -1 == fd ) {
fprintf(stderr, "unable to read from mice\n");
return -1;
}
ioret = ioctl(fd, EVIOCGVERSION, &version);
ioret = ioctl(fd, EVIOCGNAME(sizeof(device_name)), device_name);
ioret = ioctl(fd, EVIOCGRAB, &grab);
if ( -1 == ioret ) {
perror("ioctl()");
}
fprintf(stdout, "ver: %d, ret = %d\n", version, ioret);
printf("device name is: %s\n", device_name);
FD_SET(fd, &rfds);
while ( 1 ) {
res = select(fd + 1, &rfds, NULL, NULL, NULL);
if ( -1 == res && EINTR == errno ) {
continue;
}
if ( -1 == res ) {
perror("select() failed");
fprintf(stderr, "failed to select, fd is %d\n", fd);
return -1;
}
if ( FD_ISSET(fd, &rfds) ) {
fprintf(stdout, "got some data\n");
res = read(fd, read_buffer, sizeof(read_buffer));
if ( -1 == res) {
fprintf(stderr, "error reading data\n");
return -1;
}
fprintf(stdout, "got %d bytes\n", res);
numevs = ( res / sizeof(struct input_event) ); /* get how many input events we got */
fprintf(stdout, "got %u events\n", numevs);
for ( c = 0; c < numevs; c++ ) {
currev = (struct input_event *)(read_buffer + (sizeof(struct input_event) * c));
fprintf(stdout, "event time %ld/%ld\n", currev->time.tv_sec, currev->time.tv_usec);
fprintf(stdout, "event type = %hd, code = %hd, value = %d\n", currev->type, currev->code, currev->value);
}
} else {
fprintf(stderr, "odd ... no data and we only listen in 1 fd\n");
}
}
return 0;
}
After few days of testing, I would like to recommend this last code I have posted. You may further update it. I added many lines, all keydings of all keys of my mini keyboard.
It is very lightweight and reliable. Better than Logkey deb since you can implement it into your own C code.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.