chriswalsh has asked for the wisdom of the Perl Monks concerning the following question:

Hello folks,

Is it possible to use Perl's oictl() method in the same way as you could use the os's ioctl() system call from a c program?

It says in The Cookbook that the Perl method is a direct interface to the OS's method, but when the third argument is a struct, how does it work?

The Class::Struct structs are only struct-like, rather than in essence, right?

Help please, my brain hurts!

C

Replies are listed 'Best First'.
Re: Using ioctl()
by Joost (Canon) on Oct 08, 2004 at 18:17 UTC
    ikegami is right that you can use pack and unpack create / read from structs. however, using pack() to write structs does not work portably, especially when you've got a struct made up of different-sized elements - AFAIK C compilers are allowed to switch elements in struct around, and anyway insert unused bytes to align elements depending on their type. IOW:

    struct { byte a; long b; }

    may take up 6 bytes on a system with 4-byte integers and a 2-byte alignment requirement for integers. OTOH on a system with 4-byte aligned 4-byte integers, it might take up 8 bytes.

    Ofcourse, there are modules to deal with all of this, a CPAN search gave me this (probably incomplete) list:

    note - I've not tested any of these and if none of them work, I know Inline::C does, but it's probably overkill for this application. Also, if you only need it to work on a specific system, you can hardcode the pack() template anyway (you might have to experiment to get the right one).

      The C standard allows for arbitrary padding for alignment reasons but in practice how structs are padded is pretty consistent among most C compilers.

      Also, most good structs are laid out such that no padding is required.

      So you can use pack quite portably in most cases. But, yes, there are exceptions.

      - tye        

Re: Using ioctl()
by ikegami (Patriarch) on Oct 08, 2004 at 17:30 UTC
    You're right about Class::Struct. pack is the function designed to create C-style structs. If ioctl returns values using the struct, you can unpack it using unpack.
Re: Using ioctl()
by tachyon (Chancellor) on Oct 09, 2004 at 00:39 UTC

    Sometimes it is just easier to do it in C Inline C lets you get data back to perl easily. Re: MAC Address of An Interface in one of my ioctl inline C examples. There are a few others I posted here to change an interfaces IP....

    cheers

    tachyon

      Thanks tachyon,

      Maybe I should do it in c so...

      For the record, I'm trying to get NIC speed and Duplex mode. Machines can be one of (Linux|SunOS|AIX|HP-UX)...

      I need to go away now and beat my forehead off the keyboard for another while...

      C.

        Have a look at mii-tool Google for mii-tool to find the source code which is failrly short. Here is a good page on ioctl for reference.

        cheers

        tachyon