> > Recipe 12.14. Using h2ph to Translate C #include Files (Perl Cookbook) NAME="DC.title" CONTENT="Perl Cookbook"> NAME="DC.creator" CONTENT="Tom Christiansen & Nathan Torkington"> NAME="DC.publisher" CONTENT="O'Reilly & Associates, Inc."> NAME="DC.date" CONTENT="1999-07-02T01:41:57Z"> NAME="DC.type" CONTENT="Text.Monograph"> NAME="DC.format" CONTENT="text/html" SCHEME="MIME"> NAME="DC.source" CONTENT="1-56592-243-3" SCHEME="ISBN"> NAME="DC.language" CONTENT="en-US"> NAME="generator" CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"> REV="made" HREF="mailto:online-books@oreilly.com" TITLE="Online Books Comments"> REL="up" HREF="ch12_01.htm" TITLE="12. Packages, Libraries, and Modules"> REL="prev" HREF="ch12_14.htm" TITLE="12.13. Referring to Packages Indirectly"> REL="next" HREF="ch12_16.htm" TITLE="12.15. Using h2xs to Make a Module with C Code"> > BGCOLOR="#FFFFFF"> WIDTH="684" BORDER="0" CELLSPACING="0" CELLPADDING="0" > > ALIGN="LEFT" VALIGN="TOP" WIDTH="228" > CLASS="sect1" HREF="ch12_14.htm" TITLE="12.13. Referring to Packages Indirectly" > SRC="../gifs/txtpreva.gif" ALT="Previous: 12.13. Referring to Packages Indirectly" BORDER="0"> > > ALIGN="CENTER" VALIGN="TOP" WIDTH="228" > > FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1" > CLASS="chapter" REL="up" HREF="ch12_01.htm" TITLE="12. Packages, Libraries, and Modules" > > > > > ALIGN="RIGHT" VALIGN="TOP" WIDTH="228" > CLASS="sect1" HREF="ch12_16.htm" TITLE="12.15. Using h2xs to Make a Module with C Code" > SRC="../gifs/txtnexta.gif" ALT="Next: 12.15. Using h2xs to Make a Module with C Code" BORDER="0"> > > > > > CLASS="sect1" > CLASS="sect1" > CLASS="title" NAME="ch12-25588" >12.14. Using h2ph to Translate C #include Files > > CLASS="sect2" > CLASS="sect2" > CLASS="title" NAME="ch12-pgfId-1344" >Problem CLASS="indexterm" NAME="ch12-idx-1000005277-0" > > CLASS="indexterm" NAME="ch12-idx-1000005277-1" > > CLASS="indexterm" NAME="ch12-idx-1000005277-2" > > > > CLASS="para" >Someone gave you code that generates the bizarre error message: > CLASS="programlisting" > CLASS="userinput" > > CLASS="replaceable" > >Can't locate sys/syscall.ph in @INC (did you run h2ph?) > > > > CLASS="userinput" > > CLASS="replaceable" > >(@INC contains: /usr/lib/perl5/i686-linux/5.00404 /usr/lib/perl5 > > > > CLASS="userinput" > > CLASS="replaceable" > >/usr/lib/perl5/site_perl/i686-linux /usr/lib/perl5/site_perl .) > > > > CLASS="userinput" > > CLASS="replaceable" > >at some_program line 7. > > > > > CLASS="para" >You want to know what it means and how to fix it. > > CLASS="sect2" > CLASS="sect2" > CLASS="title" NAME="ch12-pgfId-1360" >Solution > > CLASS="para" >Get your system administrator to do this, running as the superuser: > CLASS="programlisting" >% cd /usr/include; h2ph sys/syscall.h > CLASS="para" >However, most include files require other include files, which means you should probably just translate them all: > CLASS="programlisting" >% cd /usr/include; h2ph *.h */*.h > CLASS="para" >If that reports too many filenames or misses some that are more deeply nested, try this instead: > CLASS="programlisting" >% cd /usr/include; find . -name '*.h' -print | xargs h2ph > > CLASS="sect2" > CLASS="sect2" > CLASS="title" NAME="ch12-pgfId-1376" >Discussion > > CLASS="para" >A file whose name ends in CLASS="literal" >".ph" > has been created by the CLASS="emphasis" >h2ph > tool, which translates C preprocessor directives from C CLASS="literal" >#include > files into Perl. The goal is to allow Perl code to access the same constants as C code. The CLASS="emphasis" >h2xs > tool is a better approach in most cases because it provides compiled C code for your modules, not Perl code simulating C code. However, using CLASS="emphasis" >h2xs > requires a lot more programming savvy (at least, for accessing C code) than CLASS="emphasis" >h2ph > does. > CLASS="para" >When CLASS="emphasis" >h2ph >'s translation process works, it's wonderful. When it doesn't, you're probably out of luck. As system architectures and include files become more complex, CLASS="emphasis" >h2ph > fails more frequently. If you're lucky, the constants you need are already in the Fcntl, Socket, or POSIX modules. The POSIX module implements constants from CLASS="emphasis" >sys/file.h >, CLASS="emphasis" >sys/errno.h >, and CLASS="emphasis" >sys/wait.h >, among others. It also allows fancy tty handling, as described in CLASS="xref" HREF="ch15_09.htm" TITLE="Using POSIX termios" >Recipe 15.8 >. > CLASS="para" >So what can you do with these . CLASS="emphasis" >ph > files? Here are a few examples. The first uses the pessimally non-portable CLASS="literal" >syscall > function to access your operating system's CLASS="literal" >gettimeofday > system call. This implements the FineTime module described in CLASS="xref" HREF="ch12_12.htm" TITLE="Overriding Built-In Functions" >Recipe 12.11 >. > CLASS="programlisting" ># file FineTime.pm package main; require 'sys/syscall.ph'; die "No SYS_gettimeofday in sys/syscall.ph" unless defined &SYS_gettimeofday; package FineTime; use strict; require Exporter; use vars qw(@ISA @EXPORT_OK); @ISA = qw(Exporter); @EXPORT_OK = qw(time); sub time() { my $tv = pack("LL", ()); # presize buffer to two longs syscall(&main::SYS_gettimeofday, $tv, undef) >= 0 or die "gettimeofday: $!"; my($seconds, $microseconds) = unpack("LL", $tv); return $seconds + ($microseconds / 1_000_000); } 1; > CLASS="para" >If you are forced to CLASS="literal" >require > an old-style . CLASS="emphasis" >pl > or . CLASS="emphasis" >ph > file, do so from the main package ( CLASS="literal" >package > CLASS="literal" >main > in the preceding code). These old libraries always put their symbols in the current package, and main serves as a reasonable rendezvous point. To use a symbol, use its fully qualified name, as we did with CLASS="literal" >main::SYS_gettimeofday >. > CLASS="para" >The CLASS="emphasis" >sys/ioctl.ph > file, if you can get it to build on your system, is the gateway to your system's idiosyncratic I/O functions through the CLASS="indexterm" NAME="ch12-idx-1000006219-0" > > CLASS="literal" >ioctl > function. One such function is the TIOCSTI ioctl, shown in CLASS="xref" HREF="ch12_15.htm#ch12-25531" TITLE="jam" >Example 12.1 >. That abbreviation stands for "terminal I/O control, simulate terminal input." On systems that implement this function, it will push one character into your device stream so that the next time any process reads from that device, it gets the character you put there. > CLASS="example" > CLASS="example" > CLASS="title" NAME="ch12-25531" >Example 12.1: jam > > CLASS="programlisting" >#!/usr/bin/perl -w # CLASS="indexterm" NAME="ch12-idx-1000005347-0" > >jam - stuff characters down STDIN's throat require 'sys/ioctl.ph'; die "no TIOCSTI" unless defined &TIOCSTI; sub jam { local $SIG{TTOU} = "IGNORE"; # "Stopped for tty output" local *TTY; # make local filehandle open(TTY, "+</dev/tty") or die "no tty: $!"; for (split(//, $_[0])) { ioctl(TTY, &TIOCSTI, $_) or die "bad TIOCSTI: $!"; } close(TTY); } jam("@ARGV\n"); > > CLASS="para" >Since CLASS="emphasis" >sys/ioctl.h > translation is so dodgy, you'll probably have to run this C program to get your TIOCSTI value. > CLASS="programlisting" >% cat > tio.c <<EOF && cc tio.c && a.out #include <sys/ioctl.h> main() { printf("%#08x\n", TIOCSTI); } EOF CLASS="userinput" > > CLASS="replaceable" > >0x005412 > > > > > CLASS="para" >Another popular use for CLASS="literal" >ioctl > is for figuring out your current CLASS="indexterm" NAME="ch12-idx-1000006222-0" > >window size in rows and columns, and maybe even in pixels. This is shown in CLASS="xref" HREF="ch12_15.htm#ch12-29133" TITLE="winsz" >Example 12.2 >. > CLASS="example" > CLASS="example" > CLASS="title" NAME="ch12-29133" >Example 12.2: winsz > > CLASS="programlisting" >#!/usr/bin/perl # CLASS="indexterm" NAME="ch12-idx-1000005348-0" > >winsz - find x and y for chars and pixels require 'sys/ioctl.ph'; die "no TIOCGWINSZ " unless defined &TIOCGWINSZ; open(TTY, "+</dev/tty") or die "No tty: $!"; unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) { die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ; } ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize); print "(row,col) = ($row,$col)"; print " (xpixel,ypixel) = ($xpixel,$ypixel)" if $xpixel || $ypixel; print "\n"; > > CLASS="para" >As you see, as soon as you start playing with . CLASS="emphasis" >ph > files, CLASS="literal" >unpack >ing binary data, and calling CLASS="literal" >syscall > and CLASS="literal" >ioctl >, you need to know about the C APIs that Perl normally hides. The only other thing that requires this much C knowledge is using the XS interface. Some suggest you should resist the temptation to descend into such unportable convolutions. Others feel that the demands put upon the trenchworkers are such that they must be forgiven these desperate measures. > CLASS="para" >Fortunately, less fragile mechanisms are increasingly available. CPAN modules for most of these functions now exist, which should theoretically prove more robust than sourcing . CLASS="emphasis" >ph > files. CLASS="indexterm" NAME="ch12-idx-1000005279-0" > > CLASS="indexterm" NAME="ch12-idx-1000005279-1" > > CLASS="indexterm" NAME="ch12-idx-1000005279-2" > > > > CLASS="sect2" > CLASS="sect2" > CLASS="title" NAME="ch12-pgfId-1508" >See Also > > CLASS="para" > CLASS="filename" >h2ph > (1); the instructions on running CLASS="filename" >h2ph > in the CLASS="filename" >INSTALL > file from the CLASS="filename" >perl > source distribution; the CLASS="olink" HREF="../prog/ch03_164.htm" > CLASS="literal" >syscall > > and CLASS="olink" HREF="../prog/ch03_077.htm" > CLASS="literal" >ioctl > > functions in CLASS="olink" HREF="../prog/ch03_01.htm" >Chapter 3 > of CLASS="citetitle" HREF="../prog/index.htm" TITLE="Programming Perl" > CLASS="citetitle" >Programming Perl > > and in CLASS="filename" >perlmod >(1); CLASS="xref" HREF="ch12_16.htm" TITLE="Using h2xs to Make a Module with C Code" >Recipe 12.15 > > > > CLASS="htmlnav" > > > ALIGN="LEFT" WIDTH="684" TITLE="footer"> WIDTH="684" BORDER="0" CELLSPACING="0" CELLPADDING="0" > > ALIGN="LEFT" VALIGN="TOP" WIDTH="228" > CLASS="sect1" HREF="ch12_14.htm" TITLE="12.13. Referring to Packages Indirectly" > SRC="../gifs/txtpreva.gif" ALT="Previous: 12.13. Referring to Packages Indirectly" BORDER="0"> > > ALIGN="CENTER" VALIGN="TOP" WIDTH="228" > CLASS="book" HREF="index.htm" TITLE="Perl Cookbook" > SRC="../gifs/txthome.gif" ALT="Perl Cookbook" BORDER="0"> > > ALIGN="RIGHT" VALIGN="TOP" WIDTH="228" > CLASS="sect1" HREF="ch12_16.htm" TITLE="12.15. Using h2xs to Make a Module with C Code" > SRC="../gifs/txtnexta.gif" ALT="Next: 12.15. Using h2xs to Make a Module with C Code" BORDER="0"> > > > > ALIGN="LEFT" VALIGN="TOP" WIDTH="228" >12.13. Referring to Packages Indirectly > ALIGN="CENTER" VALIGN="TOP" WIDTH="228" > CLASS="index" HREF="index/index.htm" TITLE="Book Index" > SRC="../gifs/index.gif" ALT="Book Index" BORDER="0"> > > ALIGN="RIGHT" VALIGN="TOP" WIDTH="228" >12.15. Using h2xs to Make a Module with C Code > > > ALIGN="LEFT" WIDTH="684" TITLE="footer"> SIZE="-1" > > >