diff --git a/pglogical_apply_spi.c b/pglogical_apply_spi.c index 3eaccc4..111a4eb 100644 --- a/pglogical_apply_spi.c +++ b/pglogical_apply_spi.c @@ -454,7 +454,7 @@ static void pglogical_proccess_copy(pglogical_copyState *pglcstate) { uint64 processed; - FILE *save_stdin; + int save_stdin; if (!pglcstate->copy_parsetree || !pglcstate->copy_buffered_tuples) return; @@ -489,8 +489,16 @@ pglogical_proccess_copy(pglogical_copyState *pglcstate) * for this relation. Before that we save the current 'stdin' stream and * restore it back when the COPY is done */ - save_stdin = stdin; - stdin = pglcstate->copy_read_file; + save_stdin = dup(fileno(stdin)); + if (save_stdin < 0) + ereport(FATAL, + (errcode_for_file_access(), + errmsg("could not save stdin: %m"))); + + if (dup2(fileno(pglcstate->copy_read_file), fileno(stdin)) < 0) + ereport(FATAL, + (errcode_for_file_access(), + errmsg("could not redirect stdin: %m"))); /* COPY may call into SPI (triggers, ...) and we already are in SPI. */ SPI_push(); @@ -501,10 +509,17 @@ pglogical_proccess_copy(pglogical_copyState *pglcstate) /* Clean up SPI state */ SPI_pop(); + /* + * Also close the read end of the pipe and restore 'stdin' to its original + * value + */ + if (dup2(save_stdin, fileno(stdin)) < 0) + ereport(FATAL, + (errcode_for_file_access(), + errmsg("could not restore stdin: %m"))); fclose(pglcstate->copy_read_file); pglcstate->copy_read_file = NULL; - stdin = save_stdin; /* Ensure we processed correct number of tuples */ Assert(processed == pglcstate->copy_buffered_tuples);