process

package module
v1.6.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2024 License: MIT Imports: 12 Imported by: 3

README

Process

This package provides a method to spawn child processes, like os/exec package, but with one huge difference: on Windows you have the capabilty of sending an Interrupt signal, that is you can simulate a CTRL+C event to the child process, which can then decide whether to handle it or not.

This is HUGE because Windows does not support sending signals, but with this package at least you can send an os.Interrupt at least.

The underlying structure used to spawn and manage the process is the exec.Cmd: for managing input, output and lifecycle of the process, its highly recommended to use the functions provided by the package.

The package also gives for Windows users some usefull functions to recreate the behaviour via the various functions from the kernel32.dll.

Behaviour

By default, each child process is spawned in a new console/tty. This is required for Windows to work so it's also the default behaviour in Linux for a consistent implementation.

When starting a process, these are the options you can provide ...

For the stdin argument:

  • if you provide nil, the process will listen on the standard input provided by the new environment, and no data can be sent through the pipe
  • if you provide process.DevNull(), the pipe will be created and usable, the child will not use the standard input of the new console and will only receive data through the pipe by the parent
  • for any other value, the pipe will be created and usable, and any data inside the io.Reader provided will be passed through the pipe. This means that if you pass os.Stdin, you can send data from the parent via the methods of the pipe and via your console natively

For the stdout and stderr arguments:

  • if you provide nil:
    • on Windows, the child will use the standard output / error of the new console, you can't capture any data
    • on Unix-like systems, the child will write to the /dev/null device and you can't capture any data
  • if you provide process.DevNull(), you will be able to access any data sent by the child, but only through the process methods (no real standard output / error)
  • for any other value, any data will be captured and written to the io.Writer provided. This means that if you pass os.Stdout/Stderr, you will also have the output sent to the parent console

OS Compatibility

The package is obviously compatible with all operating systems, but there are some differences:

Non Windows OSes (Linux, Mac OS, etc)

Considering its natively supported to send signals between processes, there is full support without any external program

Windows

By default, in windows, the process is spawned in a different console (so has different stdin, out and err from the parent) and is hidden, but this behaviour can be reverted with the method Process.ShowWindow() by calling it before the start

This process might still fail, the reasons are still not known. For example, if the child process you want to stop is created by the "go run" command, this will not work

Documentation

Overview

Package Process provides a method to spawn child processes, like os/exec package, but with one huge difference: on Windows you have the capabilty of sending an Interrupt signal, that is you can simulate a CTRL+C event to the child process, which can then decide whether to handle it or not.

The underlying structure used to spawn and manage the process is the exec.Cmd: for managing input, output and lifecycle of the process, its highly recommended to use the functions provided by the package

The package also gives for Windows users some usefull functions to recreate the behaviour via the various functions from the kernel32.dll

Behaviour

By default, each child process is spawned in a new console/tty. This is required for Windows to work so it's also the default behaviour in Linux for a consistent implementation.

When starting a process, these are the options you can provide ...

For the stdin argument:

  • if you provide nil, the process will listen on the standard input provided by the new environment, and no data can be sent through the pipe
  • if you provide process.DevNull(), the pipe will be created and usable, the child will not use the standard input of the new console and will only receive data through the pipe by the parent
  • for any other value, the pipe will be created and usable, and any data inside the io.Reader provided will be passed through the pipe. This means that if you pass os.Stdin, you can send data from the parent via the methods of the pipe and via your console natively

For the stdout and stderr argument:

  • if you provide nil:
  • on Windows, the child will use the standard output / error of the new console, you can't capture any data
  • on Unix-like systems, the child will write to the /dev/null device and you can't capture any data
  • if you provide process.DevNull(), you will be able to access any data sent by the child, but only through the process methods (no real standard output / error)
  • for any other value, any data will be captured and written to the io.Writer provided. This means that if you pass os.Stdout/Stderr, you will also have the output sent to the parent console

OS Compatibility

The package is obviously compatible with all operating systems, but there are some differences:

> Non Windows OSes (Linux, Mac OS, etc)

Considering its natively supported to send signals between processes, there is full support without any external program

> Windows

By default, in windows, the process is spawned in a different console (so has different stdin, out and err from the parent) and is hidden, but this behaviour can be reverted with the method Process.ShowWindow() by calling it before the start

This process might still fail, the reasons are still not known. For example, if the child process you want to stop is created by the "go run" command, this will not work

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DevNull

func DevNull() *os.File

