1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
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);
|