closeConsoleNoLock closes the console handle, and sets it to windows.InvalidHandle. It must be called with p.closeMutex held.
()
| 169 | // closeConsoleNoLock closes the console handle, and sets it to |
| 170 | // windows.InvalidHandle. It must be called with p.closeMutex held. |
| 171 | func (p *ptyWindows) closeConsoleNoLock() error { |
| 172 | // if we are running a command in the PTY, the corresponding *windowsProcess |
| 173 | // may have already closed the PseudoConsole when the command exited, so that |
| 174 | // output reads can get to EOF. In that case, we don't need to close it |
| 175 | // again here. |
| 176 | if p.console != windows.InvalidHandle { |
| 177 | // ClosePseudoConsole has no return value and typically the syscall |
| 178 | // returns S_FALSE (a success value). We could ignore the return value |
| 179 | // and error here but we handle anyway, it just in case. |
| 180 | // |
| 181 | // Note that ClosePseudoConsole is a blocking system call and may write |
| 182 | // a final frame to the output buffer (p.outputWrite), so there must be |
| 183 | // a consumer (p.outputRead) to ensure we don't block here indefinitely. |
| 184 | // |
| 185 | // https://docs.microsoft.com/en-us/windows/console/closepseudoconsole |
| 186 | ret, _, err := procClosePseudoConsole.Call(uintptr(p.console)) |
| 187 | if winerrorFailed(ret) { |
| 188 | return xerrors.Errorf("close pseudo console (%d): %w", ret, err) |
| 189 | } |
| 190 | p.console = windows.InvalidHandle |
| 191 | } |
| 192 | |
| 193 | return nil |
| 194 | } |
| 195 | |
| 196 | func (p *ptyWindows) Close() error { |
| 197 | p.closeMutex.Lock() |
no test coverage detected