OK, here is the first draft against current master. It builds on Windows with VS 2012 and on FreeBSD 10 with clang 3.3. I ran the regression tests on Windows, they all pass.

The changed behavior is limited to Windows, where it now silently ignores Ctrl-C and Ctrl-Break when started via pg_ctl start.

I don't think there is currently any support for switch-type long options, so rather than invent my own, I squeezed the two lines I added into postmaster.c where they fit best; unfortunately, the result is quite ugly. I'll be happy to refine that if someone can give me a hint on how to do it.

Patch attached, will add to CF soon.

--
Christian

diff --git a/doc/src/sgml/ref/postgres-ref.sgml 
b/doc/src/sgml/ref/postgres-ref.sgml
new file mode 100644
index 8e225e4..731682c
*** a/doc/src/sgml/ref/postgres-ref.sgml
--- b/doc/src/sgml/ref/postgres-ref.sgml
*************** PostgreSQL documentation
*** 590,595 ****
--- 590,620 ----
       </varlistentry>
      </variablelist>
     </refsect2>
+ 
+    <refsect2>
+     <title>Platform-specific Options</title>
+ 
+       <varlistentry>
+        <term><option>--background</option></term>
+        <indexterm>
+         <primary>background execution</primary>
+         <secondary>Windows</secondary>
+        </indexterm>
+        <listitem>
+         <para>
+          This option is effective on Windows only and ignored on all other 
platforms.
+         </para>
+         <para>
+          It instructs the server to ignore the signals caused by pressing
+          <keycombo action="simul"><keycap>Ctrl</><keycap>C</></> or
+          <keycombo action="simul"><keycap>Ctrl</><keycap>Break</></>
+          in a console window. It is used automatically by
+          <command>pg_ctl</command> when called with the
+          <option>start</option> subcommand.
+         </para>
+        </listitem>
+       </varlistentry>
+    </refsect2>
   </refsect1>
  
   <refsect1>
diff --git a/src/backend/port/win32/signal.c b/src/backend/port/win32/signal.c
new file mode 100644
index 322b857..91f8243
*** a/src/backend/port/win32/signal.c
--- b/src/backend/port/win32/signal.c
*************** static pqsigfunc pg_signal_defaults[PG_S
*** 41,46 ****
--- 41,48 ----
  static DWORD WINAPI pg_signal_thread(LPVOID param);
  static BOOL WINAPI pg_console_handler(DWORD dwCtrlType);
  
+ extern bool IsBackgroundPostmaster;
+ extern bool IsUnderPostmaster;
  
  /*
   * pg_usleep --- delay the specified number of microseconds, but
*************** pg_signal_thread(LPVOID param)
*** 346,358 ****
  static BOOL WINAPI
  pg_console_handler(DWORD dwCtrlType)
  {
!       if (dwCtrlType == CTRL_C_EVENT ||
!               dwCtrlType == CTRL_BREAK_EVENT ||
!               dwCtrlType == CTRL_CLOSE_EVENT ||
!               dwCtrlType == CTRL_SHUTDOWN_EVENT)
        {
                pg_queue_signal(SIGINT);
!               return TRUE;
        }
!       return FALSE;
  }
--- 348,369 ----
  static BOOL WINAPI
  pg_console_handler(DWORD dwCtrlType)
  {
!       switch (dwCtrlType)
        {
+       case CTRL_C_EVENT:
+       case CTRL_BREAK_EVENT:
+               /* Ignore if started with "pg_ctl start". */
+               if (IsUnderPostmaster || IsBackgroundPostmaster)
+                       break;
+               /* fall through */
+       case CTRL_CLOSE_EVENT:
+       case CTRL_SHUTDOWN_EVENT:
                pg_queue_signal(SIGINT);
!               break;
!       default:
!               return FALSE;
        }
! 
!       return TRUE;
  }
+ 
diff --git a/src/backend/postmaster/postmaster.c 
b/src/backend/postmaster/postmaster.c
new file mode 100644
index b573fd8..d1ce978
*** a/src/backend/postmaster/postmaster.c
--- b/src/backend/postmaster/postmaster.c
*************** PostmasterMain(int argc, char *argv[])
*** 751,771 ****
                                                           *value;
  
                                        ParseLongOption(optarg, &name, &value);
