RE: perldebug.pod suggestion
[p5sagit/p5-mst-13.2.git] / pod / perlfaq8.pod
index 1df3b6a..164d235 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perlfaq8 - System Interaction ($Revision: 1.39 $, $Date: 1999/05/23 18:37:57 $)
+perlfaq8 - System Interaction ($Revision: 1.17 $, $Date: 2003/01/26 17:44:04 $)
 
 =head1 DESCRIPTION
 
@@ -77,7 +77,7 @@ Or like this:
 Controlling input buffering is a remarkably system-dependent matter.
 On many systems, you can just use the B<stty> command as shown in
 L<perlfunc/getc>, but as you see, that's already getting you into
-portability snags.  
+portability snags.
 
     open(TTY, "+</dev/tty") or die "no tty: $!";
     system "stty  cbreak </dev/tty >/dev/tty 2>&1";
@@ -188,14 +188,14 @@ positions, etc, you might wish to use Term::Cap module:
 
 =head2 How do I get the screen size?
 
-If you have Term::ReadKey module installed from CPAN, 
+If you have Term::ReadKey module installed from CPAN,
 you can use it to fetch the width and height in characters
 and in pixels:
 
     use Term::ReadKey;
     ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
 
-This is more portable than the raw C<ioctl>, but not as 
+This is more portable than the raw C<ioctl>, but not as
 illustrative:
 
     require 'sys/ioctl.ph';
@@ -275,7 +275,7 @@ next.
 
 If you expect characters to get to your device when you print() them,
 you'll want to autoflush that filehandle.  You can use select()
-and the C<$|> variable to control autoflushing (see L<perlvar/$|>
+and the C<$|> variable to control autoflushing (see L<perlvar/$E<verbar>>
 and L<perlfunc/select>, or L<perlfaq5>, ``How do I flush/unbuffer an
 output filehandle?  Why must I do this?''):
 
@@ -294,7 +294,7 @@ of code just because you're afraid of a little $| variable:
     DEV->autoflush(1);
 
 As mentioned in the previous item, this still doesn't work when using
-socket I/O between Unix and Macintosh.  You'll need to hardcode your
+socket I/O between Unix and Macintosh.  You'll need to hard code your
 line terminators, in that case.
 
 =item non-blocking input
@@ -346,7 +346,12 @@ passwd(1), for example).
 
 =head2 How do I start a process in the background?
 
-You could use
+Several modules can start other processes that do not block
+your Perl program.  You can use IPC::Open3, Parallel::Jobs,
+IPC::Run, and some of the POE modules.  See CPAN for more
+details.
+
+You could also use
 
     system("cmd &")
 
@@ -375,10 +380,26 @@ not an issue with C<system("cmd&")>.
 
 =item Zombies
 
-You have to be prepared to "reap" the child process when it finishes
+You have to be prepared to "reap" the child process when it finishes.
 
     $SIG{CHLD} = sub { wait };
 
+    $SIG{CHLD} = 'IGNORE';
+
+You can also use a double fork. You immediately wait() for your
+first child, and the init daemon will wait() for your grandchild once
+it exits.
+
+       unless ($pid = fork) {
+               unless (fork) {
+            exec "what you really wanna do";
+            die "exec failed!";
+               }
+        exit 0;
+       }
+    waitpid($pid,0);
+
+
 See L<perlipc/"Signals"> for other examples of code to do this.
 Zombies are not an issue with C<system("prog &")>.
 
@@ -424,8 +445,8 @@ If perl was installed correctly and your shadow library was written
 properly, the getpw*() functions described in L<perlfunc> should in
 theory provide (read-only) access to entries in the shadow password
 file.  To change the file, make a new shadow password file (the format
-varies from system to system--see L<passwd(5)> for specifics) and use
-pwd_mkdb(8) to install it (see L<pwd_mkdb(8)> for more details).
+varies from system to system--see L<passwd> for specifics) and use
+pwd_mkdb(8) to install it (see L<pwd_mkdb> for more details).
 
 =head2 How do I set the time and date?
 
