github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/util/sysutil/sysutil_unix.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  // +build !windows
    12  
    13  //lint:file-ignore Unconvert (redundant conversions are necessary for cross-platform compatibility)
    14  
    15  package sysutil
    16  
    17  import (
    18  	"fmt"
    19  	"math"
    20  	"os"
    21  	"syscall"
    22  
    23  	"golang.org/x/sys/unix"
    24  )
    25  
    26  // ProcessIdentity returns a string describing the user and group that this
    27  // process is running as.
    28  func ProcessIdentity() string {
    29  	return fmt.Sprintf("uid %d euid %d gid %d egid %d",
    30  		unix.Getuid(), unix.Geteuid(), unix.Getgid(), unix.Getegid())
    31  }
    32  
    33  // StatFS returns an FSInfo describing the named filesystem. It is only
    34  // supported on Unix-like platforms.
    35  func StatFS(path string) (*FSInfo, error) {
    36  	var fs unix.Statfs_t
    37  	if err := unix.Statfs(path, &fs); err != nil {
    38  		return nil, err
    39  	}
    40  	// Statfs_t's fields have different types on different platforms. Our FSInfo
    41  	// type uses int64s for all fields, so make sure the values returned by the OS
    42  	// will fit.
    43  	if uint64(fs.Bfree) > math.MaxInt64 ||
    44  		uint64(fs.Bavail) > math.MaxInt64 ||
    45  		uint64(fs.Blocks) > math.MaxInt64 ||
    46  		uint64(fs.Bsize) > math.MaxInt64 {
    47  		return nil, fmt.Errorf("statfs syscall returned unrepresentable value %#v", fs)
    48  	}
    49  	return &FSInfo{
    50  		FreeBlocks:  int64(fs.Bfree),
    51  		AvailBlocks: int64(fs.Bavail),
    52  		TotalBlocks: int64(fs.Blocks),
    53  		BlockSize:   int64(fs.Bsize),
    54  	}, nil
    55  }
    56  
    57  // StatAndLinkCount wraps os.Stat, returning its result and, if the platform
    58  // supports it, the link-count from the returned file info.
    59  func StatAndLinkCount(path string) (os.FileInfo, int64, error) {
    60  	stat, err := os.Stat(path)
    61  	if err != nil {
    62  		return stat, 0, err
    63  	}
    64  	if sys := stat.Sys(); sys != nil {
    65  		if s, ok := sys.(*syscall.Stat_t); ok {
    66  			return stat, int64(s.Nlink), nil
    67  		}
    68  	}
    69  	return stat, 0, nil
    70  }
    71  
    72  // IsCrossDeviceLinkErrno checks whether the given error object (as
    73  // extracted from an *os.LinkError) is a cross-device link/rename
    74  // error.
    75  func IsCrossDeviceLinkErrno(errno error) bool {
    76  	return errno == syscall.EXDEV
    77  }