Re: Patch to add Windows 7 support - Mailing list pgsql-hackers

From Magnus Hagander
Subject Re: Patch to add Windows 7 support
Date
Msg-id 49803F52.5010009@hagander.net
Whole thread Raw
In response to Re: Patch to add Windows 7 support  (Dave Page <dpage@pgadmin.org>)
List pgsql-hackers
Dave Page wrote:
>> I don't think it's enough that we need to care about it really. I'm
>> thinking we could perhaps even just never set that, and not bother with
>> the version check...
>
> That was how I originally coded it, but figured we might as well set
> it if we can - it's not like it's expensive to do.
>
>> But perhaps we should set it only when launching as a service, and not
>> when running from the commandline?
>
> We could. I'm not sure there's a great deal of need - most people will
> run as a service, and it won't make any difference for those that
> start the postmaster directly.

I have applied this updated patch. It simplifies the if branches a bit
(imho, that is), and also adds the switch to only make the change when
starting as a service.

//Magnus

*** a/src/bin/pg_ctl/pg_ctl.c
--- b/src/bin/pg_ctl/pg_ctl.c
***************
*** 121,127 **** static void pgwin32_SetServiceStatus(DWORD);
  static void WINAPI pgwin32_ServiceHandler(DWORD);
  static void WINAPI pgwin32_ServiceMain(DWORD, LPTSTR *);
  static void pgwin32_doRunAsService(void);
! static int    CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo);

  static SERVICE_STATUS status;
  static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
--- 121,127 ----
  static void WINAPI pgwin32_ServiceHandler(DWORD);
  static void WINAPI pgwin32_ServiceMain(DWORD, LPTSTR *);
  static void pgwin32_doRunAsService(void);
! static int    CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo, bool as_service);

  static SERVICE_STATUS status;
  static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
***************
*** 385,391 **** start_postmaster(void)
          snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s < \"%s\" 2>&1" SYSTEMQUOTE,
                   postgres_path, pgdata_opt, post_opts, DEVNULL);

!     if (!CreateRestrictedProcess(cmd, &pi))
          return GetLastError();
      CloseHandle(pi.hProcess);
      CloseHandle(pi.hThread);
--- 385,391 ----
          snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s < \"%s\" 2>&1" SYSTEMQUOTE,
                   postgres_path, pgdata_opt, post_opts, DEVNULL);

!     if (!CreateRestrictedProcess(cmd, &pi, false))
          return GetLastError();
      CloseHandle(pi.hProcess);
      CloseHandle(pi.hThread);
***************
*** 1210,1216 **** pgwin32_ServiceMain(DWORD argc, LPTSTR * argv)

      /* Start the postmaster */
      pgwin32_SetServiceStatus(SERVICE_START_PENDING);
!     if (!CreateRestrictedProcess(pgwin32_CommandLine(false), &pi))
      {
          pgwin32_SetServiceStatus(SERVICE_STOPPED);
          return;
--- 1210,1216 ----

      /* Start the postmaster */
      pgwin32_SetServiceStatus(SERVICE_START_PENDING);
!     if (!CreateRestrictedProcess(pgwin32_CommandLine(false), &pi, true))
      {
          pgwin32_SetServiceStatus(SERVICE_STOPPED);
          return;
***************
*** 1313,1319 **** typedef        BOOL(WINAPI * __QueryInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS,
   * automatically destroyed when pg_ctl exits.
   */
  static int
! CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo)
  {
      int            r;
      BOOL        b;
--- 1313,1319 ----
   * automatically destroyed when pg_ctl exits.
   */
  static int
! CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo, bool as_service)
  {
      int            r;
      BOOL        b;
***************
*** 1449,1454 **** CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo)
--- 1449,1455 ----
                      JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit;
                      JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions;
                      JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit;
+                     OSVERSIONINFO osv;

                      ZeroMemory(&basicLimit, sizeof(basicLimit));
                      ZeroMemory(&uiRestrictions, sizeof(uiRestrictions));
***************
*** 1459,1466 **** CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo)
                      _SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));

                      uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP |
JOB_OBJECT_UILIMIT_DISPLAYSETTINGS| 
!                         JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_HANDLES |
JOB_OBJECT_UILIMIT_READCLIPBOARD| 
                          JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
                      _SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions,
sizeof(uiRestrictions));

                      securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;
--- 1460,1482 ----
                      _SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));

                      uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP |
JOB_OBJECT_UILIMIT_DISPLAYSETTINGS| 
!                         JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_READCLIPBOARD |
                          JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
+
+                     if (as_service)
+                     {
+                         osv.dwOSVersionInfoSize = sizeof(osv);
+                         if (!GetVersionEx(&osv) ||
+                             osv.dwMajorVersion < 6 ||
+                             (osv.dwMajorVersion == 6 && osv.dwMinorVersion == 0))
+                         {
+                             /*
+                              * On Windows 7 (and presumably later), JOB_OBJECT_UILIMIT_HANDLES prevents us from
+                              * starting as a service. So we only enable it on Vista and earlier (version <= 6.0)
+                              */
+                             uiRestrictions.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
+                         }
+                     }
                      _SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions,
sizeof(uiRestrictions));

                      securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;

pgsql-hackers by date:

Previous
From: Cédric Villemain
Date:
Subject: Re: Commitfest infrastructure (was Re: 8.4 release planning)
Next
From: Gregory Stark
Date:
Subject: Re: Index Scan cost expression