github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/utils/utils.go (about)

     1  package utils
     2  
     3  import (
     4  	"crypto/rand"
     5  	"encoding/hex"
     6  	"encoding/json"
     7  	"io"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  	"syscall"
    12  	"unsafe"
    13  )
    14  
    15  const (
    16  	exitSignalOffset = 128
    17  )
    18  
    19  // GenerateRandomName returns a new name joined with a prefix.  This size
    20  // specified is used to truncate the randomly generated value
    21  func GenerateRandomName(prefix string, size int) (string, error) {
    22  	id := make([]byte, 32)
    23  	if _, err := io.ReadFull(rand.Reader, id); err != nil {
    24  		return "", err
    25  	}
    26  	if size > 64 {
    27  		size = 64
    28  	}
    29  	return prefix + hex.EncodeToString(id)[:size], nil
    30  }
    31  
    32  // ResolveRootfs ensures that the current working directory is
    33  // not a symlink and returns the absolute path to the rootfs
    34  func ResolveRootfs(uncleanRootfs string) (string, error) {
    35  	rootfs, err := filepath.Abs(uncleanRootfs)
    36  	if err != nil {
    37  		return "", err
    38  	}
    39  	return filepath.EvalSymlinks(rootfs)
    40  }
    41  
    42  // ExitStatus returns the correct exit status for a process based on if it
    43  // was signaled or exited cleanly
    44  func ExitStatus(status syscall.WaitStatus) int {
    45  	if status.Signaled() {
    46  		return exitSignalOffset + int(status.Signal())
    47  	}
    48  	return status.ExitStatus()
    49  }
    50  
    51  // WriteJSON writes the provided struct v to w using standard json marshaling
    52  func WriteJSON(w io.Writer, v interface{}) error {
    53  	data, err := json.Marshal(v)
    54  	if err != nil {
    55  		return err
    56  	}
    57  	_, err = w.Write(data)
    58  	return err
    59  }
    60  
    61  // CleanPath makes a path safe for use with filepath.Join. This is done by not
    62  // only cleaning the path, but also (if the path is relative) adding a leading
    63  // '/' and cleaning it (then removing the leading '/'). This ensures that a
    64  // path resulting from prepending another path will always resolve to lexically
    65  // be a subdirectory of the prefixed path. This is all done lexically, so paths
    66  // that include symlinks won't be safe as a result of using CleanPath.
    67  func CleanPath(path string) string {
    68  	// Deal with empty strings nicely.
    69  	if path == "" {
    70  		return ""
    71  	}
    72  
    73  	// Ensure that all paths are cleaned (especially problematic ones like
    74  	// "/../../../../../" which can cause lots of issues).
    75  	path = filepath.Clean(path)
    76  
    77  	// If the path isn't absolute, we need to do more processing to fix paths
    78  	// such as "../../../../<etc>/some/path". We also shouldn't convert absolute
    79  	// paths to relative ones.
    80  	if !filepath.IsAbs(path) {
    81  		path = filepath.Clean(string(os.PathSeparator) + path)
    82  		// This can't fail, as (by definition) all paths are relative to root.
    83  		path, _ = filepath.Rel(string(os.PathSeparator), path)
    84  	}
    85  
    86  	// Clean the path again for good measure.
    87  	return filepath.Clean(path)
    88  }
    89  
    90  // SearchLabels searches a list of key-value pairs for the provided key and
    91  // returns the corresponding value. The pairs must be separated with '='.
    92  func SearchLabels(labels []string, query string) string {
    93  	for _, l := range labels {
    94  		parts := strings.SplitN(l, "=", 2)
    95  		if len(parts) < 2 {
    96  			continue
    97  		}
    98  		if parts[0] == query {
    99  			return parts[1]
   100  		}
   101  	}
   102  	return ""
   103  }
   104  
   105  // Annotations returns the bundle path and user defined annotations from the
   106  // libcontainer state.  We need to remove the bundle because that is a label
   107  // added by libcontainer.
   108  func Annotations(labels []string) (bundle string, userAnnotations map[string]string) {
   109  	userAnnotations = make(map[string]string)
   110  	for _, l := range labels {
   111  		parts := strings.SplitN(l, "=", 2)
   112  		if len(parts) < 2 {
   113  			continue
   114  		}
   115  		if parts[0] == "bundle" {
   116  			bundle = parts[1]
   117  		} else {
   118  			userAnnotations[parts[0]] = parts[1]
   119  		}
   120  	}
   121  	return
   122  }
   123  
   124  func GetIntSize() int {
   125  	return int(unsafe.Sizeof(1))
   126  }