This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Upgrade to Time-HiRes-1.76
[perl5.git] / pod / perlfaq8.pod
index e2ea3e7..f9f3584 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perlfaq8 - System Interaction ($Revision: 1.17 $, $Date: 2003/01/26 17:44:04 $)
+perlfaq8 - System Interaction ($Revision: 1.25 $, $Date: 2005/06/04 04:12:40 $)
 
 =head1 DESCRIPTION
 
@@ -276,8 +276,8 @@ 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/$E<verbar>>
-and L<perlfunc/select>, or L<perlfaq5>, ``How do I flush/unbuffer an
-output filehandle?  Why must I do this?''):
+and L<perlfunc/select>, or L<perlfaq5>, "How do I flush/unbuffer an
+output filehandle?  Why must I do this?"):
 
     $oldh = select(DEV);
     $| = 1;
@@ -411,33 +411,32 @@ You don't actually "trap" a control character.  Instead, that character
 generates a signal which is sent to your terminal's currently
 foregrounded process group, which you then trap in your process.
 Signals are documented in L<perlipc/"Signals"> and the
-section on ``Signals'' in the Camel.
+section on "Signals" in the Camel.
 
-Be warned that very few C libraries are re-entrant.  Therefore, if you
-attempt to print() in a handler that got invoked during another stdio
-operation your internal structures will likely be in an
-inconsistent state, and your program will dump core.  You can
-sometimes avoid this by using syswrite() instead of print().
+You can set the values of the %SIG hash to be the functions you want
+to handle the signal.  After perl catches the signal, it looks in %SIG
+for a key with the same name as the signal, then calls the subroutine
+value for that key.
 
-Unless you're exceedingly careful, the only safe things to do inside a
-signal handler are (1) set a variable and (2) exit.  In the first case,
-you should only set a variable in such a way that malloc() is not
-called (eg, by setting a variable that already has a value).
+       # as an anonymous subroutine
 
-For example:
+       $SIG{INT} = sub { syswrite(STDERR, "ouch\n", 5 ) };
 
-    $Interrupted = 0;  # to ensure it has a value
-    $SIG{INT} = sub {
-        $Interrupted++;
-       syswrite(STDERR, "ouch\n", 5);
-    }
+       # or a reference to a function
+
+       $SIG{INT} = \&ouch;
+
+       # or the name of the function as a string
+
+       $SIG{INT} = "ouch";
+
+Perl versions before 5.8 had in its C source code signal handlers which
+would catch the signal and possibly run a Perl function that you had set
+in %SIG.  This violated the rules of signal handling at that level
+causing perl to dump core. Since version 5.8.0, perl looks at %SIG
+*after* the signal has been caught, rather than while it is being caught.
+Previous versions of this answer were incorrect.
 
-However, because syscalls restart by default, you'll find that if
-you're in a "slow" call, such as <FH>, read(), connect(), or
-wait(), that the only way to terminate them is by "longjumping" out;
-that is, by raising an exception.  See the time-out handler for a
-blocking flock() in L<perlipc/"Signals"> or the section on ``Signals''
-in the Camel book.
 
 =head2 How do I modify the shadow password file on a Unix system?
 
@@ -528,7 +527,7 @@ though, so if you use END blocks you should also use
 Perl's exception-handling mechanism is its eval() operator.  You can
 use eval() as setjmp and die() as longjmp.  For details of this, see
 the section on signals, especially the time-out handler for a blocking
-flock() in L<perlipc/"Signals"> or the section on ``Signals'' in
+flock() in L<perlipc/"Signals"> or the section on "Signals" in
 the Camel Book.
 
 If exception handling is all you're interested in, try the
@@ -749,10 +748,10 @@ but leave its STDOUT to come out our old STDERR:
     while (<PH>) { }                            #    plus a read
 
 To read both a command's STDOUT and its STDERR separately, it's easiest
-and safest to redirect them separately to files, and then read from those
-files when the program is done:
+to redirect them separately to files, and then read from those files
+when the program is done:
 
-    system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr");
+    system("program args 1>program.stdout 2>program.stderr");
 
 Ordering is important in all these examples.  That's because the shell
 processes file descriptor redirections in strictly left to right order.
@@ -1018,7 +1017,7 @@ the current process group of your controlling terminal as follows:
 
 Use the alarm() function, probably in conjunction with a signal
 handler, as documented in L<perlipc/"Signals"> and the section on