@@ -435,7 +456,7 @@ program.  (There is no way to set the time and date on a per-process
 basis.)  This mechanism will work for Unix, MS-DOS, Windows, and NT;
 the VMS equivalent is C<set time>.
 
-However, if all you want to do is change your timezone, you can
+However, if all you want to do is change your time zone, you can
 probably get away with setting an environment variable:
 
     $ENV{TZ} = "MST7MDT";                 # unixish
@@ -447,12 +468,14 @@ probably get away with setting an environment variable:
 If you want finer granularity than the 1 second that the sleep()
 function provides, the easiest way is to use the select() function as
 documented in L<perlfunc/"select">.  Try the Time::HiRes and
-the BSD::Itimer modules (available from CPAN).
+the BSD::Itimer modules (available from CPAN, and starting from
+Perl 5.8 Time::HiRes is part of the standard distribution).
 
 =head2 How can I measure time under a second?
 
 In general, you may not be able to.  The Time::HiRes module (available
-from CPAN) provides this functionality for some systems.
+from CPAN, and starting from Perl 5.8 part of the standard distribution)
+provides this functionality for some systems.
 
 If your system supports both the syscall() function in Perl as well as
 a system call like gettimeofday(2), then you may be able to do
@@ -488,14 +511,14 @@ something like this:
 
 Release 5 of Perl added the END block, which can be used to simulate
 atexit().  Each package's END block is called when the program or
-thread ends (see L<perlmod> manpage for more details).  
+thread ends (see L<perlmod> manpage for more details).
 
 For example, you can use this to make sure your filter program
 managed to finish its output without filling up the disk:
 
     END {
        close(STDOUT) || die "stdout close failed: $!";
-    } 
+    }
 
 The END block isn't called when untrapped signals kill the program,
 though, so if you use END blocks you should also use
@@ -533,7 +556,10 @@ syscall(), you can use the syscall function (documented in
 L<perlfunc>).
 
 Remember to check the modules that came with your distribution, and
-CPAN as well--someone may already have written a module to do it.
+CPAN as well---someone may already have written a module to do it. On
+Windows, try Win32::API.  On Macs, try Mac::Carbon.  If no module
+has an interface to the C function, you can inline a bit of C in your
+Perl source with Inline::C.
 
 =head2 Where do I get the include files to do ioctl() or syscall()?
 
@@ -571,8 +597,8 @@ scripts inherently insecure.  Perl gives you a number of options
 The IPC::Open2 module (part of the standard perl distribution) is an
 easy-to-use approach that internally uses pipe(), fork(), and exec() to do
 the job.  Make sure you read the deadlock warnings in its documentation,
