package main // import "io" // IO has something just like what we want - except it uses a constant blocksize import "os" import "fmt" import "flag" import "syscall" // const bufsize uint64 = 1024*1024 const bufsize uint64 = 32768 // const bufsize = 32 func usage(retval int) { fmt.Fprintf(os.Stderr, "Usage: snapcat [--max-length n]\n"); os.Exit(retval); } // I'm a little surprised the math package doesn't appear to have a min, but whatever func min(left, right uint64) (uint64) { // Without the result variable, that is, with two returns, I get a compiler error about not returning // a value var result uint64; if (left <= right) { result = left } else { result = right } return result; } func main() { var max_length *int64 = flag.Int64("max-length", -1, "Maximum number of bytes to transfer"); var amount_written int64; var err os.Error; var this_block_length uint64; flag.Parse(); for amount_written = 0; *max_length < 0 || amount_written < *max_length; { var buffer [bufsize]byte; if (*max_length < int64(0)) { this_block_length = bufsize; } else { this_block_length = min(bufsize, uint64(*max_length) - uint64(amount_written)); } // FIXME: Why is this returning an int rather than a uint? length_read, e := syscall.Read(0, buffer[0:this_block_length]); if e != 0 { err = os.Errno(e); fmt.Fprintf(os.Stderr, "Error while reading from stdin: %s\n", err); os.Exit(1); } amount_written += int64(length_read); // fmt.Fprintf(os.Stderr, "Read %d so far\n", amount_written); if length_read == 0 { // EOF break; } var length_written int; var amount_to_write uint64; // FIXME: Why is this returning an int rather than a uint? for amount_to_write = this_block_length; amount_to_write > 0; amount_to_write -= uint64(length_written) { length_written, e = syscall.Write(1, buffer[0:this_block_length]); if e != 0 { err = os.Errno(e); fmt.Fprintf(os.Stderr, "Error while writing to stdout: %s\n", err); os.Exit(1); } } } }