| 442 | } |
| 443 | |
| 444 | static int run_credential_helper(struct credential *c, |
| 445 | const char *cmd, |
| 446 | int want_output) |
| 447 | { |
| 448 | struct child_process helper = CHILD_PROCESS_INIT; |
| 449 | FILE *fp; |
| 450 | |
| 451 | strvec_push(&helper.args, cmd); |
| 452 | helper.use_shell = 1; |
| 453 | helper.in = -1; |
| 454 | if (want_output) |
| 455 | helper.out = -1; |
| 456 | else |
| 457 | helper.no_stdout = 1; |
| 458 | |
| 459 | if (start_command(&helper) < 0) |
| 460 | return -1; |
| 461 | |
| 462 | fp = xfdopen(helper.in, "w"); |
| 463 | sigchain_push(SIGPIPE, SIG_IGN); |
| 464 | credential_write(c, fp, want_output ? CREDENTIAL_OP_HELPER : CREDENTIAL_OP_RESPONSE); |
| 465 | fclose(fp); |
| 466 | sigchain_pop(SIGPIPE); |
| 467 | |
| 468 | if (want_output) { |
| 469 | int r; |
| 470 | fp = xfdopen(helper.out, "r"); |
| 471 | r = credential_read(c, fp, CREDENTIAL_OP_HELPER); |
| 472 | fclose(fp); |
| 473 | if (r < 0) { |
| 474 | finish_command(&helper); |
| 475 | return -1; |
| 476 | } |
| 477 | } |
| 478 | |
| 479 | if (finish_command(&helper)) |
| 480 | return -1; |
| 481 | return 0; |
| 482 | } |
| 483 | |
| 484 | static int credential_do(struct credential *c, const char *helper, |
| 485 | const char *operation) |
no test coverage detected