
=encoding utf8

=head1 Title

DRAFT: Synopsis 16: IPC / IO / Signals

=head1 Version

 Author:        Largely, the authors of the related Perl 5 docs.
 Maintainer:    Larry Wall <larry@wall.org>
 Contributions: Mark Stosberg <mark@summersault.com>
 Date:          12 Sep 2006
 Last Modified: 25 Sep 2006
 Version:       15  

This is a draft document. Many of these functions will work as in Perl 5,
except we're trying to rationalize everything into packages.  For now you can
assume most of the important ones will automatically be in the * namespace.

As a starting point, you can help by finding the official Perl 5 documentation
for these functions and copying it here. 

=head1 Filehandles, files, and directories

=over 4

=item -X

=over 8

=item -X FILEHANDLE
X<-r>X<-w>X<-x>X<-o>X<-R>X<-W>X<-X>X<-O>X<-e>X<-z>X<-s>X<-f>X<-d>X<-l>X<-p>
X<-S>X<-b>X<-c>X<-t>X<-u>X<-g>X<-k>X<-T>X<-B>X<-M>X<-A>X<-C>

=item -X EXPR

=item -X

  -X $file  
  $file.'-X'

A file test, where X is one of the letters listed below.  This unary
operator takes one argument, either a filename or a filehandle, and
tests the associated file to see if something is true about it.
The argument may not be omitted unless it is C<$_>, in which case you must
use the C<.'-X'> form.

All file test operators return a stat buffer that also carries a "cumulative
success" boolean (or file size in the case of C<-s>) so that tests may be stacked:

    -r -w $filename

or applied to existing stat buffers:

    $b = stat($filename);
    if -r $b {...}

Despite the funny
names, precedence is the same as any other named unary operator, and
the argument may be parenthesized like any other unary operator.  The
operator may be any of:

    -r	File is readable by effective uid/gid.
    -w	File is writable by effective uid/gid.
    -x	File is executable by effective uid/gid.
    -o	File is owned by effective uid.

    -R	File is readable by real uid/gid.
    -W	File is writable by real uid/gid.
    -X	File is executable by real uid/gid.
    -O	File is owned by real uid.

    -e	File exists.
    -z	File has zero size (is empty).
    -s	File has nonzero size (returns size in bytes).

    -f	File is a plain file.
    -d	File is a directory.
    -l	File is a symbolic link.
    -p	File is a named pipe (FIFO), or Filehandle is a pipe.
    -S	File is a socket.
    -b	File is a block special file.
    -c	File is a character special file.
    -t	Filehandle is opened to a tty.

    -u	File has setuid bit set.
    -g	File has setgid bit set.
    -k	File has sticky bit set.

    -T	File is an ASCII text file (heuristic guess).
    -B	File is a "binary" file (opposite of -T).

    -M	Script start time minus file modification time, in days.
    -A	Same for access time.
    -C	Same for inode change time (Unix, may differ for other platforms)

The interpretation of the file permission operators C<-r>, C<-R>,
C<-w>, C<-W>, C<-x>, and C<-X> is by default based solely on the mode
of the file and the uids and gids of the user.  There may be other
reasons you can't actually read, write, or execute the file.  Such
reasons may be for example network filesystem access controls, ACLs
(access control lists), read-only filesystems, and unrecognized
executable formats.

Also note that, for the superuser on the local filesystems, the C<-r>,
C<-R>, C<-w>, and C<-W> tests always return 1, and C<-x> and C<-X> return 1
if any execute bit is set in the mode.  Scripts run by the superuser
may thus need to do a stat() to determine the actual mode of the file,
or temporarily set their effective uid to something else.

If you are using ACLs, there is a pragma called C<filetest> that may
produce more accurate results than the bare stat() mode bits.
When under the C<use filetest 'access'> the above-mentioned filetests
will test whether the permission can (not) be granted using the
access() family of system calls.  Also note that the C<-x> and C<-X> may
under this pragma return true even if there are no execute permission
bits set (nor any extra execute permission ACLs).  This strangeness is
due to the underlying system calls' definitions.  Read the
documentation for the C<filetest> pragma for more information.

