mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-18 18:44:06 +08:00
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:
parent
25a1324703
commit
5b2f4afffe
@ -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">
|
||||
@ -1271,7 +1271,7 @@ $PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.270 2004/07/26 00:26:42 momjian
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
New start/end of dump markers in pg_dump (Bruce)
|
||||
New start/stop of dump markers in pg_dump (Bruce)
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
|
142
src/port/exec.c
142
src/port/exec.c
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -290,14 +412,12 @@ find_other_exec(const char *argv0, const char *target,
|
||||
{
|
||||
char cmd[MAXPGPATH];
|
||||
char line[100];
|
||||
FILE *pgver;
|
||||
|
||||
|
||||
if (find_my_exec(argv0, retpath) < 0)
|
||||
return -1;
|
||||
|
||||
/* Trim off program name and keep just directory */
|
||||
*last_dir_separator(retpath) = '\0';
|
||||
|
||||
snprintf(retpath + strlen(retpath), MAXPGPATH - strlen(retpath),
|
||||
"/%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);
|
||||
|
||||
/* flush output buffers in case popen does not... */
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
if ((pgver = popen(cmd, "r")) == NULL)
|
||||
if (!pipe_read_line(cmd, line, sizeof(line)))
|
||||
return -1;
|
||||
|
||||
if (fgets(line, sizeof(line), pgver) == NULL)
|
||||
perror("fgets failure");
|
||||
|
||||
if (pclose_check(pgver))
|
||||
return -1;
|
||||
|
||||
|
||||
if (strcmp(line, versionstr) != 0)
|
||||
return -2;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user