AFS-Monitor

 view release on metacpan or  search on metacpan

LICENSES/COPYING  view on Meta::CPAN

 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

			    Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

LICENSES/COPYING  view on Meta::CPAN

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.


LICENSES/COPYING  view on Meta::CPAN

apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding

LICENSES/COPYING  view on Meta::CPAN


Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

			    NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN

LICENSES/COPYING  view on Meta::CPAN

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) 19yy  <name of author>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

    Gnomovision version 69, Copyright (C) 19yy name of author
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your

examples/rxdebug  view on Meta::CPAN


use blib;
use strict;
use AFS::Monitor qw(rxdebug constant);
use Data::Dumper;

my $servers  = 'virtue.openafs.org'; # machine to run this on
my $port     = 7001;      # port to run this on
my $onlyhost = 'andrew.e.kth.se';  # some of the tests will show only connections from this host
my $onlyport = 7000;      # some of the tests will show only connections on this port
my $onlyauth = 'auth';    # some of the tests will show only connections with this auth level

my @tests;      # choose which tests to run
$tests[1] = 1;  # prints version
$tests[2] = 0;  # prints all peers and all non-dallying connections.
                # (can be long)
$tests[3] = 0;  # nonexistant host
$tests[4] = 0;  # nonexistant port
$tests[5] = 0;  # bad port; getstats fails. (can be slow)
$tests[6] = 0;  # prints long version of all peers. (can be long)
$tests[7] = 0;  # server $servers port $port. prints default info.
$tests[8] = 0;  # prints rxstats, no connections.
$tests[9] = 0;  # prints only auth $onlyauth
$tests[10] = 0; # shows all connections. (can be long)
$tests[11] = 0; # shows all server connections. (can be long)
$tests[12] = 0; # shows all client connections on port $port from host $onlyhost
$tests[13] = 0; # doesn't give port, tries default (7000).
$tests[14] = 0; # no arguments, runs on current machine with default port.
$tests[15] = 0; # port $port, runs on current machine.
$tests[16] = 0; # prints rxstats, all connections, long version of all peers.
                # (can be very long)

my $all = 1;    # show all tests

examples/rxdebug  view on Meta::CPAN

#         onlyserver     => 1,
#         onlyclient     => 1,
#         onlyport       => $onlyport,
#         version        => 1,
#         noconns        => 1,
#         peers          => 1,
#         long           => 1,
#         servers        => $servers, # required
#         port           => $port,
#         onlyhost       => $onlyhost,
#         onlyauth       => $onlyauth,
#        );

print "***** Starting now... *****\n";
my $rxdeb;

if ($all || $tests[1]) {
  print "\n******** TEST 1: ********\n";

  print "\nrxdebug -version -servers $servers -port $port\n\n";

examples/rxdebug  view on Meta::CPAN

                   servers => $servers,
                   port    => $port,
                   rxstats => 1
                  );
  parse_results($rxdeb);
}

if ($all || $tests[9]) {
  print "\n******** TEST 9 ********\n";

  print "\nrxdebug -servers $servers -port $port -onlyauth $onlyauth\n\n";

  $rxdeb = rxdebug(servers  => $servers,
                   port     => $port,
                   onlyauth => $onlyauth
                  );
  parse_results($rxdeb);
}

