github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/os_other.go (about) 1 //go:build plan9 || solaris 2 // +build plan9 solaris 3 4 // Copyright (c) 2015-2021 MinIO, Inc. 5 // 6 // This file is part of MinIO Object Storage stack 7 // 8 // This program is free software: you can redistribute it and/or modify 9 // it under the terms of the GNU Affero General Public License as published by 10 // the Free Software Foundation, either version 3 of the License, or 11 // (at your option) any later version. 12 // 13 // This program is distributed in the hope that it will be useful 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU Affero General Public License for more details. 17 // 18 // You should have received a copy of the GNU Affero General Public License 19 // along with this program. If not, see <http://www.gnu.org/licenses/>. 20 21 package cmd 22 23 import ( 24 "io" 25 "os" 26 "syscall" 27 ) 28 29 func access(name string) error { 30 _, err := os.Lstat(name) 31 return err 32 } 33 34 func osMkdirAll(dirPath string, perm os.FileMode, _ string) error { 35 // baseDir is not honored in plan9 and solaris platforms. 36 return os.MkdirAll(dirPath, perm) 37 } 38 39 // readDirFn applies the fn() function on each entries at dirPath, doesn't recurse into 40 // the directory itself, if the dirPath doesn't exist this function doesn't return 41 // an error. 42 func readDirFn(dirPath string, filter func(name string, typ os.FileMode) error) error { 43 d, err := Open(dirPath) 44 if err != nil { 45 if osErrToFileErr(err) == errFileNotFound { 46 return nil 47 } 48 return osErrToFileErr(err) 49 } 50 defer d.Close() 51 52 maxEntries := 1000 53 for { 54 // Read up to max number of entries. 55 fis, err := d.Readdir(maxEntries) 56 if err != nil { 57 if err == io.EOF { 58 break 59 } 60 err = osErrToFileErr(err) 61 if err == errFileNotFound { 62 return nil 63 } 64 return err 65 } 66 for _, fi := range fis { 67 if fi.Mode()&os.ModeSymlink == os.ModeSymlink { 68 fi, err = Stat(pathJoin(dirPath, fi.Name())) 69 if err != nil { 70 // It got deleted in the meantime, not found 71 // or returns too many symlinks ignore this 72 // file/directory. 73 if osIsNotExist(err) || isSysErrPathNotFound(err) || 74 isSysErrTooManySymlinks(err) { 75 continue 76 } 77 return err 78 } 79 80 // Ignore symlinked directories. 81 if fi.IsDir() { 82 continue 83 } 84 } 85 if err = filter(fi.Name(), fi.Mode()); err == errDoneForNow { 86 // filtering requested to return by caller. 87 return nil 88 } 89 } 90 } 91 return nil 92 } 93 94 // Return entries at the directory dirPath. 95 func readDirWithOpts(dirPath string, opts readDirOpts) (entries []string, err error) { 96 d, err := Open(dirPath) 97 if err != nil { 98 return nil, osErrToFileErr(err) 99 } 100 defer d.Close() 101 102 maxEntries := 1000 103 if opts.count > 0 && opts.count < maxEntries { 104 maxEntries = opts.count 105 } 106 107 done := false 108 remaining := opts.count 109 110 for !done { 111 // Read up to max number of entries. 112 fis, err := d.Readdir(maxEntries) 113 if err != nil { 114 if err == io.EOF { 115 break 116 } 117 return nil, osErrToFileErr(err) 118 } 119 if opts.count > -1 { 120 if remaining <= len(fis) { 121 fis = fis[:remaining] 122 done = true 123 } 124 } 125 for _, fi := range fis { 126 if fi.Mode()&os.ModeSymlink == os.ModeSymlink { 127 fi, err = Stat(pathJoin(dirPath, fi.Name())) 128 if err != nil { 129 // It got deleted in the meantime, not found 130 // or returns too many symlinks ignore this 131 // file/directory. 132 if osIsNotExist(err) || isSysErrPathNotFound(err) || 133 isSysErrTooManySymlinks(err) { 134 continue 135 } 136 return nil, err 137 } 138 139 // Ignore symlinked directories. 140 if !opts.followDirSymlink && fi.IsDir() { 141 continue 142 } 143 } 144 145 if fi.IsDir() { 146 // Append SlashSeparator instead of "\" so that sorting is achieved as expected. 147 entries = append(entries, fi.Name()+SlashSeparator) 148 } else if fi.Mode().IsRegular() { 149 entries = append(entries, fi.Name()) 150 } 151 if opts.count > 0 { 152 remaining-- 153 } 154 } 155 } 156 return entries, nil 157 } 158 159 func globalSync() { 160 // no-op not sure about plan9/solaris support for syscall support 161 defer globalOSMetrics.time(osMetricSync)() 162 syscall.Sync() 163 }