graceful

package module
v0.0.0-...-803ae39 Latest Latest
Warning

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

Go to latest
Published: Jul 27, 2017 License: MIT Imports: 6 Imported by: 0

README

graceful

GoDoc

Go library facilitating orderly shutdown of processes on Windows.

Documentation

Rendered for windows/amd64

Overview

Package graceful facilitates orderly shutdown of processes on Windows. It does this by injecting a thread into the target process that calls ExitProcess() from within the target process' address space.

This package is based on ideas put forth by Andrew Tucker in a Dr. Dobb's article published in 1999 titled "A Safer Alternative to TerminateProcess()": http://www.drdobbs.com/a-safer-alternative-to-terminateprocess/184416547

This package also draws inspiration from the git-for-windows implementation of the same idea: https://github.com/git-for-windows/msys2-runtime/pull/15/commits/e9cb332976cf6ba44d9f5fc0ed4f725ce43fe646

Example
package main

import (
	"context"
	"fmt"
	"os"
	"os/exec"
	"time"

	"github.com/gentlemanautomaton/graceful"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	cmd := exec.Command("ping", "127.0.0.1")
	if err := cmd.Start(); err != nil {
		fmt.Printf("unable to start ping: %v\n", err)
		os.Exit(2)
	}
	fmt.Println("ping started")
	if err := graceful.Exit(ctx, cmd.Process.Pid, 2); err != nil {
		fmt.Printf("exit failed: %v\n", err)
		graceful.Terminate(cmd.Process.Pid, 2) // Forcefully end the process (but know that this won't kill child processes)
		os.Exit(2)
	}
	cmd.Wait()
	fmt.Println("ping exited")
}
Output:

ping started
ping exited

Index

Examples

Constants

View Source
const (
	ProcessTerminate        = 0x0001 // PROCESS_TERMINATE
	ProcessCreateThread     = 0x0002 // PROCESS_CREATE_THREAD
	ProcessVMOperation      = 0x0008 // PROCESS_VM_OPERATION
	ProcessVMRead           = 0x0010 // PROCESS_VM_READ
	ProcessVMWrite          = 0x0020 // PROCESS_VM_WRITE
	ProcessQueryInformation = 0x0400 // PROCESS_QUERY_INFORMATION

	ProcessCreateRemoteThread = ProcessCreateThread | ProcessQueryInformation | ProcessVMOperation | ProcessVMWrite | ProcessVMRead | ProcessTerminate
)

These are win32 process security and access rights necessary to perform a call to CreateRemoteThread().

Reference: https://msdn.microsoft.com/library/ms682437

Variables

View Source
var (
	// ErrDifferentArch is returned when the target process has a different
	// architecture (x86 or x64) than the calling process. Both processes must
	// be of the same architecture for an exit to be performed.
	ErrDifferentArch = errors.New("target process architecture differs from the caller")
)

Functions

func Exit

func Exit(ctx context.Context, pid, code int) (err error)

Exit attempts to force an exit within a target process. The process is identified by its process id. If successful, the process will exit with the given exit code.

Exit is more rude than sending a real SIGINT signal. Exit is less rude than Terminate.

Exit works by effectively calling os.Exit(code) within the target process, with all the caveats that would entail. It calls the ExitProcess() function in the win32 API.

If the calling process architecture differs from that of the target process, ErrDifferentArch will be returned.

The returned error will be nil if the process exited. If it is non-nil, the process may still be running. If the context has been cancelled the context's error may be returned.

TODO: Check to make sure the process is actually running first.

func ExitOrTerminate

func ExitOrTerminate(ctx context.Context, pid, code int) (err error)

ExitOrTerminate attempts to use Exit to end a target process. If Exit fails or the context is cancelled, Terminate will be called.

FIXME: The termination portion of this function is not implemented yet.

func Terminate

func Terminate(pid int, code int) (err error)

Terminate forcefully ends the target process. The process is identified by its process id. The process will be given no opportunity to execute a system shutdown or run any cleanup functions. Child processes will be orphaned.

TODO: Check to make sure the process is actually running first.

TODO: Kill the entire process tree of the target process.

Types

This section is empty.

Jump to

Keyboard shortcuts

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