github.com/dtromb/docker@v1.6.0/pkg/directory/directory_linux.go (about)

     1  // +build linux
     2  
     3  package directory
     4  
     5  import (
     6  	"os"
     7  	"path/filepath"
     8  	"syscall"
     9  )
    10  
    11  // Size walks a directory tree and returns its total size in bytes.
    12  func Size(dir string) (size int64, err error) {
    13  	data := make(map[uint64]struct{})
    14  	err = filepath.Walk(dir, func(d string, fileInfo os.FileInfo, e error) error {
    15  		// Ignore directory sizes
    16  		if fileInfo == nil {
    17  			return nil
    18  		}
    19  
    20  		s := fileInfo.Size()
    21  		if fileInfo.IsDir() || s == 0 {
    22  			return nil
    23  		}
    24  
    25  		// Check inode to handle hard links correctly
    26  		inode := fileInfo.Sys().(*syscall.Stat_t).Ino
    27  		// inode is not a uint64 on all platforms. Cast it to avoid issues.
    28  		if _, exists := data[uint64(inode)]; exists {
    29  			return nil
    30  		}
    31  		// inode is not a uint64 on all platforms. Cast it to avoid issues.
    32  		data[uint64(inode)] = struct{}{}
    33  
    34  		size += s
    35  
    36  		return nil
    37  	})
    38  	return
    39  }