Example #1
0
func main() {
	flag.Usage = func() {
		fmt.Printf("Usage: %s [OPTION]... [FILE]\n", flag.Program)
		fmt.Printf(`Output who is currently logged in according to FILE.
If FILE is not specified, use %s. %s as FILE is common.

`,
			utmp.UtmpxFile, utmp.Wtmpxfile)
		flag.PrintDefaults()
		fmt.Printf(`
Report %s bugs to [email protected]
Go coreutils home page: <https://www.github.com/EricLagergren/go-coreutils/>
`, flag.Program)
		os.Exit(0)
	}

	flag.Parse()

	switch flag.NArg() {
	case 0:
		users(utmp.UtmpxFile, utmp.CheckPIDs)
	case 1:
		users(flag.Arg(0), 0)
	default:
		log.Fatalf("extra operand(s) %v", flag.Args()[1:])
	}

}
Example #2
0
func main() {
	var ok int // return status

	outStat, err := os.Stdout.Stat()
	if err != nil {
		fatal.Fatalln(err)
	}
	outReg := outStat.Mode().IsRegular()
	outBsize := bsize(outStat)

	// catch (./cat) < /etc/group
	args := flag.Args()
	if flag.NArg() == 0 {
		args = []string{"-"}
	}

	var file *os.File
	for _, arg := range args {
		file = os.Stdin
		if arg != "-" {
			file, err = os.Open(arg)
			if err != nil {
				fatal.Fatalln(err)
			}
		}

		inStat, err := file.Stat()
		if err != nil {
			fatal.Fatalln(err)
		}
		if inStat.IsDir() {
			fatal.Printf("%s: is a directory\n", file.Name())
		}
		inBsize := bsize(inStat)

		// prefetch! prefetch! prefetch!
		unix.Fadvise(int(file.Fd()), 0, 0, unix.FADV_SEQUENTIAL)

		// Make sure we're not catting a file to itself,
		// provided it's a regular file. Catting a non-reg
		// file to itself is cool.
		// e.g. cat file > file
		if outReg && os.SameFile(outStat, inStat) {
			if n, _ := file.Seek(0, os.SEEK_CUR); n < inStat.Size() {
				fatal.Fatalf("%s: input file is output file\n", file.Name())
			}
		}

		pageSize := os.Getpagesize()
		if simple {
			// Select larger block size
			size := max(inBsize, outBsize)
			outBuf := bufio.NewWriterSize(os.Stdout, size+pageSize-1)
			ok ^= simpleCat(file, outBuf)

			// Flush because we don't have a chance to in
			// simpleCat() because we use io.Copy()
			outBuf.Flush()
		} else {
			// If you want to know why, exactly, I chose
			// outBsize -1 + inBsize*4 + 20, read GNU's cat
			// source code. The tl;dr is the 20 is the counter
			// buffer, inBsize*4 is from potentially prepending
			// the control characters (M-^), and outBsize is
			// due to new tests for newlines.
			size := outBsize - 1 + inBsize*4 + 20
			outBuf := bufio.NewWriterSize(os.Stdout, size)
			inBuf := make([]byte, inBsize+pageSize-1)
			ok ^= cat(file, inBuf, outBuf)
		}

		file.Close()
	}

	os.Exit(ok)
}
Example #3
0
func main() {
	flag.Usage = func() {
		fmt.Printf(`Usage: %s [OPTION]... [FILE]...
  or:  wc [OPTION]... --files0-from=F
Print newline, word, and byte counts for each FILE, and a total line if
more than one FILE is specified.  A word is a non-zero-length sequence of
characters delimited by white space.

With no FILE, or when FILE is -, read standard input.

The options below may be used to select which counts are printed, always in
the following order: newline, word, character, byte, maximum line length.
`, flag.Program)
		flag.PrintDefaults()
		fmt.Printf(`
Report %s bugs to [email protected]
Go coreutils home page: <https://www.github.com/EricLagergren/go-coreutils/>
`, flag.Program)
		os.Exit(0)
	}
	flag.ProgVersion = "2.2"
	flag.Parse()

	if *constVersion {
		fmt.Printf("Unicode Version: %s\n", unicode.Version)
		os.Exit(0)
	}

	if !(*printBytes || *printChars ||
		*printLines || *printWords || *printLineLength) {
		*printLines = true
		*printBytes = true
		*printWords = true
	}

	// This is a gross attempt to simulate this...
	// (print_lines + print_words + print_chars +
	//	print_bytes + print_linelength) == 1
	//
	// Since Go can't add booleans (e.g. false + true == 1)
	// and checking that *only* one of 5 bool variables would be sloppy,
	// we check the number of set flags and the remaining non-'print' flags
	// which is a much smaller set of conditions to check
	//
	//	I could just use a loop, but this also removes a branch soooo...
	printOne =
		// 1 flag and it's not *filesFrom OR *tabWidth
		((flag.NFlag() == 1 && *filesFrom == "" && *tabWidth == 8) ||
			// 2 flags and one is *filesFrom OR *tabWidth
			(flag.NFlag() == 2 && (*filesFrom != "" || *tabWidth != 8)) ||
			// 3 flags and two are *filesFrom AND *tabWidth
			(flag.NFlag() == 3 && *filesFrom != "" && *tabWidth != 8))

	var (
		ok         int           // Return status.
		files      = flag.Args() // List of files.
		numFiles   = len(files)  // Number of files to wc.
		reasonable = true        // Can we read file list into memory?
		size       int64
	)

	if *filesFrom != "" {
		// Cannot specify files with --files0-from.
		if flag.NArg() > 0 {
			fatal("file operands cannot be combined with --files0-from")
		}

		// --files0-from is small enough to fit into RAM.
		if reasonable, size = isReasonable(*filesFrom); reasonable {
			files, numFiles = getFileList(*filesFrom, size)
		}
	}

	fs := getFileStatus(files)
	numberWidth = findNumberWidth(fs)

	if reasonable {
		if files == nil || len(files) == 0 {
			files = []string{"-"}
		}
		for i, file := range files {
			ok ^= wcFile(file, fs[i])
		}
	} else {
		var err error

		file := os.Stdin
		if *filesFrom != "-" {
			file, err = os.Open(*filesFrom)
		}

		if err != nil {
			fatal("cannot open %q for reading: No such file or directory", *filesFrom)
		}
		defer file.Close()

		s := bufio.NewScanner(file)
		s.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
			if atEOF && len(data) == 0 {
				return 0, nil, nil
			}
			if i := bytes.IndexByte(data, nullByte); i >= 0 {
				// We have a full newline-terminated line.
				return i + 1, dropnullByte(numFiles, data[0:i]), nil
			}
			// If we're at EOF, we have a final, non-terminated line. Return it.
			if atEOF {
				return len(data), dropnullByte(numFiles, data), nil
			}
			// Request more data.
			return 0, nil, nil
		})
		for ; s.Scan(); numFiles++ {
			ok ^= wcFile(s.Text(), fstatus{})
		}
		if err := s.Err(); err != nil {
			fatal("%v", err)
		}
	}

	if numFiles > 1 {
		writeCounts(totalLines, totalWords,
			totalChars, totalBytes, maxLineLength, "total")
	}

	// Return status.
	os.Exit(ok)
}