github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/updater/process/matcher.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package process
     5  
     6  import (
     7  	"strings"
     8  
     9  	"github.com/keybase/go-ps"
    10  )
    11  
    12  // MatchFn is a process matching function
    13  type MatchFn func(ps.Process) bool
    14  
    15  // Matcher can match a process
    16  type Matcher struct {
    17  	match     string
    18  	matchType MatchType
    19  	exceptPID int
    20  	log       Log
    21  }
    22  
    23  // MatchType is how to match
    24  type MatchType string
    25  
    26  const (
    27  	// PathEqual matches path equals string
    28  	PathEqual MatchType = "path-equal"
    29  	// PathContains matches path contains string
    30  	PathContains MatchType = "path-contains"
    31  	// PathPrefix matches path has string prefix
    32  	PathPrefix MatchType = "path-prefix"
    33  	// ExecutableEqual matches executable name equals string
    34  	ExecutableEqual MatchType = "executable-equal"
    35  )
    36  
    37  // NewMatcher returns a new matcher
    38  func NewMatcher(match string, matchType MatchType, log Log) Matcher {
    39  	return Matcher{match: match, matchType: matchType, log: log}
    40  }
    41  
    42  // ExceptPID will not match specified pid
    43  func (m *Matcher) ExceptPID(p int) {
    44  	m.exceptPID = p
    45  }
    46  
    47  func (m Matcher) matchPathFn(pathFn func(path, str string) bool) MatchFn {
    48  	return func(p ps.Process) bool {
    49  		if m.exceptPID != 0 && p.Pid() == m.exceptPID {
    50  			return false
    51  		}
    52  		path, err := p.Path()
    53  		if err != nil {
    54  			return false
    55  		}
    56  		return pathFn(path, m.match)
    57  	}
    58  }
    59  
    60  func (m Matcher) matchExecutableFn(execFn func(executable, str string) bool) MatchFn {
    61  	return func(p ps.Process) bool {
    62  		if m.exceptPID != 0 && p.Pid() == m.exceptPID {
    63  			return false
    64  		}
    65  		return execFn(p.Executable(), m.match)
    66  	}
    67  }
    68  
    69  // Fn is the matching function
    70  func (m Matcher) Fn() MatchFn {
    71  	switch m.matchType {
    72  	case PathEqual:
    73  		return m.matchPathFn(func(s, t string) bool { return s == t })
    74  	case PathContains:
    75  		return m.matchPathFn(strings.Contains)
    76  	case PathPrefix:
    77  		return m.matchPathFn(strings.HasPrefix)
    78  	case ExecutableEqual:
    79  		return m.matchExecutableFn(func(s, t string) bool { return s == t })
    80  	default:
    81  		return nil
    82  	}
    83  }