Clean up some code, comments and docs referring to Windows 2000 and older
This fixes and updates a couple of comments related to outdated Windows versions. Particularly, src/common/exec.c had a fallback implementation to read a file's line from a pipe because stdin/stdout/stderr does not exist in Windows 2000 that is removed to simplify src/common/ as there are unlikely versions of Postgres running on such platforms. Author: Michael Paquier Reviewed-by: Kyotaro Horiguchi, Juan José Santamaría Flecha Discussion: https://postgr.es/m/20191219021526.GC4202@paquier.xyz
This commit is contained in:
parent
e3ff789acf
commit
e2e02191e2
|
@ -46,8 +46,7 @@
|
||||||
<productname>Cygwin</productname> is not recommended for running a
|
<productname>Cygwin</productname> is not recommended for running a
|
||||||
production server, and it should only be used for running on
|
production server, and it should only be used for running on
|
||||||
older versions of <productname>Windows</productname> where
|
older versions of <productname>Windows</productname> where
|
||||||
the native build does not work, such as
|
the native build does not work. The official
|
||||||
<productname>Windows 98</productname>. The official
|
|
||||||
binaries are built using <productname>Visual Studio</productname>.
|
binaries are built using <productname>Visual Studio</productname>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|
|
@ -2087,7 +2087,7 @@ export MANPATH
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<productname>PostgreSQL</productname> can be expected to work on these operating
|
<productname>PostgreSQL</productname> can be expected to work on these operating
|
||||||
systems: Linux (all recent distributions), Windows (Win2000 SP4 and later),
|
systems: Linux (all recent distributions), Windows (XP and later),
|
||||||
FreeBSD, OpenBSD, NetBSD, macOS, AIX, HP/UX, and Solaris.
|
FreeBSD, OpenBSD, NetBSD, macOS, AIX, HP/UX, and Solaris.
|
||||||
Other Unix-like systems may also work but are not currently
|
Other Unix-like systems may also work but are not currently
|
||||||
being tested. In most cases, all CPU architectures supported by
|
being tested. In most cases, all CPU architectures supported by
|
||||||
|
|
|
@ -2503,9 +2503,9 @@ InitializeLDAPConnection(Port *port, LDAP **ldap)
|
||||||
if (_ldap_start_tls_sA == NULL)
|
if (_ldap_start_tls_sA == NULL)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Need to load this function dynamically because it does not
|
* Need to load this function dynamically because it may not exist
|
||||||
* exist on Windows 2000, and causes a load error for the whole
|
* on Windows, and causes a load error for the whole exe if
|
||||||
* exe if referenced.
|
* referenced.
|
||||||
*/
|
*/
|
||||||
HANDLE ldaphandle;
|
HANDLE ldaphandle;
|
||||||
|
|
||||||
|
|
|
@ -2007,7 +2007,7 @@ make_postgres(FILE *cmdfd)
|
||||||
* signal handler in case we are interrupted.
|
* signal handler in case we are interrupted.
|
||||||
*
|
*
|
||||||
* The Windows runtime docs at
|
* The Windows runtime docs at
|
||||||
* http://msdn.microsoft.com/library/en-us/vclib/html/_crt_signal.asp
|
* https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/signal
|
||||||
* specifically forbid a number of things being done from a signal handler,
|
* specifically forbid a number of things being done from a signal handler,
|
||||||
* including IO, memory allocation and system calls, and only allow jmpbuf
|
* including IO, memory allocation and system calls, and only allow jmpbuf
|
||||||
* if you are handling SIGFPE.
|
* if you are handling SIGFPE.
|
||||||
|
@ -2016,11 +2016,10 @@ make_postgres(FILE *cmdfd)
|
||||||
* exit() directly.
|
* exit() directly.
|
||||||
*
|
*
|
||||||
* Also note the behaviour of Windows with SIGINT, which says this:
|
* Also note the behaviour of Windows with SIGINT, which says this:
|
||||||
* Note SIGINT is not supported for any Win32 application, including
|
* SIGINT is not supported for any Win32 application. When a CTRL+C interrupt
|
||||||
* Windows 98/Me and Windows NT/2000/XP. When a CTRL+C interrupt occurs,
|
* occurs, Win32 operating systems generate a new thread to specifically
|
||||||
* Win32 operating systems generate a new thread to specifically handle
|
* handle that interrupt. This can cause a single-thread application, such as
|
||||||
* that interrupt. This can cause a single-thread application such as UNIX,
|
* one in UNIX, to become multithreaded and cause unexpected behavior.
|
||||||
* to become multithreaded, resulting in unexpected behavior.
|
|
||||||
*
|
*
|
||||||
* I have no idea how to handle this. (Strange they call UNIX an application!)
|
* I have no idea how to handle this. (Strange they call UNIX an application!)
|
||||||
* So this will need some testing on Windows.
|
* So this will need some testing on Windows.
|
||||||
|
|
|
@ -354,17 +354,11 @@ find_other_exec(const char *argv0, const char *target,
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The runtime library's popen() on win32 does not work when being
|
* Execute a command in a pipe and read the first line from it.
|
||||||
* called from a service when running on windows <= 2000, because
|
|
||||||
* there is no stdin/stdout/stderr.
|
|
||||||
*
|
|
||||||
* Executing a command in a pipe and reading the first line from it
|
|
||||||
* is all we need.
|
|
||||||
*/
|
*/
|
||||||
static char *
|
static char *
|
||||||
pipe_read_line(char *cmd, char *line, int maxsize)
|
pipe_read_line(char *cmd, char *line, int maxsize)
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
|
||||||
FILE *pgver;
|
FILE *pgver;
|
||||||
|
|
||||||
/* flush output buffers in case popen does not... */
|
/* flush output buffers in case popen does not... */
|
||||||
|
@ -393,130 +387,6 @@ pipe_read_line(char *cmd, char *line, int maxsize)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
#else /* WIN32 */
|
|
||||||
|
|
||||||
SECURITY_ATTRIBUTES sattr;
|
|
||||||
HANDLE childstdoutrd,
|
|
||||||
childstdoutwr,
|
|
||||||
childstdoutrddup;
|
|
||||||
PROCESS_INFORMATION pi;
|
|
||||||
STARTUPINFO si;
|
|
||||||
char *retval = NULL;
|
|
||||||
|
|
||||||
sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
|
||||||
sattr.bInheritHandle = TRUE;
|
|
||||||
sattr.lpSecurityDescriptor = NULL;
|
|
||||||
|
|
||||||
if (!CreatePipe(&childstdoutrd, &childstdoutwr, &sattr, 0))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!DuplicateHandle(GetCurrentProcess(),
|
|
||||||
childstdoutrd,
|
|
||||||
GetCurrentProcess(),
|
|
||||||
&childstdoutrddup,
|
|
||||||
0,
|
|
||||||
FALSE,
|
|
||||||
DUPLICATE_SAME_ACCESS))
|
|
||||||
{
|
|
||||||
CloseHandle(childstdoutrd);
|
|
||||||
CloseHandle(childstdoutwr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(childstdoutrd);
|
|
||||||
|
|
||||||
ZeroMemory(&pi, sizeof(pi));
|
|
||||||
ZeroMemory(&si, sizeof(si));
|
|
||||||
si.cb = sizeof(si);
|
|
||||||
si.dwFlags = STARTF_USESTDHANDLES;
|
|
||||||
si.hStdError = childstdoutwr;
|
|
||||||
si.hStdOutput = childstdoutwr;
|
|
||||||
si.hStdInput = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
if (CreateProcess(NULL,
|
|
||||||
cmd,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
TRUE,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&si,
|
|
||||||
&pi))
|
|
||||||
{
|
|
||||||
/* Successfully started the process */
|
|
||||||
char *lineptr;
|
|
||||||
|
|
||||||
ZeroMemory(line, maxsize);
|
|
||||||
|
|
||||||
/* Try to read at least one line from the pipe */
|
|
||||||
/* This may require more than one wait/read attempt */
|
|
||||||
for (lineptr = line; lineptr < line + maxsize - 1;)
|
|
||||||
{
|
|
||||||
DWORD bytesread = 0;
|
|
||||||
|
|
||||||
/* Let's see if we can read */
|
|
||||||
if (WaitForSingleObject(childstdoutrddup, 10000) != WAIT_OBJECT_0)
|
|
||||||
break; /* Timeout, but perhaps we got a line already */
|
|
||||||
|
|
||||||
if (!ReadFile(childstdoutrddup, lineptr, maxsize - (lineptr - line),
|
|
||||||
&bytesread, NULL))
|
|
||||||
break; /* Error, but perhaps we got a line already */
|
|
||||||
|
|
||||||
lineptr += strlen(lineptr);
|
|
||||||
|
|
||||||
if (!bytesread)
|
|
||||||
break; /* EOF */
|
|
||||||
|
|
||||||
if (strchr(line, '\n'))
|
|
||||||
break; /* One or more lines read */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lineptr != line)
|
|
||||||
{
|
|
||||||
/* OK, we read some data */
|
|
||||||
int len;
|
|
||||||
|
|
||||||
/* If we got more than one line, cut off after the first \n */
|
|
||||||
lineptr = strchr(line, '\n');
|
|
||||||
if (lineptr)
|
|
||||||
*(lineptr + 1) = '\0';
|
|
||||||
|
|
||||||
len = strlen(line);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If EOL is \r\n, convert to just \n. Because stdout is a
|
|
||||||
* text-mode stream, the \n output by the child process is
|
|
||||||
* received as \r\n, so we convert it to \n. The server main.c
|
|
||||||
* sets setvbuf(stdout, NULL, _IONBF, 0) which has the effect of
|
|
||||||
* disabling \n to \r\n expansion for stdout.
|
|
||||||
*/
|
|
||||||
if (len >= 2 && line[len - 2] == '\r' && line[len - 1] == '\n')
|
|
||||||
{
|
|
||||||
line[len - 2] = '\n';
|
|
||||||
line[len - 1] = '\0';
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We emulate fgets() behaviour. So if there is no newline at the
|
|
||||||
* end, we add one...
|
|
||||||
*/
|
|
||||||
if (len == 0 || line[len - 1] != '\n')
|
|
||||||
strcat(line, "\n");
|
|
||||||
|
|
||||||
retval = line;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(pi.hProcess);
|
|
||||||
CloseHandle(pi.hThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(childstdoutwr);
|
|
||||||
CloseHandle(childstdoutrddup);
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
#endif /* WIN32 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,10 +69,9 @@ haveNativeWindowsIPv6routines(void)
|
||||||
return (getaddrinfo_ptr != NULL);
|
return (getaddrinfo_ptr != NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For Windows XP and Windows 2003 (and longhorn/vista), the IPv6 routines
|
* For Windows XP and later versions, the IPv6 routines are present in the
|
||||||
* are present in the WinSock 2 library (ws2_32.dll). Try that first
|
* WinSock 2 library (ws2_32.dll).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
hLibrary = LoadLibraryA("ws2_32");
|
hLibrary = LoadLibraryA("ws2_32");
|
||||||
|
|
||||||
if (hLibrary == NULL || GetProcAddress(hLibrary, "getaddrinfo") == NULL)
|
if (hLibrary == NULL || GetProcAddress(hLibrary, "getaddrinfo") == NULL)
|
||||||
|
@ -83,13 +82,6 @@ haveNativeWindowsIPv6routines(void)
|
||||||
*/
|
*/
|
||||||
if (hLibrary != NULL)
|
if (hLibrary != NULL)
|
||||||
FreeLibrary(hLibrary);
|
FreeLibrary(hLibrary);
|
||||||
|
|
||||||
/*
|
|
||||||
* In Windows 2000, there was only the IPv6 Technology Preview look in
|
|
||||||
* the IPv6 WinSock library (wship6.dll).
|
|
||||||
*/
|
|
||||||
|
|
||||||
hLibrary = LoadLibraryA("wship6");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If hLibrary is null, we couldn't find a dll with functions */
|
/* If hLibrary is null, we couldn't find a dll with functions */
|
||||||
|
|
Loading…
Reference in New Issue