aboutsummaryrefslogtreecommitdiffstats
path: root/community/postgresql-pglogical/001-fix-stdin-handling.patch
blob: 8ba3f6c958b80b7c8704901929446c5b61add061 (plain)
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);