-though (see L<IPC::Open2>).  See 
-L<perlipc/"Bidirectional Communication with Another Process"> and 
+though (see L<IPC::Open2>).  See
+L<perlipc/"Bidirectional Communication with Another Process"> and
 L<perlipc/"Bidirectional Communication with Yourself">
 
 You may also use the IPC::Open3 module (part of the standard perl
@@ -602,6 +628,68 @@ With system(), both STDOUT and STDERR will go the same place as the
 script's STDOUT and STDERR, unless the system() command redirects them.
 Backticks and open() read B<only> the STDOUT of your command.
 
+You can also use the open3() function from IPC::Open3.  Benjamin
+Goldberg provides some sample code:
+
+To capture a program's STDOUT, but discard its STDERR:
+
+    use IPC::Open3;
+    use File::Spec;
+    use Symbol qw(gensym);
+    open(NULL, ">", File::Spec->devnull);
+    my $pid = open3(gensym, \*PH, ">&NULL", "cmd");
+    while( <PH> ) { }
+    waitpid($pid, 0);
+
+To capture a program's STDERR, but discard its STDOUT:
+
+    use IPC::Open3;
+    use File::Spec;
+    use Symbol qw(gensym);
+    open(NULL, ">", File::Spec->devnull);
+    my $pid = open3(gensym, ">&NULL", \*PH, "cmd");
+    while( <PH> ) { }
+    waitpid($pid, 0);
+
+To capture a program's STDERR, and let its STDOUT go to our own STDERR:
+
+    use IPC::Open3;
+    use Symbol qw(gensym);
+    my $pid = open3(gensym, ">&STDERR", \*PH, "cmd");
+    while( <PH> ) { }
+    waitpid($pid, 0);
+
+To read both a command's STDOUT and its STDERR separately, you can
+redirect them to temp files, let the command run, then read the temp
+files:
+
+    use IPC::Open3;
+    use Symbol qw(gensym);
+    use IO::File;
+    local *CATCHOUT = IO::File->new_tempfile;
+    local *CATCHERR = IO::File->new_tempfile;
+    my $pid = open3(gensym, ">&CATCHOUT", ">&CATCHERR", "cmd");
+    waitpid($pid, 0);
+    seek $_, 0, 0 for \*CATCHOUT, \*CATCHERR;
+    while( <CATCHOUT> ) {}
+    while( <CATCHERR> ) {}
+
+But there's no real need for *both* to be tempfiles... the following
+should work just as well, without deadlocking:
+
+    use IPC::Open3;
+    use Symbol qw(gensym);
+    use IO::File;
+    local *CATCHERR = IO::File->new_tempfile;
+    my $pid = open3(gensym, \*CATCHOUT, ">&CATCHERR", "cmd");
+    while( <CATCHOUT> ) {}
+    waitpid($pid, 0);
+    seek CATCHERR, 0, 0;
+    while( <CATCHERR> ) {}
+
+And it'll be faster, too, since we can begin processing the program's
+stdout immediately, rather than waiting for the program to finish.
+
 With any of these, you can change file descriptors before the call:
 
     open(STDOUT, ">logfile");
@@ -632,9 +720,10 @@ STDOUT).
 
 Note that you I<must> use Bourne shell (sh(1)) redirection syntax in
 backticks, not csh(1)!  Details on why Perl's system() and backtick
-and pipe opens all use the Bourne shell are in
-http://www.perl.com/CPAN/doc/FMTEYEWTK/versus/csh.whynot .
-To capture a command's STDERR and STDOUT together:
+and pipe opens all use the Bourne shell are in the
+F<versus/csh.whynot> article in the "Far More Than You Ever Wanted To
+Know" collection in http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz .  To
+capture a command's STDERR and STDOUT together:
 
     $output = `cmd 2>&1`;                       # either with backticks
     $pid = open(PH, "cmd 2>&1 |");              # or with an open pipe
@@ -677,50 +766,38 @@ there, and the old standard error shows up on the old standard out.
 
 =head2 Why doesn't open() return an error when a pipe open fails?
 
-Because the pipe open takes place in two steps: first Perl calls
-fork() to start a new process, then this new process calls exec() to
-run the program you really wanted to open.  The first step reports
-success or failure to your process, so open() can only tell you
-whether the fork() succeeded or not.
-
-To find out if the exec() step succeeded, you have to catch SIGCHLD
-and wait() to get the exit status.  You should also catch SIGPIPE if
-you're writing to the child--you may not have found out the exec()
-failed by the time you write.  This is documented in L<perlipc>.
-
-In some cases, even this won't work.  If the second argument to a
-piped open() contains shell metacharacters, perl fork()s, then exec()s
-a shell to decode the metacharacters and eventually run the desired
-program.  Now when you call wait(), you only learn whether or not the
-I<shell> could be successfully started...it's best to avoid shell
-metacharacters.
+If the second argument to a piped open() contains shell
+metacharacters, perl fork()s, then exec()s a shell to decode the
+metacharacters and eventually run the desired program.  If the program
+couldn't be run, it's the shell that gets the message, not Perl. All
+your Perl program can find out is whether the shell itself could be
+successfully started.  You can still capture the shell's STDERR and
+check it for error messages.  See L<"How can I capture STDERR from an
+external command?"> elsewhere in this document, or use the
+IPC::Open3 module.
 
-On systems that follow the spawn() paradigm, open() I<might> do what
-you expect--unless perl uses a shell to start your command. In this
-case the fork()/exec() description still applies.
+If there are no shell metacharacters in the argument of open(), Perl
+runs the command directly, without using the shell, and can correctly
+report whether the command started.
 
 =head2 What's wrong with using backticks in a void context?
 
 Strictly speaking, nothing.  Stylistically speaking, it's not a good
-way to write maintainable code because backticks have a (potentially
-humongous) return value, and you're ignoring it.  It's may also not be very
-efficient, because you have to read in all the lines of output, allocate
-memory for them, and then throw it away.  Too often people are lulled
-to writing:
+way to write maintainable code.  Perl has several operators for
+running external commands.  Backticks are one; they collect the output
+from the command for use in your program.  The C<system> function is
+another; it doesn't do this.
 
-    `cp file file.bak`;
-
-And now they think "Hey, I'll just always use backticks to run programs."
-Bad idea: backticks are for capturing a program's output; the system()
-function is for running programs.
+Writing backticks in your program sends a clear message to the readers
+of your code that you wanted to collect the output of the command.
+Why send a clear message that isn't true?
 
 Consider this line:
 
     `cat /etc/termcap`;
 
-You haven't assigned the output anywhere, so it just wastes memory
-(for a little while).  You forgot to check C<$?> to see whether
-the program even ran correctly, too.  Even if you wrote
+You forgot to check C<$?> to see whether the program even ran
+correctly.  Even if you wrote
 
     print `cat /etc/termcap`;
 
@@ -737,11 +814,20 @@ processing may take place, whereas backticks do not.
 
 =head2 How can I call backticks without shell processing?
 
-This is a bit tricky.  Instead of writing
+This is a bit tricky.  You can't simply write the command
+like this:
 
     @ok = `grep @opts '$search_string' @filenames`;
 
-You have to do this:
+As of Perl 5.8.0, you can use open() with multiple arguments.
+Just like the list forms of system() and exec(), no shell
+escapes happen.
+
+   open( GREP, "-|", 'grep', @opts, $search_string, @filenames );
+   chomp(@ok = <GREP>);
+   close GREP;
+
+You can also:
 
     my @ok = ();
     if (open(GREP, "-|")) {
@@ -757,12 +843,9 @@ You have to do this:
 Just as with system(), no shell escapes happen when you exec() a list.
 Further examples of this can be found in L<perlipc/"Safe Pipe Opens">.
 
-Note that if you're stuck on Microsoft, no solution to this vexing issue
+Note that if you're use Microsoft, no solution to this vexing issue
 is even possible.  Even if Perl were to emulate fork(), you'd still
-be hosed, because Microsoft gives no argc/argv-style API.  Their API
-always reparses from a single string, which is fundamentally wrong,
-but you're not likely to get the Gods of Redmond to acknowledge this
-and fix it for you.
+be stuck, because Microsoft does not have a argc/argv-style API.
 
 =head2 Why can't my script read from STDIN after I gave it EOF (^D on Unix, ^Z on MS-DOS)?
 
@@ -809,7 +892,7 @@ causes many inefficiencies.
 =head2 Can I use perl to run a telnet or ftp session?
 
 Try the Net::FTP, TCP::Client, and Net::Telnet modules (available from
-CPAN).  http://www.perl.com/CPAN/scripts/netstuff/telnet.emul.shar
+CPAN).  http://www.cpan.org/scripts/netstuff/telnet.emul.shar
 will also help for emulating the telnet protocol, but Net::Telnet is
 quite probably easier to use..
 
@@ -864,7 +947,7 @@ different process from the shell it was started from.  Changes to a
 process are not reflected in its parent--only in any children
 created after the change.  There is shell magic that may allow you to
 fake it by eval()ing the script's output in your shell; check out the
