+Alternately, you can specify the exact directory to place the extension's
+files by placing a "PREFIX=/destination/directory" after the make install.
+(or in between the make and install if you have a brain-dead version of make).
+This can be very useful if you are building an extension that will eventually
+be distributed to multiple systems. You can then just archive the files in
+the destination directory and distribute them to your destination systems.
+
+=head2 EXAMPLE 5
+
+In this example, we'll do some more work with the argument stack. The
+previous examples have all returned only a single value. We'll now
+create an extension that returns an array.
+
+This extension is very Unix-oriented (struct statfs and the statfs system
+call). If you are not running on a Unix system, you can substitute for
+statfs any other function that returns multiple values, you can hard-code
+values to be returned to the caller (although this will be a bit harder
+to test the error case), or you can simply not do this example. If you
+change the XSUB, be sure to fix the test cases to match the changes.
+
+Return to the Mytest directory and add the following code to the end of
+Mytest.xs:
+
+ void
+ statfs(path)
+ char * path
+ INIT:
+ int i;
+ struct statfs buf;
+
+ PPCODE:
+ i = statfs(path, &buf);
+ if (i == 0) {
+ XPUSHs(sv_2mortal(newSVnv(buf.f_bavail)));
+ XPUSHs(sv_2mortal(newSVnv(buf.f_bfree)));
+ XPUSHs(sv_2mortal(newSVnv(buf.f_blocks)));
+ XPUSHs(sv_2mortal(newSVnv(buf.f_bsize)));
+ XPUSHs(sv_2mortal(newSVnv(buf.f_ffree)));
+ XPUSHs(sv_2mortal(newSVnv(buf.f_files)));
+ XPUSHs(sv_2mortal(newSVnv(buf.f_type)));
+ XPUSHs(sv_2mortal(newSVnv(buf.f_fsid[0])));
+ XPUSHs(sv_2mortal(newSVnv(buf.f_fsid[1])));
+ } else {
+ XPUSHs(sv_2mortal(newSVnv(errno)));
+ }
+
+You'll also need to add the following code to the top of the .xs file, just
+after the include of "XSUB.h":
+
+ #include <sys/vfs.h>
+
+Also add the following code segment to test.pl while incrementing the "1..9"
+string in the BEGIN block to "1..11":
+
+ @a = &Mytest::statfs("/blech");
+ print ((scalar(@a) == 1 && $a[0] == 2) ? "ok 10\n" : "not ok 10\n");
+ @a = &Mytest::statfs("/");
+ print scalar(@a) == 9 ? "ok 11\n" : "not ok 11\n";
+
+=head2 New Things in this Example
+
+This example added quite a few new concepts. We'll take them one at a time.
+
+=over 4
+
+=item *
+
+The INIT: directive contains code that will be placed immediately after
+the argument stack is decoded. C does not allow variable declarations at
+arbitrary locations inside a function,
+so this is usually the best way to declare local variables needed by the XSUB.
+(Alternatively, one could put the whole C<PPCODE:> section into braces, and
+put these declarations on top.)
+
+=item *
+
+This routine also returns a different number of arguments depending on the
+success or failure of the call to statfs. If there is an error, the error
+number is returned as a single-element array. If the call is successful,
+then a 9-element array is returned. Since only one argument is passed into
+this function, we need room on the stack to hold the 9 values which may be
+returned.
+
+We do this by using the PPCODE: directive, rather than the CODE: directive.
+This tells B<xsubpp> that we will be managing the return values that will be
+put on the argument stack by ourselves.
+
+=item *
+
+When we want to place values to be returned to the caller onto the stack,
+we use the series of macros that begin with "XPUSH". There are five
+different versions, for placing integers, unsigned integers, doubles,
+strings, and Perl scalars on the stack. In our example, we placed a
+Perl scalar onto the stack. (In fact this is the only macro which
+can be used to return multiple values.)
+
+The XPUSH* macros will automatically extend the return stack to prevent
+it from being overrun. You push values onto the stack in the order you
+want them seen by the calling program.
+
+=item *
+
+The values pushed onto the return stack of the XSUB are actually mortal SV's.
+They are made mortal so that once the values are copied by the calling
+program, the SV's that held the returned values can be deallocated.
+If they were not mortal, then they would continue to exist after the XSUB
+routine returned, but would not be accessible. This is a memory leak.
+
+=item *
+
+If we were interested in performance, not in code compactness, in the success
+branch we would not use C<XPUSHs> macros, but C<PUSHs> macros, and would
+pre-extend the stack before pushing the return values:
+
+ EXTEND(SP, 9);
+
+The tradeoff is that one needs to calculate the number of return values
+in advance (though overextending the stack will not typically hurt
+anything but memory consumption).
+
+Similarly, in the failure branch we could use C<PUSHs> I<without> extending
+the stack: the Perl function reference comes to an XSUB on the stack, thus
+the stack is I<always> large enough to take one return value.
+
+=back
+
+=head2 EXAMPLE 6
+
+In this example, we will accept a reference to an array as an input
+parameter, and return a reference to an array of hashes. This will
+demonstrate manipulation of complex Perl data types from an XSUB.
+
+This extension is somewhat contrived. It is based on the code in
+the previous example. It calls the statfs function multiple times,
+accepting a reference to an array of filenames as input, and returning
+a reference to an array of hashes containing the data for each of the
+filesystems.
+
+Return to the Mytest directory and add the following code to the end of
+Mytest.xs:
+
+ SV *
+ multi_statfs(paths)
+ SV * paths
+ INIT:
+ AV * results;
+ I32 numpaths = 0;
+ int i, n;
+ struct statfs buf;
+
+ if ((!SvROK(paths))
+ || (SvTYPE(SvRV(paths)) != SVt_PVAV)
+ || ((numpaths = av_len((AV *)SvRV(paths))) < 0))
+ {
+ XSRETURN_UNDEF;
+ }
+ results = (AV *)sv_2mortal((SV *)newAV());
+ CODE:
+ for (n = 0; n <= numpaths; n++) {
+ HV * rh;
+ STRLEN l;
+ char * fn = SvPV(*av_fetch((AV *)SvRV(paths), n, 0), l);
+
+ i = statfs(fn, &buf);
+ if (i != 0) {
+ av_push(results, newSVnv(errno));
+ continue;
+ }
+
+ rh = (HV *)sv_2mortal((SV *)newHV());
+
+ hv_store(rh, "f_bavail", 8, newSVnv(buf.f_bavail), 0);
+ hv_store(rh, "f_bfree", 7, newSVnv(buf.f_bfree), 0);
+ hv_store(rh, "f_blocks", 8, newSVnv(buf.f_blocks), 0);
+ hv_store(rh, "f_bsize", 7, newSVnv(buf.f_bsize), 0);
+ hv_store(rh, "f_ffree", 7, newSVnv(buf.f_ffree), 0);
+ hv_store(rh, "f_files", 7, newSVnv(buf.f_files), 0);
+ hv_store(rh, "f_type", 6, newSVnv(buf.f_type), 0);
+
+ av_push(results, newRV((SV *)rh));
+ }
+ RETVAL = newRV((SV *)results);
+ OUTPUT:
+ RETVAL
+
+And add the following code to test.pl, while incrementing the "1..11"
+string in the BEGIN block to "1..13":
+
+ $results = Mytest::multi_statfs([ '/', '/blech' ]);
+ print ((ref $results->[0]) ? "ok 12\n" : "not ok 12\n");
+ print ((! ref $results->[1]) ? "ok 13\n" : "not ok 13\n");
+
+=head2 New Things in this Example
+
+There are a number of new concepts introduced here, described below:
+
+=over 4
+
+=item *
+
+This function does not use a typemap. Instead, we declare it as accepting
+one SV* (scalar) parameter, and returning an SV* value, and we take care of
+populating these scalars within the code. Because we are only returning
+one value, we don't need a C<PPCODE:> directive - instead, we use C<CODE:>
+and C<OUTPUT:> directives.
+
+=item *
+
+When dealing with references, it is important to handle them with caution.
+The C<INIT:> block first checks that
+C<SvROK> returns true, which indicates that paths is a valid reference. It
+then verifies that the object referenced by paths is an array, using C<SvRV>
+to dereference paths, and C<SvTYPE> to discover its type. As an added test,
+it checks that the array referenced by paths is non-empty, using the C<av_len>
+function (which returns -1 if the array is empty). The XSRETURN_UNDEF macro
+is used to abort the XSUB and return the undefined value whenever all three of
+these conditions are not met.
+
+=item *
+
+We manipulate several arrays in this XSUB. Note that an array is represented
+internally by an AV* pointer. The functions and macros for manipulating
+arrays are similar to the functions in Perl: C<av_len> returns the highest
+index in an AV*, much like $#array; C<av_fetch> fetches a single scalar value
+from an array, given its index; C<av_push> pushes a scalar value onto the
+end of the array, automatically extending the array as necessary.
+
+Specifically, we read pathnames one at a time from the input array, and
+store the results in an output array (results) in the same order. If
+statfs fails, the element pushed onto the return array is the value of
+errno after the failure. If statfs succeeds, though, the value pushed
+onto the return array is a reference to a hash containing some of the
+information in the statfs structure.
+
+As with the return stack, it would be possible (and a small performance win)
+to pre-extend the return array before pushing data into it, since we know
+how many elements we will return:
+
+ av_extend(results, numpaths);
+
+=item *
+
+We are performing only one hash operation in this function, which is storing
+a new scalar under a key using C<hv_store>. A hash is represented by an HV*
+pointer. Like arrays, the functions for manipulating hashes from an XSUB
+mirror the functionality available from Perl. See L<perlguts> and L<perlapi>
+for details.
+
+=item *
+
+To create a reference, we use the C<newRV> function. Note that you can
+cast an AV* or an HV* to type SV* in this case (and many others). This
+allows you to take references to arrays, hashes and scalars with the same
+function. Conversely, the C<SvRV> function always returns an SV*, which may
+need to be be cast to the appropriate type if it is something other than a
+scalar (check with C<SvTYPE>).
+
+=item *
+
+At this point, xsubpp is doing very little work - the differences between
+Mytest.xs and Mytest.c are minimal.
+
+=back
+
+=head2 EXAMPLE 7 (Coming Soon)
+
+XPUSH args AND set RETVAL AND assign return value to array
+
+=head2 EXAMPLE 8 (Coming Soon)
+
+Setting $!
+
+=head2 EXAMPLE 9 (Coming Soon)
+
+Getting fd's from filehandles
+
+=head2 Troubleshooting these Examples
+
+As mentioned at the top of this document, if you are having problems with
+these example extensions, you might see if any of these help you.
+
+=over 4
+
+=item *
+
+In versions of 5.002 prior to the gamma version, the test script in Example
+1 will not function properly. You need to change the "use lib" line to
+read:
+
+ use lib './blib';
+
+=item *
+
+In versions of 5.002 prior to version 5.002b1h, the test.pl file was not
+automatically created by h2xs. This means that you cannot say "make test"
+to run the test script. You will need to add the following line before the
+"use extension" statement:
+
+ use lib './blib';
+
+=item *
+
+In versions 5.000 and 5.001, instead of using the above line, you will need
+to use the following line:
+
+ BEGIN { unshift(@INC, "./blib") }
+
+=item *
+
+This document assumes that the executable named "perl" is Perl version 5.
+Some systems may have installed Perl version 5 as "perl5".
+
+=back
+
+=head1 See also