-``Signals'' in the Camel.  You may instead use the more flexible
+"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.
@@ -1063,8 +1062,76 @@ O_NDELAY or O_NONBLOCK flag from the Fcntl module in conjunction with
 sysopen():
 
     use Fcntl;
-    sysopen(FH, "/tmp/somefile", O_WRONLY|O_NDELAY|O_CREAT, 0644)
-        or die "can't open /tmp/somefile: $!":
+    sysopen(FH, "/foo/somefile", O_WRONLY|O_NDELAY|O_CREAT, 0644)
+        or die "can't open /foo/somefile: $!":
+
+=head2 How do I tell the difference between errors from the shell and perl?
+
+(answer contributed by brian d foy, C<< <bdfoy@cpan.org> >>
+
+When you run a Perl script, something else is running the script for you,
+and that something else may output error messages.  The script might
+emit its own warnings and error messages.  Most of the time you cannot
+tell who said what.
+
+You probably cannot fix the thing that runs perl, but you can change how
+perl outputs its warnings by defining a custom warning and die functions.
+
+Consider this script, which has an error you may not notice immediately.
+
+       #!/usr/locl/bin/perl
+
+       print "Hello World\n";
+
+I get an error when I run this from my shell (which happens to be
+bash).  That may look like perl forgot it has a print() function,
+but my shebang line is not the path to perl, so the shell runs the
+script, and I get the error.
+
+       $ ./test
+       ./test: line 3: print: command not found
+
+A quick and dirty fix involves a little bit of code, but this may be all
+you need to figure out the problem.
+
+       #!/usr/bin/perl -w
+
+       BEGIN {
+       $SIG{__WARN__} = sub{ print STDERR "Perl: ", @_; };
+       $SIG{__DIE__}  = sub{ print STDERR "Perl: ", @_; exit 1};
+       }
+
+       $a = 1 + undef;
+       $x / 0;
+       __END__
+
+The perl message comes out with "Perl" in front.  The BEGIN block
+works at compile time so all of the compilation errors and warnings
+get the "Perl:" prefix too.
+
+       Perl: Useless use of division (/) in void context at ./test line 9.
+       Perl: Name "main::a" used only once: possible typo at ./test line 8.
+       Perl: Name "main::x" used only once: possible typo at ./test line 9.
+       Perl: Use of uninitialized value in addition (+) at ./test line 8.
+       Perl: Use of uninitialized value in division (/) at ./test line 9.
+       Perl: Illegal division by zero at ./test line 9.
+       Perl: Illegal division by zero at -e line 3.
+
+If I don't see that "Perl:", it's not from perl.
+
+You could also just know all the perl errors, and although there are
+some people who may know all of them, you probably don't.  However, they
+all should be in the perldiag manpage. If you don't find the error in
+there, it probably isn't a perl error.
+
+Looking up every message is not the easiest way, so let perl to do it
+for you.  Use the diagnostics pragma with turns perl's normal messages
+into longer discussions on the topic.
+
+       use diagnostics;
+
+If you don't get a paragraph or two of expanded discussion, it
+might not be perl's message.
 
 =head2 How do I install a module from CPAN?
 
@@ -1110,8 +1177,8 @@ just need to replace step 3 (B<make>) with B<make perl> and you will
 get a new F<perl> binary with your extension linked in.
 
 See L<ExtUtils::MakeMaker> for more details on building extensions.
-See also the next question, ``What's the difference between require
-and use?''.
+See also the next question, "What's the difference between require
+and use?".
 
 =head2 What's the difference between require and use?
 
@@ -1163,7 +1230,7 @@ See Perl's L<lib> for more information.
     use lib "$FindBin::Bin";
     use your_own_modules;
 
-=head2 How do I add a directory to my include path at runtime?
+=head2 How do I add a directory to my include path (@INC) at runtime?
 
 Here are the suggested ways of modifying your include path:
 
@@ -1185,8 +1252,8 @@ but other times it is not.  Modern programs C<use Socket;> instead.
 
 =head1 AUTHOR AND COPYRIGHT
 
-Copyright (c) 1997-2003 Tom Christiansen and Nathan Torkington.
-All rights reserved.
+Copyright (c) 1997-2005 Tom Christiansen, Nathan Torkington, and
+other authors as noted. All rights reserved.
 
 This documentation is free; you can redistribute it and/or modify it
 under the same terms as Perl itself.