1// Copyright 2015 Keybase, Inc. All rights reserved. Use of 2// this source code is governed by the included BSD license. 3 4package process 5 6import ( 7 "strings" 8 9 "github.com/keybase/go-ps" 10) 11 12// MatchFn is a process matching function 13type MatchFn func(ps.Process) bool 14 15// Matcher can match a process 16type Matcher struct { 17 match string 18 matchType MatchType 19 exceptPID int 20 log Log 21} 22 23// MatchType is how to match 24type MatchType string 25 26const ( 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 38func 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 43func (m *Matcher) ExceptPID(p int) { 44 m.exceptPID = p 45} 46 47func (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 60func (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 70func (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} 84