- opendir(DIR, $dirname) or die "can't opendir $dirname: $!";
- while (defined($file = readdir(DIR))) {
- # do something with "$dirname/$file"
- }
- closedir(DIR);
-
-If you want to process directories recursively, it's better to use the
-File::Find module. For example, this prints out all files recursively,
-add adds a slash to their names if the file is a directory.
-
- @ARGV = qw(.) unless @ARGV;
- use File::Find;
- find sub { print $File::Find::name, -d && '/', "\n" }, @ARGV;
-
-This finds all bogus symbolic links beneath a particular directory:
-
- find sub { print "$File::Find::name\n" if -l && !-e }, $dir;
-
-As you see, with symbolic links, you can just pretend that it is
-what it points to. Or, if you want to know I<what> it points to, then
-C<readlink> is called for:
-
- if (-l $file) {
- if (defined($whither = readlink($file))) {
- print "$file points to $whither\n";
- } else {
- print "$file points nowhere: $!\n";
- }
- }
-
-Named pipes are a different matter. You pretend they're regular files,
-but their opens will normally block until there is both a reader and
-a writer. You can read more about them in L<perlipc/"Named Pipes">.
-Unix-domain sockets are rather different beasts as well; they're
-described in L<perlipc/"Unix-Domain TCP Clients and Servers">.
-
-When it comes to opening devices, it can be easy and it can tricky.
-We'll assume that if you're opening up a block device, you know what
-you're doing. The character devices are more interesting. These are
-typically used for modems, mice, and some kinds of printers. This is
-described in L<perlfaq8/"How do I read and write the serial port?">
-It's often enough to open them carefully:
-
- sysopen(TTYIN, "/dev/ttyS1", O_RDWR | O_NDELAY | O_NOCTTY)
- # (O_NOCTTY no longer needed on POSIX systems)
- or die "can't open /dev/ttyS1: $!";
- open(TTYOUT, "+>&TTYIN")
- or die "can't dup TTYIN: $!";
-
- $ofh = select(TTYOUT); $| = 1; select($ofh);
-
- print TTYOUT "+++at\015";
- $answer = <TTYIN>;
-
-With descriptors that you haven't opened using C<sysopen>, such as a
-socket, you can set them to be non-blocking using C<fcntl>:
-
- use Fcntl;
- fcntl(Connection, F_SETFL, O_NONBLOCK)
- or die "can't set non blocking: $!";
-
-Rather than losing yourself in a morass of twisting, turning C<ioctl>s,
-all dissimilar, if you're going to manipulate ttys, it's best to
-make calls out to the stty(1) program if you have it, or else use the
-portable POSIX interface. To figure this all out, you'll need to read the
-termios(3) manpage, which describes the POSIX interface to tty devices,
-and then L<POSIX>, which describes Perl's interface to POSIX. There are
-also some high-level modules on CPAN that can help you with these games.
-Check out Term::ReadKey and Term::ReadLine.
-
-What else can you open? To open a connection using sockets, you won't use
-one of Perl's two open functions. See L<perlipc/"Sockets: Client/Server
-Communication"> for that. Here's an example. Once you have it,
-you can use FH as a bidirectional filehandle.
-
- use IO::Socket;
- local *FH = IO::Socket::INET->new("www.perl.com:80");
-
-For opening up a URL, the LWP modules from CPAN are just what
-the doctor ordered. There's no filehandle interface, but
-it's still easy to get the contents of a document:
-
- use LWP::Simple;
- $doc = get('http://www.sn.no/libwww-perl/');
-
-=head2 Binary Files
-
-On certain legacy systems with what could charitably be called terminally
-convoluted (some would say broken) I/O models, a file isn't a file--at
-least, not with respect to the C standard I/O library. On these old
-systems whose libraries (but not kernels) distinguish between text and
-binary streams, to get files to behave properly you'll have to bend over
-backwards to avoid nasty problems. On such infelicitous systems, sockets
-and pipes are already opened in binary mode, and there is currently no
-way to turn that off. With files, you have more options.
-
-Another option is to use the C<binmode> function on the appropriate
-handles before doing regular I/O on them:
-
- binmode(STDIN);
- binmode(STDOUT);
- while (<STDIN>) { print }
-
-Passing C<sysopen> a non-standard flag option will also open the file in
-binary mode on those systems that support it. This is the equivalent of
-opening the file normally, then calling C<binmode>ing on the handle.
-
- sysopen(BINDAT, "records.data", O_RDWR | O_BINARY)
- || die "can't open records.data: $!";
-
-Now you can use C<read> and C<print> on that handle without worrying
-about the system non-standard I/O library breaking your data. It's not
-a pretty picture, but then, legacy systems seldom are. CP/M will be
-with us until the end of days, and after.
-
-On systems with exotic I/O systems, it turns out that, astonishingly
-enough, even unbuffered I/O using C<sysread> and C<syswrite> might do
-sneaky data mutilation behind your back.
-
- while (sysread(WHENCE, $buf, 1024)) {
- syswrite(WHITHER, $buf, length($buf));
- }
-
-Depending on the vicissitudes of your runtime system, even these calls
-may need C<binmode> or C<O_BINARY> first. Systems known to be free of
-such difficulties include Unix, the Mac OS, Plan9, and Inferno.
-
-=head2 File Locking
-
-In a multitasking environment, you may need to be careful not to collide
-with other processes who want to do I/O on the same files as others
-are working on. You'll often need shared or exclusive locks
-on files for reading and writing respectively. You might just
-pretend that only exclusive locks exist.
-
-Never use the existence of a file C<-e $file> as a locking indication,
-because there is a race condition between the test for the existence of
-the file and its creation. Atomicity is critical.
-
-Perl's most portable locking interface is via the C<flock> function,
-whose simplicity is emulated on systems that don't directly support it,
-such as SysV or WindowsNT. The underlying semantics may affect how
-it all works, so you should learn how C<flock> is implemented on your
-system's port of Perl.
-
-File locking I<does not> lock out another process that would like to
-do I/O. A file lock only locks out others trying to get a lock, not
-processes trying to do I/O. Because locks are advisory, if one process
-uses locking and another doesn't, all bets are off.
-
-By default, the C<flock> call will block until a lock is granted.
-A request for a shared lock will be granted as soon as there is no
-exclusive locker. A request for a exclusive lock will be granted as
-soon as there is no locker of any kind. Locks are on file descriptors,
-not file names. You can't lock a file until you open it, and you can't
-hold on to a lock once the file has been closed.
-
-Here's how to get a blocking shared lock on a file, typically used
-for reading:
-
- use 5.004;
- use Fcntl qw(:DEFAULT :flock);
- open(FH, "< filename") or die "can't open filename: $!";
- flock(FH, LOCK_SH) or die "can't lock filename: $!";
- # now read from FH
-
-You can get a non-blocking lock by using C<LOCK_NB>.
-
- flock(FH, LOCK_SH | LOCK_NB)
- or die "can't lock filename: $!";
-
-This can be useful for producing more user-friendly behaviour by warning
-if you're going to be blocking:
-
- use 5.004;
- use Fcntl qw(:DEFAULT :flock);
- open(FH, "< filename") or die "can't open filename: $!";
- unless (flock(FH, LOCK_SH | LOCK_NB)) {
- $| = 1;
- print "Waiting for lock...";
- flock(FH, LOCK_SH) or die "can't lock filename: $!";
- print "got it.\n"
- }
- # now read from FH
-
-To get an exclusive lock, typically used for writing, you have to be
-careful. We C<sysopen> the file so it can be locked before it gets
-emptied. You can get a nonblocking version using C<LOCK_EX | LOCK_NB>.
-
- use 5.004;
- use Fcntl qw(:DEFAULT :flock);
- sysopen(FH, "filename", O_WRONLY | O_CREAT)
- or die "can't open filename: $!";
- flock(FH, LOCK_EX)
- or die "can't lock filename: $!";
- truncate(FH, 0)
- or die "can't truncate filename: $!";
- # now write to FH
-
-Finally, due to the uncounted millions who cannot be dissuaded from
-wasting cycles on useless vanity devices called hit counters, here's
-how to increment a number in a file safely:
-
- use Fcntl qw(:DEFAULT :flock);
-
- sysopen(FH, "numfile", O_RDWR | O_CREAT)
- or die "can't open numfile: $!";
- # autoflush FH
- $ofh = select(FH); $| = 1; select ($ofh);
- flock(FH, LOCK_EX)
- or die "can't write-lock numfile: $!";
-
- $num = <FH> || 0;
- seek(FH, 0, 0)
- or die "can't rewind numfile : $!";
- print FH $num+1, "\n"
- or die "can't write numfile: $!";
-
- truncate(FH, tell(FH))
- or die "can't truncate numfile: $!";
- close(FH)
- or die "can't close numfile: $!";
-
-=head1 SEE ALSO
-
-The C<open> and C<sysopen> function in perlfunc(1);
-the standard open(2), dup(2), fopen(3), and fdopen(3) manpages;
-the POSIX documentation.