github.com/fhs/u-root@v7.0.0+incompatible/cmds/core/truncate/truncate.go (about)

     1  // Copyright 2013-2017 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  // Truncate - shrink or extend the size of a file to the specified size
     6  //
     7  // Synopsis:
     8  //     truncate [OPTIONS] [FILE]...
     9  //
    10  // Options:
    11  //     -s: size in bytes
    12  //     -c: do not create any files
    13  //
    14  // Author:
    15  //     Roland Kammerer <dev.rck@gmail.com>
    16  package main
    17  
    18  import (
    19  	"flag"
    20  	"io/ioutil"
    21  	"log"
    22  	"os"
    23  
    24  	"github.com/rck/unit"
    25  )
    26  
    27  const cmd = "truncate [-c] -s size file..."
    28  
    29  var (
    30  	create = flag.Bool("c", false, "Do not create files.")
    31  	size   = unit.MustNewUnit(unit.DefaultUnits).MustNewValue(1, unit.None)
    32  )
    33  
    34  func init() {
    35  	flag.Var(size, "s", "Size in bytes, prefixes +/- are allowed")
    36  
    37  	defUsage := flag.Usage
    38  	flag.Usage = func() {
    39  		os.Args[0] = cmd
    40  		defUsage()
    41  	}
    42  }
    43  
    44  func usageAndExit() {
    45  	flag.Usage()
    46  	os.Exit(1)
    47  }
    48  
    49  func main() {
    50  	flag.Parse()
    51  
    52  	if !size.IsSet {
    53  		log.Println("truncate: ERROR: You need to specify -s <number>.")
    54  		usageAndExit()
    55  	}
    56  	if flag.NArg() == 0 {
    57  		log.Println("truncate: ERROR: You need to specify one or more files as argument.")
    58  		usageAndExit()
    59  	}
    60  
    61  	for _, fname := range flag.Args() {
    62  		st, err := os.Stat(fname)
    63  		if os.IsNotExist(err) && !*create {
    64  			if err = ioutil.WriteFile(fname, []byte{}, 0644); err != nil {
    65  				log.Fatalf("truncate: ERROR: %v\n", err)
    66  			}
    67  			if st, err = os.Stat(fname); err != nil {
    68  				log.Fatalf("truncate: ERROR: could not stat newly created file: %v\n", err)
    69  			}
    70  		}
    71  
    72  		final := size.Value // base case
    73  		if size.ExplicitSign != unit.None {
    74  			final += st.Size() // in case of '-', size.Value is already negative
    75  		}
    76  		if final < 0 {
    77  			final = 0
    78  		}
    79  
    80  		// intentionally ignore, like GNU truncate
    81  		os.Truncate(fname, final)
    82  	}
    83  }