-comp.unix.questions FAQ for details.  
+comp.unix.questions FAQ for details.
 
 =back
 
@@ -885,7 +968,7 @@ module for other solutions.
 
 =item *
 
-Open /dev/tty and use the TIOCNOTTY ioctl on it.  See L<tty(4)>
+Open /dev/tty and use the TIOCNOTTY ioctl on it.  See L<tty>
 for details.  Or better yet, you can just use the POSIX::setsid()
 function, so you don't have to worry about process groups.
 
@@ -938,6 +1021,9 @@ handler, as documented in L<perlipc/"Signals"> and the section on
 ``Signals'' in the Camel.  You may instead use the more flexible
 Sys::AlarmCall module available from CPAN.
 
+The alarm() function is not implemented on all versions of Windows.
+Check the documentation for your specific version of Perl.
+
 =head2 How do I set CPU limits?
 
 Use the BSD::Resource module from CPAN.
@@ -946,14 +1032,19 @@ Use the BSD::Resource module from CPAN.
 
 Use the reaper code from L<perlipc/"Signals"> to call wait() when a
 SIGCHLD is received, or else use the double-fork technique described
-in L<perlfunc/fork>.
+in L<perlfaq8/"How do I start a process in the background?">.
 
 =head2 How do I use an SQL database?
 
-There are a number of excellent interfaces to SQL databases.  See the
-DBD::* modules available from http://www.perl.com/CPAN/modules/DBD .
-A lot of information on this can be found at 
-http://www.symbolstone.org/technology/perl/DBI/
+The DBI module provides an abstract interface to most database
+servers and types, including Oracle, DB2, Sybase, mysql, Postgresql,
+ODBC, and flat files.  The DBI module accesses each database type
+through a database driver, or DBD.  You can see a complete list of
+available drivers on CPAN: http://www.cpan.org/modules/by-module/DBD/ .
+You can read more about DBI on http://dbi.perl.org .
+
+Other modules provide more specific access: Win32::ODBC, Alzabo, iodbc,
+and others found on CPAN Search: http://search.cpan.org .
 
 =head2 How do I make a system() exit on control-C?
 
@@ -962,7 +1053,7 @@ sample code) and then have a signal handler for the INT signal that
 passes the signal on to the subprocess.  Or you can check for it:
 
     $rc = system($cmd);
-    if ($rc & 127) { die "signal death" } 
+    if ($rc & 127) { die "signal death" }
 
 =head2 How do I open a file without blocking?
 
@@ -978,9 +1069,17 @@ sysopen():
 =head2 How do I install a module from CPAN?
 
 The easiest way is to have a module also named CPAN do it for you.
-This module comes with perl version 5.004 and later.  To manually install
-the CPAN module, or any well-behaved CPAN module for that matter, follow
-these steps:
+This module comes with perl version 5.004 and later.
+
+    $ perl -MCPAN -e shell
+
+    cpan shell -- CPAN exploration and modules installation (v1.59_54)
+    ReadLine support enabled
+
+    cpan> install Some::Module
+
+To manually install the CPAN module, or any well-behaved CPAN module
+for that matter, follow these steps:
 
 =over 4
 
@@ -1086,15 +1185,11 @@ but other times it is not.  Modern programs C<use Socket;> instead.
 
 =head1 AUTHOR AND COPYRIGHT
 
-Copyright (c) 1997-1999 Tom Christiansen and Nathan Torkington.
+Copyright (c) 1997-2003 Tom Christiansen and Nathan Torkington.
 All rights reserved.
 
-When included as part of the Standard Version of Perl, or as part of
-its complete documentation whether printed or otherwise, this work
-may be distributed only under the terms of Perl's Artistic License.
-Any distribution of this file or derivatives thereof I<outside>
-of that package require that special arrangements be made with
-copyright holder.
+This documentation is free; you can redistribute it and/or modify it
+under the same terms as Perl itself.
 
 Irrespective of its distribution, all code examples in this file
 are hereby placed into the public domain.  You are permitted and