(ctx context.Context, prompt string, askForConfirmationPreFn askForConfirmationPreFunc)
| 73 | } |
| 74 | |
| 75 | func askForConfirmationAsync(ctx context.Context, |
| 76 | prompt string, |
| 77 | askForConfirmationPreFn askForConfirmationPreFunc) (<-chan bool, <-chan error) { |
| 78 | |
| 79 | retValCh := make(chan bool, 1) |
| 80 | errCh := make(chan error, 1) |
| 81 | |
| 82 | done := ctx.Done() |
| 83 | eventFD := -1 |
| 84 | if done != nil { |
| 85 | fd, err := unix.Eventfd(0, unix.EFD_CLOEXEC|unix.EFD_NONBLOCK) |
| 86 | if err != nil { |
| 87 | errCh <- fmt.Errorf("eventfd(2) failed: %w", err) |
| 88 | return retValCh, errCh |
| 89 | } |
| 90 | |
| 91 | eventFD = fd |
| 92 | } |
| 93 | |
| 94 | go func() { |
| 95 | for { |
| 96 | fmt.Printf("%s ", prompt) |
| 97 | if askForConfirmationPreFn != nil { |
| 98 | if err := askForConfirmationPreFn(); err != nil { |
| 99 | if errors.Is(err, errContinue) { |
| 100 | continue |
| 101 | } |
| 102 | |
| 103 | errCh <- err |
| 104 | break |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | var response string |
| 109 | |
| 110 | pollFn := func(errPoll error, pollFDs []unix.PollFd) error { |
| 111 | if len(pollFDs) != 1 { |
| 112 | panic("unexpected number of file descriptors") |
| 113 | } |
| 114 | |
| 115 | if errPoll != nil { |
| 116 | return errPoll |
| 117 | } |
| 118 | |
| 119 | if pollFDs[0].Revents&unix.POLLIN != 0 { |
| 120 | logrus.Debug("Returned from /dev/stdin: POLLIN") |
| 121 | |
| 122 | scanner := bufio.NewScanner(os.Stdin) |
| 123 | if !scanner.Scan() { |
| 124 | if err := scanner.Err(); err != nil { |
| 125 | return err |
| 126 | } else { |
| 127 | return io.EOF |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | response = scanner.Text() |
| 132 | return nil |
no test coverage detected
searching dependent graphs…