!                                       if (!value)
                                        {
!                                               if (opt == '-')
!                                                       ereport(ERROR,
!                                                                       
(errcode(ERRCODE_SYNTAX_ERROR),
!                                                                        
errmsg("--%s requires a value",
!                                                                               
        optarg)));
!                                               else
!                                                       ereport(ERROR,
!                                                                       
(errcode(ERRCODE_SYNTAX_ERROR),
!                                                                        
errmsg("-c %s requires a value",
!                                                                               
        optarg)));
                                        }
  
-                                       SetConfigOption(name, value, 
PGC_POSTMASTER, PGC_S_ARGV);
                                        free(name);
                                        if (value)
                                                free(value);
--- 751,780 ----
                                                           *value;
  
                                        ParseLongOption(optarg, &name, &value);
! 
! #ifdef WIN32
!                                       if (strcmp(name, "background") == 0)
!                                               IsBackgroundPostmaster = true;
!                                       else
! #endif
                                        {
!                                               if (!value)
!                                               {
!                                                       if (opt == '-')
!                                                               ereport(ERROR,
!                                                                               
(errcode(ERRCODE_SYNTAX_ERROR),
!                                                                               
 errmsg("--%s requires a value",
!                                                                               
                optarg)));
!                                                       else
!                                                               ereport(ERROR,
!                                                                               
(errcode(ERRCODE_SYNTAX_ERROR),
!                                                                               
 errmsg("-c %s requires a value",
!                                                                               
                optarg)));
!                                               }
! 
!                                               SetConfigOption(name, value, 
PGC_POSTMASTER, PGC_S_ARGV);
                                        }
  
                                        free(name);
                                        if (value)
                                                free(value);
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
new file mode 100644
index be74835..051b33d
*** a/src/backend/utils/init/globals.c
--- b/src/backend/utils/init/globals.c
*************** bool            IsUnderPostmaster = false;
*** 89,94 ****
--- 89,107 ----
  bool          IsBinaryUpgrade = false;
  bool          IsBackgroundWorker = false;
  
+ #ifdef WIN32
+ /*
+  * This controls whether the postmaster process will respond to incoming
+  * console events (Ctrl-C, Ctrl-Break). If the database was started using
+  * "pg_ctl start", it is running in the background, but will still 
+  * receive the signals generated by these key combinations.
+  *
+  * The reaction of the other server processes is controlled by
+  * IsUnderPostmaster instead.
+  */
+ bool          IsBackgroundPostmaster = false;
+ #endif
+ 
  bool          ExitOnAnyError = false;
  
  int                   DateStyle = USE_ISO_DATES;
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
new file mode 100644
index fc87e7d..e0d676e
*** a/src/bin/pg_ctl/pg_ctl.c
--- b/src/bin/pg_ctl/pg_ctl.c
*************** start_postmaster(void)
*** 453,462 ****
        PROCESS_INFORMATION pi;
  
        if (log_file != NULL)
!               snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s < 
\"%s\" >> \"%s\" 2>&1" SYSTEMQUOTE,
                                 exec_path, pgdata_opt, post_opts, DEVNULL, 
log_file);
        else
!               snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s < 
\"%s\" 2>&1" SYSTEMQUOTE,
                                 exec_path, pgdata_opt, post_opts, DEVNULL);
  
        if (!CreateRestrictedProcess(cmd, &pi, false))
--- 453,462 ----
        PROCESS_INFORMATION pi;
  
        if (log_file != NULL)
!               snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s 
--background < \"%s\" >> \"%s\" 2>&1" SYSTEMQUOTE,
                                 exec_path, pgdata_opt, post_opts, DEVNULL, 
log_file);
        else
!               snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s 
--background < \"%s\" 2>&1" SYSTEMQUOTE,
                                 exec_path, pgdata_opt, post_opts, DEVNULL);
  
        if (!CreateRestrictedProcess(cmd, &pi, false))
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
new file mode 100644
index 0d61b82..3a527e9
*** a/src/include/miscadmin.h
--- b/src/include/miscadmin.h
*************** extern PGDLLIMPORT bool IsUnderPostmaste
*** 136,141 ****
--- 136,145 ----
  extern bool IsBackgroundWorker;
  extern bool IsBinaryUpgrade;
  
+ #ifdef WIN32
+ extern bool IsBackgroundPostmaster;
+ #endif
+ 
  extern bool ExitOnAnyError;
  
  extern PGDLLIMPORT char *DataDir;
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to