Rhandom has asked for the wisdom of the Perl Monks concerning the following question:
So, my question is, how do I read into a more complex structure. My C isn't as good as it could be but I have attempted to come up with a pack structure that mimics the struct but ioctl doesn't like it.
I have included the beginning of my script with some of the calling C code and the structs from linux/cdrom.h. Again, I know I could use Inline to do this and will do that if no answer works, but I would rather see if there is an answer for reading a complex structure via ioctl.
Note: it is the second ioctl call that fails.
#!/usr/bin/perl -w use strict; use vars qw(); use Fatal qw(open close ioctl); ### try to load some cdrom constants if( ! eval { require "linux/cdrom.ph" } ){ my $error; if( $@ =~ /^(Can\'t locate .+? in \@INC)/ ){ $error = $1 ."\n You may need to run h2ph.\n"; }else{ $error = $@; } print $error; print "Continuing with hard coded constants...\n"; ### copy from linux/cdrom.ph eval 'sub CDROMREADTOCHDR () {0x5305;}' unless defined(&CDROMREADTOC +HDR); eval 'sub CDROMREADTOCENTRY () {0x5306;}' unless defined(&CDROMREADT +OCENTRY); eval 'sub CDROM_MSF () {0x02;}' unless defined(&CDROM_MSF); } ### open the cdrom device print "Opening cd device...\n"; my $device = "/dev/hdc"; # not portable...yet open(_DEV,"<$device"); ### read the toc range print "Reading toc header...\n"; my $str = ''; ioctl(_DEV, CDROMREADTOCHDR(), $str); my $track0 = ord( substr($str,0,1) ); my $trackn = ord( substr($str,1,1) ); print "Track range: [$track0][$trackn]\n"; ### read the entries print "Reading toc entries...\n"; for(my $i = $track0; $i <= $trackn; $i ++){ my $track = $i; my $format = CDROM_MSF(); my $struct = "CC4C4CCCCiC"; my $str = pack($struct,$track,0,0,$format); ioctl(_DEV, CDROMREADTOCENTRY(), $str); my($_track,$adr,$ctrl,$_format, $min,$sec,$frame, $lba, $datamode) = unpack($struct,$str); print "$_track $adr $_format $min $sec $frame\n"; } print "Done\n"; __END__ # Sample calling code and structs # struct cdrom_tocentry tocentry; # tocentry.cdte_track = i; # tocentry.cdte_format = CDROM_MSF; # ioctl(drive, CDROMREADTOCENTRY, &tocentry); # # struct cdrom_msf0 # { # __u8 minute; # __u8 second; # __u8 frame; # }; # # /* Address in either MSF or logical format */ # union cdrom_addr # { # struct cdrom_msf0 msf; # int lba; # }; # # struct cdrom_tocentry # { # __u8 cdte_track; # __u8 cdte_adr :4; # __u8 cdte_ctrl :4; # __u8 cdte_format; # union cdrom_addr cdte_addr; # __u8 cdte_datamode; # };
my @a=qw(random brilliant braindead); print $a[rand(@a)];
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: ioctl into or from perl structs
by wog (Curate) on Jan 24, 2002 at 03:02 UTC | |
|
Re: ioctl into or from perl structs
by Zaxo (Archbishop) on Jan 24, 2002 at 02:58 UTC |