# 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__
|