()
| 319 | } |
| 320 | |
| 321 | func (gc *Command) wrap() error { |
| 322 | pipes := gc.exec.pipes |
| 323 | cmd := gc.exec.command |
| 324 | ctx := gc.exec.context |
| 325 | |
| 326 | // Close and drain the pipes |
| 327 | pipes.closeCallee() |
| 328 | _ = pipes.ioGroup.Wait() |
| 329 | pipes.closeCaller() |
| 330 | |
| 331 | // Get the status, exitCode, signal, error |
| 332 | var ( |
| 333 | status syscall.WaitStatus |
| 334 | signal os.Signal |
| 335 | exitCode int |
| 336 | err error |
| 337 | ) |
| 338 | |
| 339 | // XXXgolang: this is troubling. cmd.ProcessState.ExitCode() is always fine, even if cmd.ProcessState is nil. |
| 340 | exitCode = cmd.ProcessState.ExitCode() |
| 341 | |
| 342 | if cmd.ProcessState != nil { |
| 343 | var ok bool |
| 344 | if status, ok = cmd.ProcessState.Sys().(syscall.WaitStatus); !ok { |
| 345 | panic("failed casting process state sys") |
| 346 | } |
| 347 | |
| 348 | if status.Signaled() { |
| 349 | signal = status.Signal() |
| 350 | err = ErrSignaled |
| 351 | } else if exitCode != 0 { |
| 352 | err = ErrExecutionFailed |
| 353 | } |
| 354 | } |
| 355 | |
| 356 | // Catch-up on the context. |
| 357 | switch ctx.Err() { |
| 358 | case context.DeadlineExceeded: |
| 359 | err = ErrTimeout |
| 360 | case context.Canceled: |
| 361 | err = errExecutionCancelled |
| 362 | default: |
| 363 | } |
| 364 | |
| 365 | // Stuff everything in Result and return err. |
| 366 | gc.result = &Result{ |
| 367 | ExitCode: exitCode, |
| 368 | Stdout: pipes.fromStdout, |
| 369 | Stderr: pipes.fromStderr, |
| 370 | Environ: cmd.Environ(), |
| 371 | Signal: signal, |
| 372 | Duration: time.Since(gc.startTime), |
| 373 | } |
| 374 | |
| 375 | if gc.exec.err == nil { |
| 376 | gc.exec.err = err |
| 377 | } |
| 378 |
no test coverage detected