// Copyright 2015 The etcd Authors//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.
// Package fileutil implements utility functions related to files and paths.
package fileutilimport ()const (// PrivateFileMode grants owner to read/write a file.PrivateFileMode = 0600)var ( plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "pkg/fileutil"))// IsDirWriteable checks if dir is writable by writing and removing a file// to dir. It returns nil if dir is writable.func ( string) error { := filepath.Join(, ".touch")if := ioutil.WriteFile(, []byte(""), PrivateFileMode); != nil {return }returnos.Remove()}// ReadDir returns the filenames in the given directory in sorted order.func ( string) ([]string, error) { , := os.Open()if != nil {returnnil, }defer .Close() , := .Readdirnames(-1)if != nil {returnnil, }sort.Strings()return , nil}// TouchDirAll is similar to os.MkdirAll. It creates directories with 0700 permission if any directory// does not exists. TouchDirAll also ensures the given directory is writable.func ( string) error {// If path is already a directory, MkdirAll does nothing and returns nil, so, // first check if dir exist with an expected permission mode.ifExist() { := CheckDirPermission(, PrivateDirMode)if != nil {plog.Warningf("check file permission: %v", ) } } else { := os.MkdirAll(, PrivateDirMode)if != nil {// if mkdirAll("a/text") and "text" is not // a directory, this will return syscall.ENOTDIRreturn } }returnIsDirWriteable()}// CreateDirAll is similar to TouchDirAll but returns error// if the deepest directory was not empty.func ( string) error { := TouchDirAll()if == nil {var []string , = ReadDir()if != nil {return }iflen() != 0 { = fmt.Errorf("expected %q to be empty, got %q", , ) } }return}func ( string) bool { , := os.Stat()return == nil}// ZeroToEnd zeros a file starting from SEEK_CUR to its SEEK_END. May temporarily// shorten the length of the file.func ( *os.File) error {// TODO: support FALLOC_FL_ZERO_RANGE , := .Seek(0, io.SeekCurrent)if != nil {return } , := .Seek(0, io.SeekEnd)if != nil {return }if = .Truncate(); != nil {return }// make sure blocks remain allocatedif = Preallocate(, , true); != nil {return } _, = .Seek(, io.SeekStart)return}// CheckDirPermission checks permission on an existing dir.// Returns error if dir is empty or exist with a different permission than specified.func ( string, os.FileMode) error {if !Exist() {returnfmt.Errorf("directory %q empty, cannot check permission.", ) }//check the existing permission on the directory , := os.Stat()if != nil {return } := .Mode().Perm()if != { = fmt.Errorf("directory %q exist, but the permission is %q. The recommended permission is %q to prevent possible unprivileged access to the data.", , .Mode(), os.FileMode(PrivateDirMode))return }returnnil}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.