src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/cli/lscolors/feature.go (about)

     1  package lscolors
     2  
     3  import (
     4  	"os"
     5  
     6  	"src.elv.sh/pkg/fsutil"
     7  )
     8  
     9  type feature int
    10  
    11  const (
    12  	featureInvalid feature = iota
    13  
    14  	featureOrphanedSymlink
    15  	featureSymlink
    16  
    17  	featureMultiHardLink
    18  
    19  	featureNamedPipe
    20  	featureSocket
    21  	featureDoor
    22  	featureBlockDevice
    23  	featureCharDevice
    24  
    25  	featureWorldWritableStickyDirectory
    26  	featureWorldWritableDirectory
    27  	featureStickyDirectory
    28  	featureDirectory
    29  
    30  	featureCapability
    31  
    32  	featureSetuid
    33  	featureSetgid
    34  	featureExecutable
    35  
    36  	featureRegular
    37  )
    38  
    39  // Some platforms, such as Windows, have simulated Unix style permission masks.
    40  // On Windows the only two permission masks are 0o666 (RW) and 0o444 (RO).
    41  const worldWritable = 0o002
    42  
    43  // Can be mutated in tests.
    44  var isDoorFunc = isDoor
    45  
    46  func determineFeature(fname string, mh bool) (feature, error) {
    47  	stat, err := os.Lstat(fname)
    48  
    49  	if err != nil {
    50  		return featureInvalid, err
    51  	}
    52  
    53  	m := stat.Mode()
    54  
    55  	// Symlink and OrphanedSymlink has highest precedence
    56  	if is(m, os.ModeSymlink) {
    57  		_, err := os.Stat(fname)
    58  		if err != nil {
    59  			return featureOrphanedSymlink, nil
    60  		}
    61  		return featureSymlink, nil
    62  	}
    63  
    64  	// featureMultiHardLink
    65  	if mh && isMultiHardlink(stat) {
    66  		return featureMultiHardLink, nil
    67  	}
    68  
    69  	// type bits features
    70  	switch {
    71  	case is(m, os.ModeNamedPipe):
    72  		return featureNamedPipe, nil
    73  	case is(m, os.ModeSocket): // Never on Windows
    74  		return featureSocket, nil
    75  	case isDoorFunc(stat):
    76  		return featureDoor, nil
    77  	case is(m, os.ModeCharDevice):
    78  		return featureCharDevice, nil
    79  	case is(m, os.ModeDevice):
    80  		// There is no dedicated os.Mode* flag for block device. On all
    81  		// supported Unix platforms, when os.ModeDevice is set but
    82  		// os.ModeCharDevice is not, the file is a block device (i.e.
    83  		// syscall.S_IFBLK is set). On Windows, this branch is unreachable.
    84  		//
    85  		// On Plan9, this in inaccurate.
    86  		return featureBlockDevice, nil
    87  	case is(m, os.ModeDir):
    88  		// Perm bits features for directory
    89  		perm := m.Perm()
    90  		switch {
    91  		case is(m, os.ModeSticky) && is(perm, worldWritable):
    92  			return featureWorldWritableStickyDirectory, nil
    93  		case is(perm, worldWritable):
    94  			return featureWorldWritableDirectory, nil
    95  		case is(m, os.ModeSticky):
    96  			return featureStickyDirectory, nil
    97  		default:
    98  			return featureDirectory, nil
    99  		}
   100  	}
   101  
   102  	// TODO(xiaq): Support featureCapacity
   103  
   104  	// Perm bits features for regular files
   105  	switch {
   106  	case is(m, os.ModeSetuid):
   107  		return featureSetuid, nil
   108  	case is(m, os.ModeSetgid):
   109  		return featureSetgid, nil
   110  	case fsutil.IsExecutable(stat):
   111  		return featureExecutable, nil
   112  	}
   113  
   114  	// Check extension
   115  	return featureRegular, nil
   116  }
   117  
   118  func is(m, p os.FileMode) bool {
   119  	return m&p == p
   120  }