github.com/opencontainers/umoci@v0.4.8-0.20240508124516-656e4836fb0d/pkg/fseval/fseval_default.go (about)

     1  /*
     2   * umoci: Umoci Modifies Open Containers' Images
     3   * Copyright (C) 2016-2020 SUSE LLC
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *    http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  
    18  package fseval
    19  
    20  import (
    21  	"os"
    22  	"path/filepath"
    23  	"time"
    24  
    25  	"github.com/opencontainers/umoci/pkg/system"
    26  	"github.com/vbatts/go-mtree"
    27  	"golang.org/x/sys/unix"
    28  )
    29  
    30  // Default is the "identity" form of FsEval. In particular, it does not do any
    31  // trickery and calls directly to the relevant os.* functions (and does not
    32  // wrap KeywordFunc). This should be used by default, because there are no
    33  // weird side-effects.
    34  var Default FsEval = osFsEval(0)
    35  
    36  // osFsEval is a hack to be able to make DefaultFsEval a const.
    37  type osFsEval int
    38  
    39  // Open is equivalent to os.Open.
    40  func (fs osFsEval) Open(path string) (*os.File, error) {
    41  	return os.Open(path)
    42  }
    43  
    44  // Create is equivalent to os.Create.
    45  func (fs osFsEval) Create(path string) (*os.File, error) {
    46  	return os.Create(path)
    47  }
    48  
    49  // Readdir is equivalent to os.Readdir.
    50  func (fs osFsEval) Readdir(path string) ([]os.FileInfo, error) {
    51  	fh, err := os.Open(path)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	defer fh.Close()
    56  	return fh.Readdir(-1)
    57  }
    58  
    59  // Lstat is equivalent to os.Lstat.
    60  func (fs osFsEval) Lstat(path string) (os.FileInfo, error) {
    61  	return os.Lstat(path)
    62  }
    63  
    64  // Lstatx is equivalent to unix.Lstat.
    65  func (fs osFsEval) Lstatx(path string) (unix.Stat_t, error) {
    66  	var s unix.Stat_t
    67  	err := unix.Lstat(path, &s)
    68  	return s, err
    69  }
    70  
    71  // Readlink is equivalent to os.Readlink.
    72  func (fs osFsEval) Readlink(path string) (string, error) {
    73  	return os.Readlink(path)
    74  }
    75  
    76  // Symlink is equivalent to os.Symlink.
    77  func (fs osFsEval) Symlink(target, linkname string) error {
    78  	return os.Symlink(target, linkname)
    79  }
    80  
    81  // Link is equivalent to unix.Link(..., ~AT_SYMLINK_FOLLOW).
    82  func (fs osFsEval) Link(target, linkname string) error {
    83  	// We need to explicitly pass 0 as a flag because POSIX allows the default
    84  	// behaviour of link(2) when it comes to target being a symlink to be
    85  	// implementation-defined. Only linkat(2) allows us to guarantee the right
    86  	// behaviour.
    87  	//  <https://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html>
    88  	return unix.Linkat(unix.AT_FDCWD, target, unix.AT_FDCWD, linkname, 0)
    89  }
    90  
    91  // Chmod is equivalent to os.Chmod.
    92  func (fs osFsEval) Chmod(path string, mode os.FileMode) error {
    93  	return os.Chmod(path, mode)
    94  }
    95  
    96  // Lutimes is equivalent to os.Lutimes.
    97  func (fs osFsEval) Lutimes(path string, atime, mtime time.Time) error {
    98  	return system.Lutimes(path, atime, mtime)
    99  }
   100  
   101  // RemoveAll is equivalent to os.RemoveAll.
   102  func (fs osFsEval) RemoveAll(path string) error {
   103  	return os.RemoveAll(path)
   104  }
   105  
   106  // Mknod is equivalent to unix.Mknod.
   107  func (fs osFsEval) Mknod(path string, mode os.FileMode, dev uint64) error {
   108  	return system.Mknod(path, uint32(mode), dev)
   109  }
   110  
   111  // MkdirAll is equivalent to os.MkdirAll.
   112  func (fs osFsEval) MkdirAll(path string, perm os.FileMode) error {
   113  	return os.MkdirAll(path, perm)
   114  }
   115  
   116  // Llistxattr is equivalent to system.Llistxattr
   117  func (fs osFsEval) Llistxattr(path string) ([]string, error) {
   118  	return system.Llistxattr(path)
   119  }
   120  
   121  // Lremovexattr is equivalent to system.Lremovexattr
   122  func (fs osFsEval) Lremovexattr(path, name string) error {
   123  	return unix.Lremovexattr(path, name)
   124  }
   125  
   126  // Lsetxattr is equivalent to system.Lsetxattr
   127  func (fs osFsEval) Lsetxattr(path, name string, value []byte, flags int) error {
   128  	return unix.Lsetxattr(path, name, value, flags)
   129  }
   130  
   131  // Lgetxattr is equivalent to system.Lgetxattr
   132  func (fs osFsEval) Lgetxattr(path string, name string) ([]byte, error) {
   133  	return system.Lgetxattr(path, name)
   134  }
   135  
   136  // Lclearxattrs is equivalent to system.Lclearxattrs
   137  func (fs osFsEval) Lclearxattrs(path string, except map[string]struct{}) error {
   138  	return system.Lclearxattrs(path, except)
   139  }
   140  
   141  // KeywordFunc returns a wrapper around the given mtree.KeywordFunc.
   142  func (fs osFsEval) KeywordFunc(fn mtree.KeywordFunc) mtree.KeywordFunc {
   143  	return fn
   144  }
   145  
   146  // Walk is equivalent to filepath.Walk.
   147  func (fs osFsEval) Walk(root string, fn filepath.WalkFunc) error {
   148  	return filepath.Walk(root, fn)
   149  }