Here is a patch that fixes the pipes used in find_other_exec() when

running as a service on windows <= 2000. Required to make the pg_ctl
service wrapper to work at all.

Magnus Hagander
This commit is contained in:
Bruce Momjian 2004-07-26 01:48:00 +00:00
parent 25a1324703
commit 5b2f4afffe
2 changed files with 128 additions and 18 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.270 2004/07/26 00:26:42 momjian Exp $ $PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.271 2004/07/26 01:47:59 momjian Exp $
--> -->
<appendix id="release"> <appendix id="release">
@ -1271,7 +1271,7 @@ $PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.270 2004/07/26 00:26:42 momjian
<listitem> <listitem>
<para> <para>
New start/end of dump markers in pg_dump (Bruce) New start/stop of dump markers in pg_dump (Bruce)
</para> </para>
</listitem> </listitem>

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/port/exec.c,v 1.16 2004/06/10 22:26:24 momjian Exp $ * $PostgreSQL: pgsql/src/port/exec.c,v 1.17 2004/07/26 01:48:00 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -279,6 +279,128 @@ find_my_exec(const char *argv0, char *retpath)
#endif #endif
} }
/*
* The runtime librarys popen() on win32 does not work when being
* 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 *pipe_read_line(char *cmd, char *line, int maxsize)
{
#ifndef WIN32
FILE *pgver;
/* flush output buffers in case popen does not... */
fflush(stdout);
fflush(stderr);
if ((pgver = popen(cmd, "r")) == NULL)
return NULL;
if (fgets(line, maxsize, pgver) == NULL)
{
perror("fgets failure");
return NULL;
}
if (pclose_check(pgver))
return NULL;
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))
{
DWORD bytesread = 0;
/* Successfully started the process */
ZeroMemory(line,maxsize);
/* Let's see if we can read */
if (WaitForSingleObject(childstdoutrddup, 10000) != WAIT_OBJECT_0)
{
/* Got timeout */
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(childstdoutwr);
CloseHandle(childstdoutrddup);
return NULL;
}
/* We try just once */
if (ReadFile(childstdoutrddup, line, maxsize, &bytesread, NULL) &&
bytesread > 0)
{
/* So we read some data */
retval = line;
/* We emulate fgets() behaviour. So if there is no newline
* at the end, we add one... */
if (line[strlen(line)-1] != '\n')
strcat(line,"\n");
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
CloseHandle(childstdoutwr);
CloseHandle(childstdoutrddup);
return retval;
#endif
}
/* /*
* Find our binary directory, then make sure the "target" executable * Find our binary directory, then make sure the "target" executable
@ -290,14 +412,12 @@ find_other_exec(const char *argv0, const char *target,
{ {
char cmd[MAXPGPATH]; char cmd[MAXPGPATH];
char line[100]; char line[100];
FILE *pgver;
if (find_my_exec(argv0, retpath) < 0) if (find_my_exec(argv0, retpath) < 0)
return -1; return -1;
/* Trim off program name and keep just directory */ /* Trim off program name and keep just directory */
*last_dir_separator(retpath) = '\0'; *last_dir_separator(retpath) = '\0';
snprintf(retpath + strlen(retpath), MAXPGPATH - strlen(retpath), snprintf(retpath + strlen(retpath), MAXPGPATH - strlen(retpath),
"/%s%s", target, EXE); "/%s%s", target, EXE);
@ -306,19 +426,9 @@ find_other_exec(const char *argv0, const char *target,
snprintf(cmd, sizeof(cmd), "\"%s\" -V 2>%s", retpath, DEVNULL); snprintf(cmd, sizeof(cmd), "\"%s\" -V 2>%s", retpath, DEVNULL);
/* flush output buffers in case popen does not... */ if (!pipe_read_line(cmd, line, sizeof(line)))
fflush(stdout);
fflush(stderr);
if ((pgver = popen(cmd, "r")) == NULL)
return -1; return -1;
if (fgets(line, sizeof(line), pgver) == NULL)
perror("fgets failure");
if (pclose_check(pgver))
return -1;
if (strcmp(line, versionstr) != 0) if (strcmp(line, versionstr) != 0)
return -2; return -2;