talos
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5package cli
6
7import (
8"context"
9"fmt"
10"os"
11"os/signal"
12"syscall"
13)
14
15// WithContext wraps function call to provide a context cancellable with ^C.
16func WithContext(ctx context.Context, f func(context.Context) error) error {
17wrappedCtx, wrappedCtxCancel := context.WithCancel(ctx)
18defer wrappedCtxCancel()
19
20// listen for ^C and SIGTERM and abort context
21sigCh := make(chan os.Signal, 1)
22signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
23
24exited := make(chan struct{})
25defer close(exited)
26
27go func() {
28select {
29case <-sigCh:
30wrappedCtxCancel()
31
32signal.Stop(sigCh)
33fmt.Fprintln(os.Stderr, "Signal received, aborting, press Ctrl+C once again to abort immediately...")
34case <-wrappedCtx.Done():
35return
36case <-exited:
37}
38}()
39
40return f(wrappedCtx)
41}
42