Tizen_4.0 base
[platform/upstream/docker-engine.git] / pkg / directory / directory_unix.go
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 }