github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/cmds/core/readlink/readlink.go (about)

     1  // Copyright 2013-2022 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // readlink display value of symbolic link file.
     6  //
     7  // Synopsis:
     8  //
     9  //	readlink [OPTIONS] [FILE...]
    10  //
    11  // Options:
    12  //
    13  //	-f: follow
    14  //	-n: nonewline
    15  //	-v: verbose
    16  package main
    17  
    18  import (
    19  	"flag"
    20  	"fmt"
    21  	"io"
    22  	"os"
    23  	"path/filepath"
    24  )
    25  
    26  const cmd = "readlink [-fnv] FILE"
    27  
    28  var (
    29  	follow    = flag.Bool("f", false, "follow recursively")
    30  	noNewLine = flag.Bool("n", false, "do not output trailing newline")
    31  	verbose   = flag.Bool("v", false, "report error messages")
    32  )
    33  
    34  func init() {
    35  	defUsage := flag.Usage
    36  	flag.Usage = func() {
    37  		os.Args[0] = cmd
    38  		defUsage()
    39  	}
    40  }
    41  
    42  func readLink(stdout io.Writer, file string) error {
    43  	path, err := os.Readlink(file)
    44  	if err != nil {
    45  		return err
    46  	}
    47  
    48  	if *follow {
    49  		path, err = filepath.EvalSymlinks(file)
    50  	}
    51  
    52  	delimiter := "\n"
    53  	if *noNewLine {
    54  		delimiter = ""
    55  	}
    56  
    57  	fmt.Fprintf(stdout, "%s%s", path, delimiter)
    58  	return err
    59  }
    60  
    61  func run(stdout io.Writer, stderr io.Writer, args []string) error {
    62  	if len(args) == 0 {
    63  		if *verbose {
    64  			fmt.Fprintf(stderr, "missing operand")
    65  		}
    66  		return fmt.Errorf("missing operand")
    67  	}
    68  
    69  	var runErr error
    70  	for _, file := range args {
    71  		err := readLink(stdout, file)
    72  		if err != nil {
    73  			if *verbose {
    74  				fmt.Fprintf(stderr, "%v\n", err)
    75  			}
    76  			runErr = err
    77  		}
    78  	}
    79  
    80  	return runErr
    81  }
    82  
    83  func main() {
    84  	flag.Parse()
    85  	if err := run(os.Stdin, os.Stderr, flag.Args()); err != nil {
    86  		os.Exit(1)
    87  	}
    88  }