DevNull returns the NULL file and can be used to suppress input and output on processes. It can be used as a regular os.File

func FastCommandParse

func FastCommandParse(args ...string) (wd string, execName string, argV []string)

FastCommandParse

func ListenForCTRLC

func ListenForCTRLC() chan os.Signal

func ParseCommandArgs

func ParseCommandArgs(args ...string) []string

ParseCommandArgs gets a list of strings and parses their content splitting them into separated strings. The characters used to parse the commands are, in the relevant order, <'>, <"> and < >

func StopProcess

func StopProcess(PID int) error

StopProcess sends an os.Interrupt to the process

Types

type ExitStatus

type ExitStatus struct {
	PID       int
	ExitCode  int
	ExitError error
}

ExitStatus holds the status information of a Process after it has exited

func (ExitStatus) Error added in v1.3.4

func (exitStatus ExitStatus) Error() error

func (ExitStatus) Unwrap added in v1.3.4

func (exitStatus ExitStatus) Unwrap() error

type Process

type Process struct {
	ExecName string

	Env         []string
	SysProcAttr syscall.SysProcAttr
	Exec        *exec.Cmd
	// contains filtered or unexported fields
}

Process wraps the default *exec.Cmd structure and makes easier to access and redirect the standard input, output and error. It also allows to gracefully stop a process both in Windows and UNIX-like OSes by generating a CTRL-C event without stopping the parent process.

For more details, see the package documentation

func NewProcess

func NewProcess(wd string, execPath string, args ...string) (*Process, error)

NewProcess creates a new Process with the given arguments.

The Process, once started, will run on the given working directory, but the executable path can be a relative path, calculated from the parent working directory, not the child one

func (*Process) Clone added in v1.6.3

func (p *Process) Clone() *Process

func (*Process) CloseInput

func (p *Process) CloseInput() error

Closes the input pipe, simulating a CTRL-Z or an EOF (if the stdin comes from a file)

func (*Process) ConnectStderr added in v1.6.2

func (p *Process) ConnectStderr(bufSize int) ([][]byte, <-chan []byte)

func (*Process) ConnectStdout added in v1.6.2

func (p *Process) ConnectStdout(bufSize int) ([][]byte, <-chan []byte)

func (*Process) IsRunning

func (p *Process) IsRunning() bool

IsRunning reports whether the Process is running

func (*Process) Kill

func (p *Process) Kill() error

Kill forcibly kills the Process

func (*Process) Run added in v1.5.0

func (p *Process) Run(stdin io.Reader, stdout, stderr io.Writer) (exitStatus ExitStatus, err error)

func (*Process) SendInput

func (p *Process) SendInput(data []byte) error

SendInput sends data to the Process via a pipe, if the Process is running and can pipe data. The Process might take any input until a newline or an EOF: for the first one you can use the SendText method, for the second case, you can close the pipe via the CloseInput method

For more details, see the package documentation

func (*Process) SendText

func (p *Process) SendText(text string) error

Sends a text with a newline appended automatically, to simulate a real user behind a keyboard

func (*Process) Start

func (p *Process) Start(stdin io.Reader, stdout, stderr io.Writer) error

Start starts the Process. It returns an error if there is a problem with the creation of the new Process, but if something happens during the execution it will be reported in the ExitStatus provided by calling the Wait method

func (*Process) Stderr

func (p *Process) Stderr() []byte

Stderr returns all the standard error captured at the moment until the Process is started again

func (*Process) StderrLines added in v1.6.2

func (p *Process) StderrLines() [][]byte

Stderr returns all the standard error captured at the moment until the Process is started again

func (*Process) StderrListener added in v1.6.2

func (p *Process) StderrListener(bufSize int) <-chan []byte

func (*Process) Stdout

func (p *Process) Stdout() []byte

Stdout returns all the standard output captured at the moment until the Process is started again

func (*Process) StdoutLines added in v1.6.2

func (p *Process) StdoutLines() [][]byte

Stdout returns all the standard output captured at the moment until the Process is started again

func (*Process) StdoutListener added in v1.6.2

func (p *Process) StdoutListener(bufSize int) <-chan []byte

func (*Process) Stop

func (p *Process) Stop() error

Stop sends a CTRL-C event to the Process to allow a graceful exit

func (*Process) String

func (p *Process) String() string

func (*Process) Wait

func (p *Process) Wait() ExitStatus

Wait waits for the Process termination (if running) and returns the last Process state known

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL