Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Linux ioctl command module

by Zaxo (Archbishop)
on Jan 24, 2002 at 03:56 UTC ( #141074=sourcecode: print w/ replies, xml ) Need Help??

Category: Miscellaneous
Author/Contact Info /msg Zaxo on CB.
Description:

This is a translation of the bit-twiddling functions used to produce an ioctl command in Linux. See your linux.pl file for another approach. Device numbers are not so static any more.

# Constants and functions transcribed from linux 2.4 asm-i386/ioctl.h 
+macros
use strict;

package Ioctl::Linux_2_4::I386;
BEGIN {
    use Exporter;
    use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
    @ISA = qw(Exporter);
    $VERSION = '0.04';

    @EXPORT = qw( _IO _IOR _IOW _IOWR );
    @EXPORT_OK = qw(
        _IOC_DIR _IOC_SIZE _IOC_NR _IOC_TYPE
        IOC_IN IOC_OUT IOC_INOUT
        IOCSIZE_MASK IOCSIZE_SHIFT
    );
    %EXPORT_TAGS = (
        decode  => [qw( _IOC_DIR _IOC_SIZE _IOC_NR _IOC_TYPE)],
        rawdir  => [qw(IOC_IN IOC_OUT IOC_INOUT)],
        rawsize => [qw(IOCSIZE_MASK IOCSIZE_SHIFT)]
        );
}

# Bitfield layout of ioctl command word
use constant     IOC_NRBITS   =>  8;
use constant     IOC_TYPEBITS =>  8;
use constant     IOC_SIZEBITS => 14;
use constant     IOC_DIRBITS  =>  2;

# Decoding masks
use constant     IOC_NRMASK   => ((1 << IOC_NRBITS) - 1 );
use constant     IOC_TYPEMASK => ((1 << IOC_TYPEBITS) - 1 );
use constant     IOC_SIZEMASK => ((1 << IOC_SIZEBITS) - 1 );
use constant     IOC_DIRMASK  => ((1 << IOC_DIRBITS) - 1 );

# Shift amounts derived from bitfield widths
use constant     IOC_NRSHIFT   => 0;
use constant     IOC_TYPESHIFT => (IOC_NRSHIFT + IOC_NRBITS);
use constant     IOC_SIZESHIFT => (IOC_TYPESHIFT + IOC_TYPEBITS);
use constant     IOC_DIRSHIFT  => (IOC_SIZESHIFT + IOC_SIZEBITS);

# Direction encoding
use constant     IOC_NONE  => 0;
use constant     IOC_WRITE => 1;
use constant     IOC_READ  => 2;

# Convenience constants
use constant IOC_IN        => (IOC_WRITE << IOC_DIRSHIFT);
use constant IOC_OUT       => (IOC_READ << IOC_DIRSHIFT);
use constant IOC_INOUT     => ((IOC_WRITE|IOC_READ) << IOC_DIRSHIFT);
use constant IOCSIZE_MASK  => (IOC_SIZEMASK << IOC_SIZESHIFT);
use constant IOCSIZE_SHIFT => (IOC_SIZESHIFT);

# Control word packing
# arguments: direction, type, nr, size
sub _IOC ($$$$) {
    ($_[0] & IOC_DIRMASK)  << IOC_DIRSHIFT  |
    ($_[1] & IOC_TYPEMASK) << IOC_TYPESHIFT |
    ($_[2] & IOC_NRMASK)   << IOC_NRSHIFT   |
    ($_[3] & IOC_SIZEMASK) << IOC_SIZESHIFT
}

# arguments: type, nr
sub _IO ($$) {
    _IOC( IOC_NONE, $_[0], $_[1], 0)
}

# arguments: type, nr, size
sub _IOR ($$$) {
    _IOC( IOC_READ, $_[0], $_[1], $_[2])
}

# arguments type, nr, size
sub _IOW ($$$) {
    _IOC( IOC_WRITE, $_[0], $_[1], $_[2])
}

# arguments type, nr, size
sub _IOWR ($$$) {
    _IOC( IOC_WRITE | IOC_READ, $_[0], $_[1], $_[2])
}

# Decode ioctl numbers
sub _IOC_DIR ($;@) {
    $_[0] >> IOC_DIRSHIFT & IOC_DIRMASK
}

sub _IOC_TYPE ($;@) {
    $_[0] >> IOC_TYPESHIFT & IOC_TYPEMASK
}

sub _IOC_NR ($;@) {
    $_[0] >> IOC_NRSHIFT & IOC_NRMASK
}

sub _IOC_SIZE ($;@) {
    $_[0] >> IOC_SIZESHIFT & IOC_SIZEMASK
}

1;
__END__

Comment on Linux ioctl command module
Download Code

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://141074]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (5)
As of 2014-12-29 02:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

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





    Results (184 votes), past polls