github.com/ph/moby@v1.13.1/pkg/directory/directory_unix.go (about) 1 // +build linux freebsd solaris 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, err error) error { 15 if err != nil { 16 // if dir does not exist, Size() returns the error. 17 // if dir/x disappeared while walking, Size() ignores dir/x. 18 if os.IsNotExist(err) && d != dir { 19 return nil 20 } 21 return err 22 } 23 24 // Ignore directory sizes 25 if fileInfo == nil { 26 return nil 27 } 28 29 s := fileInfo.Size() 30 if fileInfo.IsDir() || s == 0 { 31 return nil 32 } 33 34 // Check inode to handle hard links correctly 35 inode := fileInfo.Sys().(*syscall.Stat_t).Ino 36 // inode is not a uint64 on all platforms. Cast it to avoid issues. 37 if _, exists := data[uint64(inode)]; exists { 38 return nil 39 } 40 // inode is not a uint64 on all platforms. Cast it to avoid issues. 41 data[uint64(inode)] = struct{}{} 42 43 size += s 44 45 return nil 46 }) 47 return 48 }