add ck_sysread() for better sysread/read/recv sanity
[p5sagit/p5-mst-13.2.git] / pod / perlfaq8.pod
index 6ad5c15..f4addd8 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perlfaq8 - System Interaction ($Revision: 1.15 $)
+perlfaq8 - System Interaction ($Revision: 1.21 $, $Date: 1997/04/24 22:44:19 $)
 
 =head1 DESCRIPTION
 
@@ -267,9 +267,9 @@ http://www.perl.com/CPAN/doc/misc/ancient/tutorial/eg/itimers.pl .
 =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) provides this functionality for some systems.
 
-In general, you may not be able to.  But if you system supports both the
+In general, you may not be able to.  But 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 something like this:
 
@@ -379,6 +379,17 @@ 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>).
 
+=head2 Why can't I get the output of a command with system()?
+
+You're confusing the purpose of system() and backticks (``).  system()
+runs a command and returns exit status information (as a 16 bit value:
+the low 8 bits are the signal the process died from, if any, and
+the high 8 bits are the actual exit value).  Backticks (``) run a
+command and return what it sent to STDOUT.
+
+    $exit_status   = system("mail-users");
+    $output_string = `ls`;
+
 =head2 How can I capture STDERR from an external command?
 
 There are three basic ways of running external commands:
@@ -437,7 +448,9 @@ process ID of the child.  The child exec()s the command to be piped
 to/from.  The parent can't know whether the exec() was successful or
 not - all it can return is whether the fork() succeeded or not.  To
 find out if the command succeeded, you have to catch SIGCHLD and
-wait() to get the exit status.
+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>.
 
 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
@@ -500,7 +513,7 @@ You have to do this:
 
 Just as with system(), no shell escapes happen when you exec() a list.
 
-=head2 Why can't my script read from STDIN after I gave it EOF (^D on Unix, ^Z on MSDOS)?
+=head2 Why can't my script read from STDIN after I gave it EOF (^D on Unix, ^Z on MS-DOS)?
 
 Because some stdio's set error and eof flags that need clearing.  The
 POSIX module defines clearerr() that you can use.  That is the
@@ -544,9 +557,27 @@ causes many inefficiencies.
 
 =head2 Can I use perl to run a telnet or ftp session?
 
-Try the Net::FTP and TCP::Client modules (available from CPAN).
-http://www.perl.com/CPAN/scripts/netstuff/telnet.emul.shar will also
-help for emulating the telnet protocol.
+Try the Net::FTP, TCP::Client, and Net::Telnet modules (available from
+CPAN).  http://www.perl.com/CPAN/scripts/netstuff/telnet.emul.shar
+will also help for emulating the telnet protocol, but Net::Telnet is
+quite probably easier to use..
+
+If all you want to do is pretend to be telnet but don't need
+the initial telnet handshaking, then the standard dual-process
+approach will suffice:
+
+    use IO::Socket;            # new in 5.004
+    $handle = IO::Socket::INET->new('www.perl.com:80')
+           || die "can't connect to port 80 on www.perl.com: $!";
+    $handle->autoflush(1);
+    if (fork()) {              # XXX: undef means failure
+       select($handle);
+       print while <STDIN>;    # everything from stdin to socket
+    } else {
+       print while <$handle>;  # everything from socket to stdout
+    }
+    close $handle;
+    exit;
 
 =head2 How can I write expect in Perl?
 
@@ -630,20 +661,6 @@ Background yourself like this:
 
 See the F<eg/nih> script (part of the perl source distribution).
 
-=head2 How do I keep my own module/library directory?
-
-When you build modules, use the PREFIX option when generating
-Makefiles:
-
-    perl Makefile.PL PREFIX=/u/mydir/perl
-
-then either set the PERL5LIB environment variable before you run
-scripts that use the modules/libraries (see L<perlrun>) or say
-
-    use lib '/u/mydir/perl';
-
-See Perl's L<lib> for more information.
-
 =head2 How do I find out if I'm running interactively or not?
 
 Good question.  Sometimes C<-t STDIN> and C<-t STDOUT> can give clues,
@@ -741,9 +758,108 @@ If your version of perl is compiled without dynamic loading, then you
 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 L<ExtUtils::MakeMaker> for more details on building extensions
+and an answer to the question "How do I keep my own module/library
+directory?"
+
+=head2 How do I keep my own module/library directory?
+
+When you build modules, use the PREFIX option when generating
+Makefiles:
+
+    perl Makefile.PL PREFIX=/u/mydir/perl
+
+then either set the PERL5LIB environment variable before you run
+scripts that use the modules/libraries (see L<perlrun>) or say
+
+    use lib '/u/mydir/perl';
+
+See Perl's L<lib> for more information.
+
+=head2 How do I add the directory my program lives in to the module/library search path?
+
+    use FindBin;
+    use lib "$FindBin::Bin";
+    use your_own_modules;
+
+=head2 How do I add a directory to my include path at runtime?
+
+Here are the suggested ways of modifying your include path:
+
+    the PERLLIB environment variable
+    the PERL5LIB environment variable
+    the perl -Idir commpand line flag
+    the use lib pragma, as in
+        use lib "$ENV{HOME}/myown_perllib";
+
+The latter is particularly useful because it knows about machine
+dependent architectures.  The lib.pm pragmatic module was first
+included with the 5.002 release of Perl.
+
+=head1 How do I get one key from the terminal at a time, under POSIX?
+
+    #!/usr/bin/perl -w
+    use strict;
+    $| = 1;
+    for (1..4) {
+        my $got;
+        print "gimme: ";
+        $got = getone();
+        print "--> $got\n";
+    }
+    exit;
+
+    BEGIN {
+        use POSIX qw(:termios_h);
+
+        my ($term, $oterm, $echo, $noecho, $fd_stdin);
+
+        $fd_stdin = fileno(STDIN);
+
+        $term     = POSIX::Termios->new();
+        $term->getattr($fd_stdin);
+        $oterm     = $term->getlflag();
+
+        $echo     = ECHO | ECHOK | ICANON;
+        $noecho   = $oterm & ~$echo;
+
+        sub cbreak {
+            $term->setlflag($noecho);
+            $term->setcc(VTIME, 1);
+            $term->setattr($fd_stdin, TCSANOW);
+        }
+
+        sub cooked {
+            $term->setlflag($oterm);
+            $term->setcc(VTIME, 0);
+            $term->setattr($fd_stdin, TCSANOW);
+        }
+
+        sub getone {
+            my $key = '';
+            cbreak();
+            sysread(STDIN, $key, 1);
+            cooked();
+            return $key;
+        }
+
+    }
+    END { cooked() }
 
 =head1 AUTHOR AND COPYRIGHT
 
-Copyright (c) 1997 Tom Christiansen and Nathan Torkington.
-All rights reserved.  See L<perlfaq> for distribution information.
+Copyright (c) 1997, 1998 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.
+
+Irrespective of its distribution, all code examples in this file
+are hereby placed into the public domain.  You are permitted and
+encouraged to use this code in your own programs for fun
+or for profit as you see fit.  A simple comment in the code giving
+credit would be courteous but is not required.