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  }