Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

How to do ioctl?

by morgon (Deacon)
on May 15, 2014 at 19:06 UTC ( #1086188=perlquestion: print w/ replies, xml ) Need Help??
morgon has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I would like to grab a Linux input-device via the EVIOCGRAB-ioctl call.

This is what's in my /usr/include/linux/input.h:

#define EVIOCGRAB _IOW('E', 0x90, int) + /* Grab/Release device */
So I tried the naive approach first:
open my $dev, "<", "/dev/input/event14" or die $!; my $r = ioctl $dev, 0x90, 1; print "$!\n" unless defined $r;
But that prints "Invalid argument".

So then I generated the ph-files (they were not generated when I installed perl via perlbrew) with h2ph and ran it like this:

require "linux/input.ph"; open my $dev, "<", "/dev/input/event14" or die $!; my $r = ioctl $dev, EVIOCGRAB(), 1; print "$!\n" unless defined $r;
But this again results in "Invalid argument".

So how do I do this?

I am running 5.18.1 on Debian testing.

Comment on How to do ioctl?
Select or Download Code
Re: How to do ioctl?
by zentara (Archbishop) on May 15, 2014 at 20:04 UTC
      I know that posting - how does it help me?

      All that "documents" is that you can (in C) use a 1 (rather than a pointer to 1) as argument.

      If I am missing what you try to say please post some working example in Perl.

Re: How to do ioctl?
by morgon (Deacon) on May 16, 2014 at 00:49 UTC
    I have now tried to following which does what I want:
    use Inline "C"; open my $dev, "<", "/dev/input/event14" or die $!; grab($dev->fileno, 1); __END__ __C__ #include <linux/input.h> void grab(int fd, int act) { int r = ioctl(fd, EVIOCGRAB, act); printf("grab: %d\n", r); }
    But it seems silly to me to resort to C just to issue an ioctl-call.

    Does anybody know how to do this in pure Perl?

      What number is EVIOCGRAB? What does Inline think it is, and what does input.ph think it is?
        Good point.

        I've tried the following:

        printf("ph: %u\n", EVIOCGRAB()); open my $dev, "<", "/dev/input/event7" or die $!; grab($dev->fileno, 1); __END__ __C__ #include <linux/input.h> void grab(int fd, int act) { printf("c: %u\n", EVIOCGRAB); int r = ioctl(fd, EVIOCGRAB, act); printf("grab: %d\n", r); }
        And sure enough it prints:

        ph: 1073759632
        c: 1074021776

        So for whatever reason there is a mismatch.

        If I don't use the .ph-files but simply do ioctl $dev, 1074021776, 1;it works.

        So it seems the problem lies with h2ph....

        The way I generated the phs was I went to /usr/include and from there I issued "h2ph -a -d <some output-dir> linux/input.h"

        Was that the wrong way to do it? And is it normal that I have to do that on my own (as I said I installed via perlbrew and there were no .phs generated then?

        But at least I know how to do it now...

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1086188]
Approved by igelkott
Front-paged by MidLifeXis
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (7)
As of 2014-12-25 20:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (163 votes), past polls