Note that C<-s/a/b/> does not do a negated substitution.  Saying
C<-exp($foo)> still works as expected, however--only single letters
following a minus are interpreted as file tests.

The C<-T> and C<-B> switches work as follows.  The first block or so of the
file is examined for odd characters such as strange control codes or
characters with the high bit set.  If too many strange characters (>30%)
are found, it's a C<-B> file; otherwise it's a C<-T> file.  Also, any file
containing null in the first block is considered a binary file.  If C<-T>
or C<-B> is used on a filehandle, the current IO buffer is examined
rather than the first block.  Both C<-T> and C<-B> return true on a null
file, or a file at EOF when testing a filehandle.  Because you have to
read a file to do the C<-T> test, on most occasions you want to use a C<-f>
against the file first, as in C<next unless -f $file && -T $file>.

The return value of a test is both a boolean and a stat buffer. So you can say:

  if -r -w -x $filename {...}

Or chain tests together in OO style:
 
  if $filename.'-e'.'-x' {...}

=item chown

=item chmod LIST
X<chmod> X<permission> X<mode>

Changes the permissions of a list of files.  The first element of the
list must be the numerical mode, which should probably be an octal
number, and which definitely should I<not> be a string of octal digits:
C<0o644> is okay, C<0644> is not.  Returns the number of files
successfully changed.

    $cnt = chmod 0o755, 'foo', 'bar';
    chmod 0o755, @executables;
    $mode = '0644'; chmod $mode, 'foo';      # !!! sets mode to --w----r-T
    $mode = '0o644'; chmod $mode, 'foo';     # this is better
    $mode = 0o644;   chmod $mode, 'foo';     # this is best

=item close FILEHANDLE

Closes the file or pipe associated with the file handle, returning
true only if IO buffers are successfully flushed and closes the system
file descriptor.  Closes the currently selected filehandle if the
argument is omitted.

You don't have to close FILEHANDLE if you are immediately going to do
another C<open> on it, because C<open> will close it for you.  (See
C<open>.)  However, an explicit C<close> on an input file resets the line
counter (C<$.>), while the implicit close done by C<open> does not.

If the file handle came from a piped open, C<close> will additionally
return false if one of the other system calls involved fails, or if the
program exits with non-zero status.  (If the only problem was that the
program exited non-zero, C<$!> will be set to C<0>.)  Closing a pipe
also waits for the process executing on the pipe to complete, in case you
want to look at the output of the pipe afterwards, and
implicitly puts the exit status value of that command into C<$!>.

=item closedir

 closedir (IO::Dir $dir)  
 $dir.closedir

Closes a directory opened by C<opendir> and returns the success of that
system call.

=item connect

 my $fh = connect($hostname, 80);

Attempts to connect to a remote host and returns an IO handle if successful.
The call fails with an exception if it cannot connect.

=item fcntl

=item glob

=item ioctl

=item link

=item listen

=item lstat

Returns a stat buffer.  If the lstat succeeds, the stat buffer evaluates
to true, and additional file tests may be performed on the value.  If
the stat fails, all subsequent tests on the stat buffer also evaluate
to false.

=item mkdir

=item open

    # Read
    my $fh = open($filename);

    # Write
    my $fh = open($filename, :w);

=item opendir EXPR

  my $dir = opendir('.');

Opens a directory named EXPR for processing by C<readdir>, C<telldir>,
C<seekdir>, C<rewinddir>, and C<closedir>.  Returns an C<IO::Dir> object if
successful.

=item readdir

 readdir (IO::Dir $dir)  
 $dir.readdir

Returns the next directory entry for a directory opened by C<opendir>.
If used in list context, returns all the rest of the entries in the
directory.  If there are no more entries, returns an undefined value in
scalar context or a null list in list context.

If you're planning to filetest the return values out of a C<readdir>, you'd
better prepend the directory in question.  Otherwise, because we didn't
C<chdir> there, it would have been testing the wrong file.

=item readlink

=item rename

=item rewinddir

 rewinddir (IO::Dir $dir)  
 $dir.rewinddir

Sets the current position to the beginning of the directory for the
C<readdir> routine on DIRHANDLE.

=item rmdir FILENAME
X<rmdir> X<rd> X<directory, remove>

=item rmdir

Deletes the directory specified by FILENAME if that directory is
empty.  If it succeeds it returns true, otherwise it returns false and
sets C<$!> (errno).  If FILENAME is omitted, uses C<$_>.

=item stat

Returns a stat buffer.  If the lstat succeeds, the stat buffer evaluates
to true, and additional file tests may be performed on the value.  If
the stat fails, all subsequent tests on the stat buffer also evaluate
to false.

=item symlink

=item syscall

=item sysopen

=item umask

=item unlink LIST
X<unlink> X<delete> X<remove> X<rm>

=item unlink

Deletes a list of files.  Returns the number of files successfully
deleted.

    $cnt = unlink 'a', 'b', 'c';

Be warned that unlinking a directory can inflict damage on your filesystem.
Finally, using C<unlink> on directories is not supported on many operating
systems.  Use C<rmdir> instead.

If LIST is omitted, uses C<$_>.

=item utime

=back

=head1 Input and Output

=over 4

=item getc FILEHANDLE

Returns the next character from the input file attached to FILEHANDLE,
or the undefined value at end of file, or if there was an error (in
the latter case C<$!> is set). 

=item print FILEHANDLE LIST
X<print>

=item print LIST

=item print

Prints a string or a list of strings.  Returns true if successful.
FILEHANDLE may be a scalar variable name, in which case the variable
contains the name of or a reference to the filehandle, thus introducing
one level of indirection.  (NOTE: If FILEHANDLE is a variable and
the next token is a term, it may be misinterpreted as an operator
unless you interpose a C<+> or put parentheses around the arguments.)
If FILEHANDLE is omitted, prints by default to standard output (or
to the last selected output channel--see L</select>).  If LIST is
also omitted, prints C<$_> to the currently selected output channel.
To set the default output channel to something other than STDOUT
use the select operation.  

=begin comment

[ I don't know what's become of $, and $\. -markstos ] 

The current value of C<$,> (if any) is
printed between each LIST item.  The current value of C<$\> (if
any) is printed after the entire LIST has been printed. 

=end comment

Because print takes a LIST, anything in the LIST is evaluated in list context,
and any subroutine that you call will have one or more of its expressions
evaluated in list context.  Also be careful not to follow the print keyword
with a left parenthesis unless you want the corresponding right parenthesis to
terminate the arguments to the print--interpose a C<+> or put parentheses
around all the arguments.

Note that if you're storing FILEHANDLEs in an array, or if you're using
any other expression more complex than a scalar variable to retrieve it,
you will have to use a block returning the filehandle value instead:

    print { @files[$i] } "stuff\n";
    print { $OK ?? STDOUT !! STDERR } "stuff\n";

=item printf

=item say

This is a version of print() that auto-appends a newline:

    Was:    print "Hello, world!\n";
    Now:    say   "Hello, world!";

=back

=head1 Unfiled

=over 4

=item fileno

=item flock

=item getpeername

=item eof

=item accept

=item /[get|set][host|net|proto|serv|sock].*/

=item alarm

=item bind

=item binmode

=item lines

    our List multi method lines (IO $handle:) is export;
    our List multi lines (Str $filename);

Returns all the lines of a file as a (lazy) List regardless of context.
See also C<slurp>.

=item pipe

=item read

=item readline

=item readpipe

=item recv

=item seek

=item seekdir

=item select(both)

=item send

=item setsockopt

=item shutdown

=item slurp

    our Item multi method slurp (IO $handle: *%opts) is export;
    our Item multi slurp (Str $filename, *%opts);

Slurps the entire file into a Str or Buf regardless of context.
(See also C<lines>.)  Whether a Str or Buf is returneded depends on
the options.

=item socket

=item socketpair

=item sysread

=item sysseek

=item syswrite

=item tell

=item telldir

=item truncate

=item warn

=back

=head1 Additions

Please post errors and feedback to perl6-language.  If you are making
a general laundry list, please separate messages by topic.
