Documentation ¶
Index ¶
- Variables
- func GetChildPIDs(pid int) ([]int, error)
- func KillProcessTree(pid int) error
- func TryPid2Pgid(cmd *exec.Cmd) bool
- type ProcCallback
- type ProcChildCntChangeCallback
- type ProcData
- type ProcHndlCallback
- type ProcInfoCallback
- type Process
- func (p *Process) AddStartCommands(args ...string)
- func (p *Process) BlockWait(tickTime time.Duration) error
- func (p *Process) Command(cmd string) error
- func (p *Process) Exec() (int, int, error)
- func (p *Process) GetLogger() mimiclog.Logger
- func (p *Process) GetProcessWatcher() (*ProcessWatch, error)
- func (p *Process) IsStarted() bool
- func (p *Process) Kill() (int, int, error)
- func (p *Process) SetCombinePipes(combine bool)
- func (p *Process) SetKeepRunning(stayOpen bool)
- func (p *Process) SetLogger(logger mimiclog.Logger)
- func (p *Process) SetOnChildCountChange(callback ProcChildCntChangeCallback)
- func (p *Process) SetOnInit(callback ProcInfoCallback)
- func (p *Process) SetOnOutput(callback ProcCallback)
- func (p *Process) SetOnWaitDone(callback ProcHndlCallback)
- func (p *Process) SetReportChildCount(report bool)
- func (p *Process) SetTimeout(timeout time.Duration)
- func (p *Process) Stop() (int, int, error)
- func (p *Process) WaitUntilRunning(tickTime time.Duration) (time.Duration, error)
- type ProcessWatch
- func (proc *ProcessWatch) CountChildsAll() int
- func (proc *ProcessWatch) GetChilds() []int
- func (proc *ProcessWatch) GetCmd() string
- func (proc *ProcessWatch) GetPid() int
- func (proc *ProcessWatch) GetProcessInfo() *os.Process
- func (proc *ProcessWatch) GetThreadCount() int
- func (proc *ProcessWatch) GetThreads() []int
- func (proc *ProcessWatch) IsRunning() (bool, error)
- func (proc *ProcessWatch) Kill() error
- func (proc *ProcessWatch) SetLogger(logger mimiclog.Logger)
- func (proc *ProcessWatch) StopChilds(signals ...Signal) error
- func (proc *ProcessWatch) StopWithDefaultSigOrder() error
- func (proc *ProcessWatch) Update() error
- func (proc *ProcessWatch) WaitForStart(timeout, waitTick time.Duration) error
- func (proc *ProcessWatch) WaitForStop(timeout, waitTick time.Duration) (time.Duration, error)
- func (proc *ProcessWatch) WalkChildProcs(f func(p *ProcData, parentPid int, level int) bool)
- type Signal
Constants ¶
This section is empty.
Variables ¶
var ( ExitInBackGround = 601 // the exit code when the process is running in the background ExitTimeout = 602 // the exit code when the process is stopped by timeout RealCodeNotPresent = -1 // the real exit code is not present because the process was killed or never started or timed out )
var ( DefaultKillSignal = Signal{Signal: os.Kill, ThenWait: 20 * time.Millisecond} DefaultInterruptSignal = Signal{Signal: os.Interrupt, ThenWait: 800 * time.Millisecond} )
Functions ¶
func GetChildPIDs ¶
func KillProcessTree ¶
KillProcessTree kills the process by using the process group id
func TryPid2Pgid ¶
on linux we need to set the process group id to kill the whole process tree now any kill command have to add -pgid to kill the whole process tree like: syscall.Kill(-ts.process.processInfo.Pid, syscall.SIGKILL) returnning true to indicate that the process group id is set
Types ¶
type ProcCallback ¶
type ProcChildCntChangeCallback ¶
type ProcChildCntChangeCallback func(int) // a callback for the process handler
type ProcData ¶
type ProcData struct { Pid int // process id Cmd string // command line ThreadCount int // number of threads Threads []int // list of threads pids Childs []int // list of child pids ChildProcs []*ProcData // list of child processes }
basic struct to hold the data of a process
func NewProc ¶
ReadProc reads the process data of a process with the given pid and returns a ProcData struct
func (*ProcData) CountChilds ¶
func (*ProcData) Stop ¶
Stop sends the given signals to the child processes and then to the process itself. any of these child processes can have child processes they will be stopped too the signal order is important. you can use one of the default Signnals, the containing the regular signal and the ThenWait time, that is used to give the process time to stop. or you can send your own signals. like so:
proc.Stop(process.Signal{Signal: syscall.SIGINT, ThenWait: 1 * time.Second}, process.Signal{Signal: syscall.SIGKILL, ThenWait: 10 * time.Millisecond})
if the process is not running anymore, we will return nil this is also used by the ProcessWatch.Stop() function
func (*ProcData) StopChilds ¶
ProcData.Stop sends the given signals to the child processes any of these child processes can have child processes they will be stopped too
func (*ProcData) WalkChildProcs ¶
func (pd *ProcData) WalkChildProcs(startLevel int, f func(p *ProcData, parentPid int, level int) bool)
WalkChildProcs walks through the child processes of the process. this is a recursive function and calls the given function for each child process. the function gets the child process data, the parent pid and the level as parameter the level is the level of the child process in the process tree. this is mostly used internally by calling WalkChildProcs from ProcessWatch. but can also be used to get any childs starting from a different level, if needed.
type ProcHndlCallback ¶
type ProcHndlCallback func(error) // a callback for the process handler
type ProcInfoCallback ¶
type Process ¶
type Process struct {
// contains filtered or unexported fields
}
func NewProcess ¶
NewProcess creates a new process with the given command and arguments
func NewTerminal ¶
Create a new process by using the default terminal as defined in the terminal package if no arguments are given, is seems to be intended to be used for interactive processes
func (*Process) AddStartCommands ¶
AddStartCommands sets the arguments to pass to the command without waiting for any other setup. other than Command(string) you do not need to setup the whole environment and control structures.
func (*Process) BlockWait ¶
BlockWait blocks the current thread until the process is stopped. it uses a tick time to check if the process is stopped in intervals. this if meant to be used by tests. not in production code except you know what you are doing. most of the time you want to use the OnOutput callback to handle the output of the process and stop the process by using the Stop() method. or use go routines to handle the process output and stop the process if needed. using this method is a sign you do not need a background process.
func (*Process) Command ¶
Command sends a command to the process. this command is send to the process by using the inPipe. the command will be send to the process as a string with a newline at the end. to get the response of the process, you need to set the onOutput callback. this is only possible if the process is set to stay open. if the process is not set to stay open, this will return an error. if the process is not started, this will return an error. if the process is stopped, this will return an error. if the inPipe is nil, this will return an error. if the command could not be send to the process, this will return an error.
func (*Process) Exec ¶
Exec starts the process onece or in background depending on the stayOpen flag. if its started in background, it will return directly after the process is started. so the return codes are not the real exit codes of the process. instead they are an internalcode that indicates the process is running in background.
- the internal exit code of the process
- the real exit code of the process (if we have one. if not then -1 on error or 0 for some expected states like killed)
- an error if one occured
func (*Process) GetProcessWatcher ¶
func (p *Process) GetProcessWatcher() (*ProcessWatch, error)
GetProcessWatcher returns the process watcher for the process.
func (*Process) Kill ¶
Kill kills the process and all its childs it uses the DefaultKillSignal to kill the processes. So this is the Hard way to kill a process. if you want to stop a process in a more graceful way use the Stop() method instead. it returns
- the internal exit code of the process
- the real exit code of the process (if we have one. if not then -1 on error or 0 for some expected states like killed)
- an error if one occured
func (*Process) SetCombinePipes ¶
SetCombinePipes sets whether or not to combine the output and error pipes this will change the behavior of the process because error messages will be handled as output. only errors that are returned by the process itself will be handled as errors and pushed to the onOutput callback. this can be usefull for command they runs once so you do not have to handle the error pipe, because you should get the error then anyway. for processes that stay open, you should not use this because you will not get the errors while runtime.
func (*Process) SetKeepRunning ¶
SetKeepRunning sets whether or not the process should stay open. If it does, it will not be stopped after the process handles the startup commands. this will change the behavior of the process because the started process will wait for inputs or beeing stopped by the Stop() method.
func (*Process) SetLogger ¶
SetLogger sets the logger for the process Fullfilling the mimiclog.Logger interface
func (*Process) SetOnChildCountChange ¶
func (p *Process) SetOnChildCountChange(callback ProcChildCntChangeCallback)
SetOnChildCountChange sets the callback to call when the child count of the process changes. this is only usefull for processes that stay open.
func (*Process) SetOnInit ¶
func (p *Process) SetOnInit(callback ProcInfoCallback)
SetOnInit sets the callback to call when the process is started. you will get the process object as argument. you can use this to get the process id and do something with it. but be carefull to not kill the process by accident. this package should handle the process for you. so you should not need to handle it by yourself.
func (*Process) SetOnOutput ¶
func (p *Process) SetOnOutput(callback ProcCallback)
SetOnOutput sets the callback to call when output is received. Depending on the combinePipes flag, the error messages will be handled as output. the callback: func(string, error) bool
- the string is the output of the process
- the error is the error of the process
- the bool is the return value of the callback. if false is returned, the process will be stopped. if true is returned, the process will continue to run.
while runtime and an not combined pipe, anything that will be written to the error pipe will be handled as error. but also as message. so there is no need to handle booth messages in case of error.
process.SetOunOutput(func(msg string, err error) bool { if err != nil { // error.Error() is the same as msg. so no need to handle it twice return false // stop the process in this example. you can also return true to keep the process running } // do something with the message return true })
func (*Process) SetOnWaitDone ¶
func (p *Process) SetOnWaitDone(callback ProcHndlCallback)
SetOnWaitDone sets the callback to call when the process is stopped after a regular wait for cmd execution. this is not called if the process is stopped by any other reason like timeout or killing the process.
func (*Process) SetReportChildCount ¶
enable reporting the child count if changed. this is mostly usefull for processes that stay open. and is ment togehther with the SetOnChildCountChange callback. but you can also use it without the callback just to get the child count by the logger output (debug level needed)
func (*Process) SetTimeout ¶
SetTimeout sets the timeout for the process. If the process is not stopped after the timeout, it will be stopped
func (*Process) Stop ¶
Stop stops the process. for this the default stop procedure is used. that means first the process willget an interrupt signal. then we wait for a short time. if the process is still running, we will kill it. this is the soft way to stop a process. if you want to kill a process in a more hard way, use the Kill() method instead. it returns
- the internal exit code of the process
- the real exit code of the process (if we have one. if not then -1 on error or 0 for some expected states like killed)
- an error if one occured
func (*Process) WaitUntilRunning ¶
WaitUntilRunning blocks the current thread until the process is running. it uses a tick time to check if the process is running in intervals. this can be usefull to make sure the process is running before you send commands to it.
type ProcessWatch ¶
type ProcessWatch struct {
// contains filtered or unexported fields
}
func NewProcessWatcherByCmd ¶
func NewProcessWatcherByCmd(cmd *exec.Cmd) (*ProcessWatch, error)
NewProcessWatcherByCmd creates a new ProcessDef struct and returns a pointer to it the ProcessDef struct holds the process data of the given process
func NewProcessWatcherByPid ¶
func NewProcessWatcherByPid(pid int) (*ProcessWatch, error)
NewProcessWatcherByPid creates a new ProcessDef struct and returns a pointer to it same as NewProcessWatcherByCmd but with a pid as parameter
func NewProcessWatcherByProcessInfo ¶
func NewProcessWatcherByProcessInfo(proc *os.Process) (*ProcessWatch, error)
NewProcessWatcherByProcessInfo creates a new ProcessDef struct and returns a pointer to it same as NewProcessWatcherByCmd but with a os.Process struct as parameter
func (*ProcessWatch) CountChildsAll ¶
func (proc *ProcessWatch) CountChildsAll() int
func (*ProcessWatch) GetChilds ¶
func (proc *ProcessWatch) GetChilds() []int
GetChilds returns the list of PID's of child processes of the process
func (*ProcessWatch) GetCmd ¶
func (proc *ProcessWatch) GetCmd() string
GetCmd returns the command line of the process
func (*ProcessWatch) GetPid ¶
func (proc *ProcessWatch) GetPid() int
GetPid returns the pid of the process
func (*ProcessWatch) GetProcessInfo ¶
func (proc *ProcessWatch) GetProcessInfo() *os.Process
GetProcessInfo returns the os.Process struct of the process
func (*ProcessWatch) GetThreadCount ¶
func (proc *ProcessWatch) GetThreadCount() int
GetThreadCount returns the number of threads of the process these are NOT the child processes. these are the threads of the process itself
func (*ProcessWatch) GetThreads ¶
func (proc *ProcessWatch) GetThreads() []int
GetThreads returns the list of PID's of threads of the process
func (*ProcessWatch) IsRunning ¶
func (proc *ProcessWatch) IsRunning() (bool, error)
IsRunning checks if the process is still running. this is done by requesting the process data again. if an error occurs then the process is not running anymore because the process data can not be read. that means that we will return false if an error occurs so this is you should check instead the error itself. the error is useful if you want to know why the process data can not be read. but again: for a process that is stopped, you will get always an error.
func (*ProcessWatch) Kill ¶
func (proc *ProcessWatch) Kill() error
Kill sends the kill signal to the process it uses the KillProcessTree function to kill the process tree. this way we can include some os specific code to kill the process tree.
func (*ProcessWatch) SetLogger ¶
func (proc *ProcessWatch) SetLogger(logger mimiclog.Logger)
SetLogger sets the logger for the process if no logger is set, a null logger will be used
func (*ProcessWatch) StopChilds ¶
func (proc *ProcessWatch) StopChilds(signals ...Signal) error
ProcessWatch.StopChilds sends the given signals to the child processes any of these child processes can have child processes. they will be stopped too. the signal order is important. you can use one of the default Signnals, the containing the regular signal and the ThenWait time, that is used to give the process time to stop. or you can send your own signals. like so:
proc.StopChilds(process.Signal{Signal: syscall.SIGINT, ThenWait: 1 * time.Second}, process.Signal{Signal: syscall.SIGKILL, ThenWait: 10 * time.Millisecond})
func (*ProcessWatch) StopWithDefaultSigOrder ¶
func (proc *ProcessWatch) StopWithDefaultSigOrder() error
StopWithDefaultSigOrder sends the default signals to the child processes DefaultInterruptSignal and DefaultKillSignal this is the same as calling StopChilds(DefaultInterruptSignal, DefaultKillSignal) instead of just stopping the current process, we also taking care about the child processes. this way we can make sure that the process tree is stopped, and we do not have any zombie processes.
func (*ProcessWatch) Update ¶
func (proc *ProcessWatch) Update() error
Update updates the process data of the process. this is done by requesting the process data again. if an error occurs then the process is not running anymore. at least this is the usual case. because the process data can not be read.
func (*ProcessWatch) WaitForStart ¶
func (proc *ProcessWatch) WaitForStart(timeout, waitTick time.Duration) error
WaitForStart waits until the process is started. or until the timeout is reached. this is ment for use in cases, we just want to wait until the process is started, before we start working with them. here we do not check any internal flags or something like that. we just check if the process is running in the system. so this would also return true if the process is running, but not able to handle some inputs. this is depending on the process itself. for checking if the process handle inputs, you need to check the output of the process. (if the application outputs some text on start)
func (*ProcessWatch) WaitForStop ¶
WaitForStop waits until the process is stopped. or until the timeout is reached. this is different to the usual Timeout function, because this will not count for the Timeout. this function is ment for use in cases, we just want to wait until the process is stopped, without forcing them being killed. if the (local) timeout is reached, we will return an error, but the process will still be running. this can be combined with the Timeout function, to force the process to stop after the timeout is reached. but then make sure to set the timeout to a higher value than the WaitForStop timeout.
func (*ProcessWatch) WalkChildProcs ¶
func (proc *ProcessWatch) WalkChildProcs(f func(p *ProcData, parentPid int, level int) bool)
WalkChildProcs walks through the child processes of the process and calls the given function for each child process the function gets the child process data, the parent pid and the level as parameter the level is the level of the child process in the process tree the function returns a bool. if the bool is true, the child processes of the child process will be walked too