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">
|
<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>
|
||||||
|
|
||||||
|
142
src/port/exec.c
142
src/port/exec.c
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user