Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
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 perusing the Monastery: (3)
As of 2014-09-21 15:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (172 votes), past polls