if ($all || $tests[10]) {
  print "\n******** TEST 10 ********\n";

  print "\nrxdebug -servers $servers -port $port -allconnections\n\n";

  $rxdeb = rxdebug(servers        => $servers,

examples/rxdebug  view on Meta::CPAN

          print ", flags=", $val->{connections}->[$i]->{secStats}->{flags},"\n";
        } elsif ($secStatsType == 2) {
          print "  rxvab level=", $val->{connections}->[$i]->{secStats}->{level};
          print ", flags=", $val->{connections}->[$i]->{secStats}->{flags},"\n";
        } elsif ($secStatsType == 3) {
          my $secStatsLevel;
          my $secStatsFlags = $val->{connections}->[$i]->{secStats}->{flags};
          if ($val->{connections}->[$i]->{secStats}->{level} == 0) {
            $secStatsLevel = "clear";
          } elsif ($val->{connections}->[$i]->{secStats}->{level} == 1) {
            $secStatsLevel = "auth";
          } elsif ($val->{connections}->[$i]->{secStats}->{level} == 2) {
            $secStatsLevel = "crypt";
          } else {
            $secStatsLevel = "unknown";
          }
          print "  rxkad: level ", $secStatsLevel;
          if ($secStatsFlags) {
            print ", flags";
          }
          if ($secStatsFlags & 1) {
            print " unalloc";
          }
          if ($secStatsFlags & 2) {
            print " authenticated";
          }
          if ($secStatsFlags & 4) {
            print " expired";
          }
          if ($secStatsFlags & 8) {
            print " pktCksum";
          }
          if ($val->{connections}->[$i]->{secStats}->{expires}) {
            my $secStatsExpires = $val->{connections}->[$i]->{secStats}->{expires} - time();
            $secStatsExpires = $secStatsExpires / 3600.0;

examples/xstat_cm_test  view on Meta::CPAN

          scalar localtime $host->{probeTime});

  print "Overall Performance Info:\n-------------------------\n";

  PrintOverallPerfInfo($host->{data}->{perf});

  print "\n";

  PrintRPCPerfInfo($host->{data}->{rpc});

  my $authentP = $host->{data}->{authent};
  print "\nAuthentication info:\n--------------------\n";

  printf("\t%d PAGS, %d records (%d auth, %d unauth), %d max in PAG, chain max: %d\n",
          $authentP->{curr_PAGs},
          $authentP->{curr_Records},
          $authentP->{curr_AuthRecords},
          $authentP->{curr_UnauthRecords},
          $authentP->{curr_MaxRecordsInPAG},
          $authentP->{curr_LongestChain});
  printf("\t%d PAG creations, %d tkt updates\n",
          $authentP->{PAGCreations},
          $authentP->{TicketUpdates});
  printf("\t[HWMs: %d PAGS, %d records, %d max in PAG, chain max: %d]\n",
          $authentP->{HWM_PAGs},
          $authentP->{HWM_Records},
          $authentP->{HWM_MaxRecordsInPAG},
          $authentP->{HWM_LongestChain});

  my $accessinfP = $host->{data}->{accessinf};
  print "\n[Un]replicated accesses:\n------------------------\n";
  printf("\t%d unrep, %d rep, %d reps accessed, %d max reps/ref, %d first OK\n\n",
          $accessinfP->{unreplicatedRefs},
          $accessinfP->{replicatedRefs},
          $accessinfP->{numReplicasAccessed},
          $accessinfP->{maxReplicasPerRef},
          $accessinfP->{refFirstReplicaOK});
}

pod/afsmon_stats.pod  view on Meta::CPAN

=item *

curr_PAGs: Current number of PAGs.

=item *

curr_Records: Current number of records in table.

=item *

curr_AuthRecords: Current number of of authenticated records (with valid ticket).

=item *

curr_UnauthRecords: Current number of of unauthenticated records (without any ticket at all).

=item *

curr_MaxRecordsInPAG: Maximum records for a single PAG.

=item *

curr_LongestChain: Length of longest current hash chain.

=item *

pod/rxdebug.pod  view on Meta::CPAN


  $rxd = rxdebug(nodally      => 1,
                 onlyserver   => 1,
                 onlyhost     => 'host2',
                 servers      => 'hostname',
                 port         => 7001,
                );

  $rxd = rxdebug(onlyclient   => 1,
                 onlyport     => 7002,
                 onlyauth     => 'crypt',
                 servers      => 'hostname',
                 port         => 7001,
                );

=head1 DESCRIPTION

The B<rxdebug> function provides a trace of Rx activity for the
server or client machine named by the B<servers> argument. Rx
is AFS's proprietary remote procedure call (RPC) protocol,
so this function enables the issuer to check the status of

pod/rxdebug.pod  view on Meta::CPAN

Produces output only for connections between the process designated by the
B<port> argument and the specified port on any another machine. Use the same
port identifiers as for the B<port> argument.

=item B<onlyhost>

Produces output only for connections between the process designated by the
B<port> argument and any process on the specified machine. To identify the
machine, use the same notation as for the B<servers> argument.

=item B<onlyauth>

Produces output only for connections that are using the specified
authentication level. Provide one of the following values:

=over

=item *

B<auth> for connections at authentication level B<rxkad_auth>

=item *

B<clear> for connections at authentication level B<rxkad_clear>

=item *

B<crypt> for connections at authentication level B<rxkad_crypt>

=item *

B<none> for unauthenticated connections (equivalents are B<null>, B<noauth>,
and B<unauth>)

=back

=item B<version>

Reports the AFS build level of the binary file for the process designated by
the B<port> argument (or of the kernel extensions file for port 7001, the Cache
Manager's callback interface). Any other options combined with this one are
ignored.

pod/xstat_cm_test.pod  view on Meta::CPAN


Reports various internal performance statistics related to the Cache Manager
(for example, statistics about how effectively the cache is being used and the
quantity of intracell and intercell data access).

=item B<2>

Reports all of the internal performance statistics provided by the B<1>
setting, plus some additional, detailed performance figures (for example,
statistics about the number of RPCs sent by the Cache Manager and how long
they take to complete, and statistics regarding authentication, access,
and PAG information associated with data access).

=back

=back

=head1 OUTPUT

The returned value is a reference to an array. There is an entry in the array
for each collection gathered for each cache manager. Each entry in the array is

src/Makefile.PL  view on Meta::CPAN

    'DEFINE'	   => "$d_flag $a_flag",
    'INC'          => "-I$AFSPath/include",
    'LIBS'         => [
                       "-L$AFSPath/lib -L$AFSPath/lib/afs "
                       . join (
                                   " ", qw(
                                           -lfsprobe
                                           -lvolser
                                           -lvldb

                                           -lkauth
                                           -lprot
                                           -lrx

                                           -lcmd
                                           -lubik
                                           -lauth

                                           -lrxkad
                                           -lrxstat
                                           -lxstat_fs
                                           -lxstat_cm
                                           -lafsint
                                           -lrx

                                           -lsys
                                           -ldes

src/Monitor.xs  view on Meta::CPAN

/*
 * from src/afsmonitor/afsmon-output.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

void
my_Print_cm_FullPerfInfo(xstat_cm_Results, cm_outFD)
   struct xstat_cm_ProbeResults xstat_cm_Results;
   FILE *cm_outFD;
{
   /* Ptr to authentication stats */
   struct afs_stats_AuthentInfo *authentP;
   /* Ptr to access stats */
   struct afs_stats_AccessInfo *accessinfP;
   /* Correct #longs */
   static afs_int32 fullPerfLongs = (sizeof(struct afs_stats_CMFullPerf) >> 2);
   /* # longs actually received */
   afs_int32 numLongs;
   /* Ptr to full perf info */
   struct afs_stats_CMFullPerf *fullP;
   /* Ptr to printable time string */
   char *printableTime;

src/Monitor.xs  view on Meta::CPAN

   /*
    * Print the overall numbers first, followed by all of the RPC numbers,
    * then each of the other groupings.
    */
   fprintf(cm_outFD,
           "Overall Performance Info:\n-------------------------\n");
   my_Print_cm_OverallPerfInfo(&(fullP->perf), cm_outFD);
   fprintf(cm_outFD, "\n");
   my_Print_cm_RPCPerfInfo(&(fullP->rpc), cm_outFD);

   authentP = &(fullP->authent);
   fprintf(cm_outFD, "\nAuthentication info:\n--------------------\n");
   fprintf(cm_outFD,
           "\t%d PAGS, %d records (%d auth, %d unauth), %d max in PAG, chain max: %d\n",
           authentP->curr_PAGs, authentP->curr_Records,
           authentP->curr_AuthRecords, authentP->curr_UnauthRecords,
           authentP->curr_MaxRecordsInPAG, authentP->curr_LongestChain);
   fprintf(cm_outFD, "\t%d PAG creations, %d tkt updates\n",
           authentP->PAGCreations, authentP->TicketUpdates);
   fprintf(cm_outFD,
           "\t[HWMs: %d PAGS, %d records, %d max in PAG, chain max: %d]\n",
           authentP->HWM_PAGs, authentP->HWM_Records,
           authentP->HWM_MaxRecordsInPAG, authentP->HWM_LongestChain);

   accessinfP = &(fullP->accessinf);
   fprintf(cm_outFD,
           "\n[Un]replicated accesses:\n------------------------\n");
   fprintf(cm_outFD,
           "\t%d unrep, %d rep, %d reps accessed, %d max reps/ref, %d first OK\n\n",
           accessinfP->unreplicatedRefs, accessinfP->replicatedRefs,
           accessinfP->numReplicasAccessed, accessinfP->maxReplicasPerRef,
           accessinfP->refFirstReplicaOK);

   /* There really isn't any authorship info
    * authorP = &(fullP->author); */
}   /* my_Print_cm_FullPerfInfo() */


/*
 * from src/afsmonitor/afsmon-output.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

void
my_afsmon_cmOutput(a_outfile, a_detOutput, xstat_cm_Results)

src/Monitor.xs  view on Meta::CPAN

      idx++;
      srcbuf++;
      tmpbuf = srcbuf++;    /* max time */
      sprintf(a_cmData->data[idx], "%d.%06d", *tmpbuf, *srcbuf);
      idx++;
      srcbuf++;
   }

   /*printf("Ending index value = %d\n",idx-1); */

   /* copy authentication info */

   srcbuf = (afs_int32 *) & (fullP->authent);
   numLongs = sizeof(struct afs_stats_AuthentInfo) / sizeof(afs_int32);
   for (i = 0; i < numLongs; i++) {
      sprintf(a_cmData->data[idx], "%d", *srcbuf);
      idx++;
      srcbuf++;
   }

   /*printf("Ending index value = %d\n",idx-1); */

   /* copy CM [un]replicated access info */

src/Monitor.xs  view on Meta::CPAN



/*
 * from src/xstat/xstat_cm_test.c
 *    ("$Header: /afs/slac/g/scs/slur/Repository/AFSDebug/Debug/src/Monitor.xs,v 1.2 2006/07/05 22:25:10 alfw Exp $");
 */

void
my_cm_PrintFullPerfInfo(struct xstat_cm_ProbeResults *xstat_cm_Results, HV *HOSTINFO)
{
   /*Ptr to authentication stats */
   struct afs_stats_AuthentInfo *authentP;
   /*Ptr to access stats */
   struct afs_stats_AccessInfo *accessinfP;
   /*Correct #int32s */
   static afs_int32 fullPerfInt32s = (sizeof(struct afs_stats_CMFullPerf) >> 2);
   /*# int32s actually received */
   afs_int32 numInt32s;
   struct afs_stats_CMFullPerf *fullP;
   HV *DATA      = newHV();
   HV *PERF      = newHV();
   HV *RPC       = newHV();

src/Monitor.xs  view on Meta::CPAN

      return;
   }
   fullP = (struct afs_stats_CMFullPerf *)
      (xstat_cm_Results->data.AFSCB_CollData_val);

   my_cm_PrintOverallPerfInfo(&(fullP->perf), PERF);
   hv_store(DATA, "perf", 4, newRV_inc((SV *) PERF), 0);
   my_PrintRPCPerfInfo(&(fullP->rpc), RPC);
   hv_store(DATA, "rpc", 3, newRV_inc((SV *) RPC), 0);

   authentP = &(fullP->authent);

   hv_store(AUTHENT, "curr_PAGs", 9, newSViv(authentP->curr_PAGs), 0);
   hv_store(AUTHENT, "curr_Records", 12, newSViv(authentP->curr_Records), 0);
   hv_store(AUTHENT, "curr_AuthRecords", 16,
            newSViv(authentP->curr_AuthRecords), 0);
   hv_store(AUTHENT, "curr_UnauthRecords", 18,
            newSViv(authentP->curr_UnauthRecords), 0);
   hv_store(AUTHENT, "curr_MaxRecordsInPAG", 20,
            newSViv(authentP->curr_MaxRecordsInPAG), 0);
   hv_store(AUTHENT, "curr_LongestChain", 17,
            newSViv(authentP->curr_LongestChain), 0);
   hv_store(AUTHENT, "PAGCreations", 12, newSViv(authentP->PAGCreations), 0);
   hv_store(AUTHENT, "TicketUpdates", 13, newSViv(authentP->TicketUpdates),
            0);
   hv_store(AUTHENT, "HWM_PAGs", 8, newSViv(authentP->HWM_PAGs), 0);
   hv_store(AUTHENT, "HWM_Records", 11, newSViv(authentP->HWM_Records), 0);
   hv_store(AUTHENT, "HWM_MaxRecordsInPAG", 19,
            newSViv(authentP->HWM_MaxRecordsInPAG), 0);
   hv_store(AUTHENT, "HWM_LongestChain", 16,
            newSViv(authentP->HWM_LongestChain), 0);
   hv_store(DATA, "authent", 7, newRV_inc((SV *) AUTHENT), 0);

   accessinfP = &(fullP->accessinf);

   hv_store(ACCESSINF, "unreplicatedRefs", 16,
            newSViv(accessinfP->unreplicatedRefs), 0);
   hv_store(ACCESSINF, "replicatedRefs", 14,
            newSViv(accessinfP->replicatedRefs), 0);
   hv_store(ACCESSINF, "numReplicasAccessed", 19,
            newSViv(accessinfP->numReplicasAccessed), 0);
   hv_store(ACCESSINF, "maxReplicasPerRef", 17,

src/Monitor.xs  view on Meta::CPAN

            char *name = (char *) SvPV(value, PL_na);
        struct hostent *th;
        th = hostutil_GetHostByName(name);
        if (!th) {
            sprintf(buffer, "rxdebug: host %s not found in host table", name);
            BSETCODE(-1, buffer);
            XSRETURN_UNDEF;
        }
        memcpy(&onlyHost, th->h_addr, sizeof(afs_int32));

        } else if (memcmp( flag, "onlyauth", 8) == 0 ) {
            char *name = (char *) SvPV(value, PL_na);
            if (strcmp (name, "clear") == 0) onlyAuth = 0;
            else if (strcmp (name, "auth") == 0) onlyAuth = 1;
            else if (strcmp (name, "crypt") == 0) onlyAuth = 2;
            else if ((strcmp (name, "null") == 0) ||
                     (strcmp (name, "none") == 0) ||
                     (strncmp (name, "noauth", 6) == 0) ||
                     (strncmp (name, "unauth", 6) == 0)) onlyAuth = -1;
            else {
              sprintf (buffer, "Unknown authentication level: %s", name);
              BSETCODE(-1, buffer);
              XSRETURN_UNDEF;
            }

        } else if (memcmp( flag, "onlyport", 8) == 0 ) {
            char *name = (char *) SvPV(value, PL_na);
            if ((onlyPort = rxdebug_PortNumber(name)) == -1)
              onlyPort = rxdebug_PortName(name);
            if (onlyPort == -1) {
              sprintf(buffer, "rxdebug: can't resolve port name %s", name);

src/afsmon-labels.h  view on Meta::CPAN

"XStatsVersion_CM_ops_max",
"GetXStats_CM_ops",
"GetXStats_CM_ops_ok",
"GetXStats_CM_ops_sum",
"GetXStats_CM_ops_sqr",
"GetXStats_CM_ops_min",
"GetXStats_CM_ops_max",
"curr_PAGs", 		/* Authentication information for CM */
"curr_Records",
"curr_AuthRecords",
"curr_UnauthRecords",
"curr_MaxRecordsInPAG",
"curr_LongestChain",
"PAGCreations",
"TicketUpdates",
"HWM_PAGS",
"HWM_Records",
"HWM_MaxRecordsInPAG",
"HWM_LongestChain",
"unreplicatedRefs", 	/* [Un]replicated file accesses: */
"replicatedRefs",

src/ppport.h  view on Meta::CPAN


#ifndef _P_P_PORTABILITY_H_
#define _P_P_PORTABILITY_H_

/* Perl/Pollution/Portability Version 1.0007 */

/* Copyright (C) 1999, Kenneth Albanowski. This code may be used and
   distributed under the same license as any version of Perl. */

/* For the latest version of this code, please retreive the Devel::PPPort
   module from CPAN, contact the author at <kjahds@kjahds.com>, or check
   with the Perl maintainers. */

/* If you needed to customize this file for your project, please mention
   your changes, and visible alter the version number. */


/*
   In order for a Perl extension module to be as portable as possible
   across differing versions of Perl itself, certain steps need to be taken.
   Including this header is the first major one, then using dTHR is all the



( run in 1.170 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )