NAME
       fcopy - Copy data from one channel to another.

SYNOPSIS
       fcopy inchan outchan ?-size size? ?-command callback?


DESCRIPTION
       The fcopy command copies data from one I/O channel, inchan
       to another I/O channel, outchan.  The fcopy command lever-
       ages  the  buffering  in the Tcl I/O system to avoid extra
       copies and to avoid buffering too much data in main memory
       when copying large files to slow destinations like network
       sockets.

       The fcopy command transfers data from inchan until end  of
       file  or  size  bytes  have  been transferred. If no -size
       argument is given, then the copy goes until end  of  file.
       All the data read from inchan is copied to outchan.  With-
       out the -command option, fcopy blocks until  the  copy  is
       complete  and  returns  the  number  of  bytes  written to
       outchan.

       The -command argument makes fcopy work in the  background.
       In  this  case  it returns immediately and the callback is
       invoked later when the copy completes.   The  callback  is
       called with one or two additional arguments that indicates
       how many bytes were  written  to  outchan.   If  an  error
       occurred  during  the background copy, the second argument
       is the error string associated with  the  error.   With  a
       background  copy,  it  is  not  necessary to put inchan or
       outchan into non-blocking mode; the  fcopy  command  takes
       care  of  that automatically.  However, it is necessary to
       enter the event loop by using  the  vwait  command  or  by
       using Tk.

       You are not allowed to do other I/O operations with inchan
       or outchan during a background fcopy.  If either inchan or
       outchan get closed while the copy is in progress, the cur-
       rent copy is stopped and the command callback is not made.
       If  inchan  is  closed,  then  all data already queued for
       outchan is written out.

       Note that inchan can become readable during  a  background
       copy.  You should turn off any fileevent handlers during a
       background copy so those handlers do  not  interfere  with
       the  copy.   Any I/O attempted by a fileevent handler will
       get a "channel busy" error.

       Fcopy  translates  end-of-line  sequences  in  inchan  and
       outchan  according  to  the  -translation option for these
       channels.  See the manual entry for fconfigure for details
       on  the  -translation  option.  The translations mean that
       the number of bytes read from inchan can be different than
       the  number  of bytes written to outchan.  Only the number
       of bytes written to outchan is  reported,  either  as  the
       return  value of a synchronous fcopy or as the argument to
       the callback for an asynchronous fcopy.

       Fcopy obeys the encodings  configured  for  the  channels.
       This  means  that  the  incoming  characters are converted
       internally first UTF-8 and then into the encoding  of  the
       channel fcopy writes to. See the manual entry for fconfig-
       ure for details on the -encoding option. No conversion  is
       done  if  both  channels  are set to encoding "binary". If
       only the output channel is set to  encoding  "binary"  the
       system will write the internal UTF-8 representation of the
       incoming characters. If only the input channel is  set  to
       encoding "binary" the system will assume that the incoming
       bytes are valid UTF-8 characters and convert them  accord-
       ing  to  the  output encoding. The behaviour of the system
       for bytes which are not valid UTF-8  characters  is  unde-
       fined in this case.


EXAMPLE
       This  first example shows how the callback gets passed the
       number of bytes transferred.  It also uses  vwait  to  put
       the application into the event loop.  Of course, this sim-
       plified example could be done without  the  command  call-
       back.

              proc Cleanup {in out bytes {error {}}} {
                  global total
                  set total $bytes
                  close $in
                  close $out
                  if {[string length $error] != 0} {
                   # error occurred during the copy
                  }
              }
              set in [open $file1]
              set out [socket $server $port]
              fcopy $in $out -command [list Cleanup $in $out]
              vwait total



       The  second  example copies in chunks and tests for end of
       file in the command callback

              proc CopyMore {in out chunk bytes {error {}}} {
                  global total done
                  incr total $bytes
                  if {([string length $error] != 0) || [eof $in] {
                   set done $total
                   close $in
                   close $out
                  } else {
                   fcopy $in $out -command [list CopyMore $in $out $chunk] \
                       -size $chunk
                  }
              }
              set in [open $file1]
              set out [socket $server $port]
              set chunk 1024
              set total 0
              fcopy $in $out -command [list CopyMore $in $out $chunk] -size $chunk
              vwait done




SEE ALSO
       eof(n), fblocked(n), fconfigure(n)


KEYWORDS
       blocking, channel, end of line, end of file,  nonblocking,
