From ac87953f4e94b692ed0d3fb3067ba7b841311b3a Mon Sep 17 00:00:00 2001
From: Paul Guo <paulguo@gmail.com>
Date: Fri, 27 Jul 2018 18:11:31 +0800
Subject: [PATCH] Create a new session for postmaster in pg_ctl by calling
 setsid().

postmaster does not create a new session like its children.
This could lead to some issues when postmaster is launched
via pg_ctl. For example, running the script below and press
ctrl+c to terminate the pg_sleep() sql could lead to
postmaster down.

$ cat test.sh
pg_ctl -D ./data -l stop.log stop
sleep 2 -- wait for pg down.
pg_ctl -D ./data -l start.log start
sleep 2 -- wait for pg up.
echo "pg_sleep()-ing"
psql -d postgres -c 'select pg_sleep(1000)'  -- press ctrl+c, then you will see postmaster and its children are all gone.

We do not directly call setsid() in postmaster process since we want
to signal postmaster on the terminal if it is manually launched.
---
 src/bin/pg_ctl/pg_ctl.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index ed2396aa6c..548640cdfe 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -468,6 +468,15 @@ start_postmaster(void)
 
 	/* fork succeeded, in child */
 
+#ifdef HAVE_SETSID
+	if (setsid() < 0)
+	{
+		write_stderr(_("%s: could not start server due to setsid() failure: %s\n"),
+					 progname, strerror(errno));
+		exit(1);
+	}
+#endif
+
 	/*
 	 * Since there might be quotes to handle here, it is easier simply to pass
 	 * everything to a shell to process them.  Use exec so that the postmaster
-- 
2.14.3

