* \w -- write query buffer to file */
| 2594 | * \w -- write query buffer to file |
| 2595 | */ |
| 2596 | static backslashResult |
| 2597 | exec_command_write(PsqlScanState scan_state, bool active_branch, |
| 2598 | const char *cmd, |
| 2599 | PQExpBuffer query_buf, PQExpBuffer previous_buf) |
| 2600 | { |
| 2601 | backslashResult status = PSQL_CMD_SKIP_LINE; |
| 2602 | |
| 2603 | if (active_branch) |
| 2604 | { |
| 2605 | char *fname = psql_scan_slash_option(scan_state, |
| 2606 | OT_FILEPIPE, NULL, true); |
| 2607 | FILE *fd = NULL; |
| 2608 | bool is_pipe = false; |
| 2609 | |
| 2610 | if (!query_buf) |
| 2611 | { |
| 2612 | pg_log_error("no query buffer"); |
| 2613 | status = PSQL_CMD_ERROR; |
| 2614 | } |
| 2615 | else |
| 2616 | { |
| 2617 | if (!fname) |
| 2618 | { |
| 2619 | pg_log_error("\\%s: missing required argument", cmd); |
| 2620 | status = PSQL_CMD_ERROR; |
| 2621 | } |
| 2622 | else |
| 2623 | { |
| 2624 | expand_tilde(&fname); |
| 2625 | if (fname[0] == '|') |
| 2626 | { |
| 2627 | is_pipe = true; |
| 2628 | disable_sigpipe_trap(); |
| 2629 | fd = popen(&fname[1], "w"); |
| 2630 | } |
| 2631 | else |
| 2632 | { |
| 2633 | canonicalize_path(fname); |
| 2634 | fd = fopen(fname, "w"); |
| 2635 | } |
| 2636 | if (!fd) |
| 2637 | { |
| 2638 | pg_log_error("%s: %m", fname); |
| 2639 | status = PSQL_CMD_ERROR; |
| 2640 | } |
| 2641 | } |
| 2642 | } |
| 2643 | |
| 2644 | if (fd) |
| 2645 | { |
| 2646 | int result; |
| 2647 | |
| 2648 | /* |
| 2649 | * We want to print the same thing \g would execute, but not to |
| 2650 | * change the query buffer state; so we can't use |
| 2651 | * copy_previous_query(). Also, beware of possibility that buffer |
| 2652 | * pointers are NULL. |
| 2653 | */ |
no test coverage detected