github.com/dara-project/godist@v0.0.0-20200823115410-e0c80c8f0c78/src/os/dir_unix.go (about) 1 // Copyright 2009 The Go 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 // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris 6 7 package os 8 9 import ( 10 "dara" 11 "io" 12 "runtime" 13 "syscall" 14 ) 15 16 const ( 17 blockSize = 4096 18 ) 19 20 func (f *File) readdir(n int) (fi []FileInfo, err error) { 21 dirname := f.name 22 if dirname == "" { 23 dirname = "." 24 } 25 names, err := f.Readdirnames(n) 26 fi = make([]FileInfo, 0, len(names)) 27 for _, filename := range names { 28 fip, lerr := lstat(dirname + "/" + filename) 29 if IsNotExist(lerr) { 30 // File disappeared between readdir + stat. 31 // Just treat it as if it didn't exist. 32 continue 33 } 34 if lerr != nil { 35 if runtime.Is_dara_profiling_on() { 36 runtime.Dara_Debug_Print(func() { 37 print("[Readdir] : ") 38 print(f.file.name) 39 print(" ") 40 println(n) 41 }) 42 argInfo1 := dara.GeneralType{Type:dara.FILE} 43 copy(argInfo1.String[:], f.name) 44 argInfo2 := dara.GeneralType{Type:dara.INTEGER, Integer:n} 45 retInfo1 := dara.GeneralType{Type:dara.ARRAY, Integer: len(fi)} 46 retInfo2 := dara.GeneralType{Type:dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 47 syscallInfo := dara.GeneralSyscall{dara.DSYS_READDIR, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}} 48 runtime.Report_Syscall_To_Scheduler(dara.DSYS_READDIR, syscallInfo) 49 } 50 return fi, lerr 51 } 52 fi = append(fi, fip) 53 } 54 if len(fi) == 0 && err == nil && n > 0 { 55 // Per File.Readdir, the slice must be non-empty or err 56 // must be non-nil if n > 0. 57 err = io.EOF 58 } 59 // DARA Instrumentation 60 if runtime.Is_dara_profiling_on() { 61 runtime.Dara_Debug_Print(func() { 62 print("[Readdir] : ") 63 print(f.file.name) 64 print(" ") 65 println(n) 66 }) 67 argInfo1 := dara.GeneralType{Type:dara.FILE} 68 copy(argInfo1.String[:], f.name) 69 argInfo2 := dara.GeneralType{Type:dara.INTEGER, Integer:n} 70 retInfo1 := dara.GeneralType{Type:dara.ARRAY, Integer: len(fi)} 71 retInfo2 := dara.GeneralType{Type:dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 72 syscallInfo := dara.GeneralSyscall{dara.DSYS_READDIR, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}} 73 runtime.Report_Syscall_To_Scheduler(dara.DSYS_READDIR, syscallInfo) 74 } 75 return fi, err 76 } 77 78 func (f *File) readdirnames(n int) (names []string, err error) { 79 // If this file has no dirinfo, create one. 80 if f.dirinfo == nil { 81 f.dirinfo = new(dirInfo) 82 // The buffer must be at least a block long. 83 f.dirinfo.buf = make([]byte, blockSize) 84 } 85 d := f.dirinfo 86 87 size := n 88 if size <= 0 { 89 size = 100 90 n = -1 91 } 92 93 names = make([]string, 0, size) // Empty with room to grow. 94 for n != 0 { 95 // Refill the buffer if necessary 96 if d.bufp >= d.nbuf { 97 d.bufp = 0 98 var errno error 99 d.nbuf, errno = f.pfd.ReadDirent(d.buf) 100 runtime.KeepAlive(f) 101 if errno != nil { 102 if runtime.Is_dara_profiling_on() { 103 runtime.Dara_Debug_Print(func() { 104 print("[Readdirnames] : ") 105 print(f.file.name) 106 print(" ") 107 println(n) 108 }) 109 argInfo1 := dara.GeneralType{Type: dara.FILE} 110 copy(argInfo1.String[:], f.name) 111 argInfo2 := dara.GeneralType{Type: dara.INTEGER, Integer:n} 112 retInfo1 := dara.GeneralType{Type: dara.ARRAY, Integer: len(names)} 113 retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 114 syscallInfo := dara.GeneralSyscall{dara.DSYS_READDIRNAMES, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}} 115 runtime.Report_Syscall_To_Scheduler(dara.DSYS_READDIRNAMES, syscallInfo) 116 } 117 return names, wrapSyscallError("readdirent", errno) 118 } 119 if d.nbuf <= 0 { 120 break // EOF 121 } 122 } 123 124 // Drain the buffer 125 var nb, nc int 126 nb, nc, names = syscall.ParseDirent(d.buf[d.bufp:d.nbuf], n, names) 127 d.bufp += nb 128 n -= nc 129 } 130 if n >= 0 && len(names) == 0 { 131 if runtime.Is_dara_profiling_on() { 132 runtime.Dara_Debug_Print(func() { 133 print("[Readdirnames] : ") 134 print(f.file.name) 135 print(" ") 136 println(n) 137 }) 138 argInfo1 := dara.GeneralType{Type: dara.FILE} 139 copy(argInfo1.String[:], f.name) 140 argInfo2 := dara.GeneralType{Type: dara.INTEGER, Integer:n} 141 retInfo1 := dara.GeneralType{Type: dara.ARRAY, Integer: len(names)} 142 retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 143 syscallInfo := dara.GeneralSyscall{dara.DSYS_READDIRNAMES, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}} 144 runtime.Report_Syscall_To_Scheduler(dara.DSYS_READDIRNAMES, syscallInfo) 145 } 146 return names, io.EOF 147 } 148 // DARA Instrumentation 149 if runtime.Is_dara_profiling_on() { 150 runtime.Dara_Debug_Print(func() { 151 print("[Readdirnames] : ") 152 print(f.file.name) 153 print(" ") 154 println(n) 155 }) 156 argInfo1 := dara.GeneralType{Type: dara.FILE} 157 copy(argInfo1.String[:], f.name) 158 argInfo2 := dara.GeneralType{Type: dara.INTEGER, Integer:n} 159 retInfo1 := dara.GeneralType{Type: dara.ARRAY, Integer: len(names)} 160 retInfo2 := dara.GeneralType{Type: dara.ERROR, Unsupported: dara.UNSUPPORTEDVAL} 161 syscallInfo := dara.GeneralSyscall{dara.DSYS_READDIRNAMES, 2, 2, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo1, retInfo2}} 162 runtime.Report_Syscall_To_Scheduler(dara.DSYS_READDIRNAMES, syscallInfo) 163 } 164 return names, nil 165 }