pgindent files for Tom.
This commit is contained in:
parent
83526ccf06
commit
bb44a7c525
@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.82 2004/05/25 01:00:20 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.83 2004/05/27 15:07:40 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -23,7 +23,7 @@
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#if defined(__alpha) && defined(__osf__) /* no __alpha__ ? */
|
#if defined(__alpha) && defined(__osf__) /* no __alpha__ ? */
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
#include "machine/hal_sysinfo.h"
|
#include "machine/hal_sysinfo.h"
|
||||||
#define ASSEMBLER
|
#define ASSEMBLER
|
||||||
@ -50,6 +50,7 @@ int
|
|||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
#endif
|
#endif
|
||||||
@ -67,7 +68,7 @@ main(int argc, char *argv[])
|
|||||||
* without help. Avoid adding more here, if you can.
|
* without help. Avoid adding more here, if you can.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(__alpha) /* no __alpha__ ? */
|
#if defined(__alpha) /* no __alpha__ ? */
|
||||||
#ifdef NOFIXADE
|
#ifdef NOFIXADE
|
||||||
int buffer[] = {SSIN_UACPROC, UAC_SIGBUS};
|
int buffer[] = {SSIN_UACPROC, UAC_SIGBUS};
|
||||||
#endif /* NOFIXADE */
|
#endif /* NOFIXADE */
|
||||||
@ -77,7 +78,7 @@ main(int argc, char *argv[])
|
|||||||
#endif /* __alpha */
|
#endif /* __alpha */
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
char *env_locale;
|
char *env_locale;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(NOFIXADE) || defined(NOPRINTADE)
|
#if defined(NOFIXADE) || defined(NOPRINTADE)
|
||||||
@ -86,7 +87,7 @@ main(int argc, char *argv[])
|
|||||||
syscall(SYS_sysmips, MIPS_FIXADE, 0, NULL, NULL, NULL);
|
syscall(SYS_sysmips, MIPS_FIXADE, 0, NULL, NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__alpha) /* no __alpha__ ? */
|
#if defined(__alpha) /* no __alpha__ ? */
|
||||||
if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL,
|
if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL,
|
||||||
(unsigned long) NULL) < 0)
|
(unsigned long) NULL) < 0)
|
||||||
fprintf(stderr, gettext("%s: setsysinfo failed: %s\n"),
|
fprintf(stderr, gettext("%s: setsysinfo failed: %s\n"),
|
||||||
@ -96,15 +97,15 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
{
|
{
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Make output streams unbuffered by default */
|
/* Make output streams unbuffered by default */
|
||||||
setvbuf(stdout,NULL,_IONBF,0);
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
setvbuf(stderr,NULL,_IONBF,0);
|
setvbuf(stderr, NULL, _IONBF, 0);
|
||||||
|
|
||||||
/* Prepare Winsock */
|
/* Prepare Winsock */
|
||||||
err = WSAStartup(MAKEWORD(2,2), &wsaData);
|
err = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: WSAStartup failed: %d\n",
|
fprintf(stderr, "%s: WSAStartup failed: %d\n",
|
||||||
@ -129,15 +130,15 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Remember the physical location of the initially given argv[] array
|
* Remember the physical location of the initially given argv[] array
|
||||||
* for possible use by ps display. On some platforms, the argv[]
|
* for possible use by ps display. On some platforms, the argv[]
|
||||||
* storage must be overwritten in order to set the process title for ps.
|
* storage must be overwritten in order to set the process title for
|
||||||
* In such cases save_ps_display_args makes and returns a new copy of
|
* ps. In such cases save_ps_display_args makes and returns a new copy
|
||||||
* the argv[] array.
|
* of the argv[] array.
|
||||||
*
|
*
|
||||||
* save_ps_display_args may also move the environment strings to make
|
* save_ps_display_args may also move the environment strings to make
|
||||||
* extra room. Therefore this should be done as early as possible during
|
* extra room. Therefore this should be done as early as possible
|
||||||
* startup, to avoid entanglements with code that might save a getenv()
|
* during startup, to avoid entanglements with code that might save a
|
||||||
* result pointer.
|
* getenv() result pointer.
|
||||||
*/
|
*/
|
||||||
argv = save_ps_display_args(argc, argv);
|
argv = save_ps_display_args(argc, argv);
|
||||||
|
|
||||||
@ -145,31 +146,32 @@ main(int argc, char *argv[])
|
|||||||
* Set up locale information from environment. Note that LC_CTYPE and
|
* Set up locale information from environment. Note that LC_CTYPE and
|
||||||
* LC_COLLATE will be overridden later from pg_control if we are in an
|
* LC_COLLATE will be overridden later from pg_control if we are in an
|
||||||
* already-initialized database. We set them here so that they will
|
* already-initialized database. We set them here so that they will
|
||||||
* be available to fill pg_control during initdb. LC_MESSAGES will get
|
* be available to fill pg_control during initdb. LC_MESSAGES will
|
||||||
* set later during GUC option processing, but we set it here to allow
|
* get set later during GUC option processing, but we set it here to
|
||||||
* startup error messages to be localized.
|
* allow startup error messages to be localized.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
set_pglocale(argv[0], "postgres");
|
set_pglocale(argv[0], "postgres");
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/*
|
|
||||||
* Windows uses codepages rather than the environment, so we work around
|
/*
|
||||||
* that by querying the environment explicitly first for LC_COLLATE
|
* Windows uses codepages rather than the environment, so we work
|
||||||
* and LC_CTYPE. We have to do this because initdb passes those values
|
* around that by querying the environment explicitly first for
|
||||||
* in the environment. If there is nothing there we fall back on the
|
* LC_COLLATE and LC_CTYPE. We have to do this because initdb passes
|
||||||
* codepage.
|
* those values in the environment. If there is nothing there we fall
|
||||||
|
* back on the codepage.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((env_locale = getenv("LC_COLLATE")) != NULL)
|
if ((env_locale = getenv("LC_COLLATE")) != NULL)
|
||||||
setlocale(LC_COLLATE,env_locale);
|
setlocale(LC_COLLATE, env_locale);
|
||||||
else
|
else
|
||||||
setlocale(LC_COLLATE, "");
|
setlocale(LC_COLLATE, "");
|
||||||
|
|
||||||
if ((env_locale = getenv("LC_CTYPE")) != NULL)
|
if ((env_locale = getenv("LC_CTYPE")) != NULL)
|
||||||
setlocale(LC_CTYPE,env_locale);
|
setlocale(LC_CTYPE, env_locale);
|
||||||
else
|
else
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
#else
|
#else
|
||||||
setlocale(LC_COLLATE, "");
|
setlocale(LC_COLLATE, "");
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
@ -213,7 +215,7 @@ main(int argc, char *argv[])
|
|||||||
gettext("\"root\" execution of the PostgreSQL server is not permitted.\n"
|
gettext("\"root\" execution of the PostgreSQL server is not permitted.\n"
|
||||||
"The server must be started under an unprivileged user ID to prevent\n"
|
"The server must be started under an unprivileged user ID to prevent\n"
|
||||||
"possible system security compromise. See the documentation for\n"
|
"possible system security compromise. See the documentation for\n"
|
||||||
"more information on how to properly start the server.\n"
|
"more information on how to properly start the server.\n"
|
||||||
));
|
));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -241,14 +243,14 @@ main(int argc, char *argv[])
|
|||||||
/*
|
/*
|
||||||
* Now dispatch to one of PostmasterMain, PostgresMain, GucInfoMain,
|
* Now dispatch to one of PostmasterMain, PostgresMain, GucInfoMain,
|
||||||
* SubPostmasterMain, pgstat_main, pgstat_mainChild or BootstrapMain
|
* SubPostmasterMain, pgstat_main, pgstat_mainChild or BootstrapMain
|
||||||
* depending on the program name (and possibly first argument) we
|
* depending on the program name (and possibly first argument) we were
|
||||||
* were called with. The lack of consistency here is historical.
|
* called with. The lack of consistency here is historical.
|
||||||
*/
|
*/
|
||||||
len = strlen(argv[0]);
|
len = strlen(argv[0]);
|
||||||
|
|
||||||
if ((len >= 10 && strcmp(argv[0] + len - 10, "postmaster") == 0)
|
if ((len >= 10 && strcmp(argv[0] + len - 10, "postmaster") == 0)
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|| (len >= 14 && strcmp(argv[0] + len - 14, "postmaster.exe") == 0)
|
|| (len >= 14 && strcmp(argv[0] + len - 14, "postmaster.exe") == 0)
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -264,9 +266,11 @@ main(int argc, char *argv[])
|
|||||||
exit(BootstrapMain(argc - 1, argv + 1));
|
exit(BootstrapMain(argc - 1, argv + 1));
|
||||||
|
|
||||||
#ifdef EXEC_BACKEND
|
#ifdef EXEC_BACKEND
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the first argument is "-forkexec", then invoke SubPostmasterMain. Note
|
* If the first argument is "-forkexec", then invoke
|
||||||
* we remove "-forkexec" from the arguments passed on to SubPostmasterMain.
|
* SubPostmasterMain. Note we remove "-forkexec" from the arguments
|
||||||
|
* passed on to SubPostmasterMain.
|
||||||
*/
|
*/
|
||||||
if (argc > 1 && strcmp(argv[1], "-forkexec") == 0)
|
if (argc > 1 && strcmp(argv[1], "-forkexec") == 0)
|
||||||
{
|
{
|
||||||
@ -275,16 +279,16 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the first argument is "-statBuf", then invoke pgstat_main.
|
* If the first argument is "-statBuf", then invoke pgstat_main.
|
||||||
*/
|
*/
|
||||||
if (argc > 1 && strcmp(argv[1], "-statBuf") == 0)
|
if (argc > 1 && strcmp(argv[1], "-statBuf") == 0)
|
||||||
{
|
{
|
||||||
pgstat_main(argc , argv);
|
pgstat_main(argc, argv);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the first argument is "-statCol", then invoke pgstat_mainChild.
|
* If the first argument is "-statCol", then invoke pgstat_mainChild.
|
||||||
*/
|
*/
|
||||||
if (argc > 1 && strcmp(argv[1], "-statCol") == 0)
|
if (argc > 1 && strcmp(argv[1], "-statCol") == 0)
|
||||||
{
|
{
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.395 2004/05/26 18:35:35 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.396 2004/05/27 15:07:41 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -180,6 +180,7 @@ static int ListenSocket[MAXLISTEN];
|
|||||||
/* Used to reduce macros tests */
|
/* Used to reduce macros tests */
|
||||||
#ifdef EXEC_BACKEND
|
#ifdef EXEC_BACKEND
|
||||||
const bool ExecBackend = true;
|
const bool ExecBackend = true;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
const bool ExecBackend = false;
|
const bool ExecBackend = false;
|
||||||
#endif
|
#endif
|
||||||
@ -270,7 +271,7 @@ static void CleanupProc(int pid, int exitstatus);
|
|||||||
static void LogChildExit(int lev, const char *procname,
|
static void LogChildExit(int lev, const char *procname,
|
||||||
int pid, int exitstatus);
|
int pid, int exitstatus);
|
||||||
static void BackendInit(Port *port);
|
static void BackendInit(Port *port);
|
||||||
static int BackendRun(Port *port);
|
static int BackendRun(Port *port);
|
||||||
static void ExitPostmaster(int status);
|
static void ExitPostmaster(int status);
|
||||||
static void usage(const char *);
|
static void usage(const char *);
|
||||||
static int ServerLoop(void);
|
static int ServerLoop(void);
|
||||||
@ -295,14 +296,14 @@ __attribute__((format(printf, 1, 2)));
|
|||||||
#ifdef EXEC_BACKEND
|
#ifdef EXEC_BACKEND
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
pid_t win32_forkexec(const char* path, char *argv[]);
|
pid_t win32_forkexec(const char *path, char *argv[]);
|
||||||
|
|
||||||
static void win32_AddChild(pid_t pid, HANDLE handle);
|
static void win32_AddChild(pid_t pid, HANDLE handle);
|
||||||
static void win32_RemoveChild(pid_t pid);
|
static void win32_RemoveChild(pid_t pid);
|
||||||
static pid_t win32_waitpid(int *exitstatus);
|
static pid_t win32_waitpid(int *exitstatus);
|
||||||
static DWORD WINAPI win32_sigchld_waiter(LPVOID param);
|
static DWORD WINAPI win32_sigchld_waiter(LPVOID param);
|
||||||
|
|
||||||
static pid_t *win32_childPIDArray;
|
static pid_t *win32_childPIDArray;
|
||||||
static HANDLE *win32_childHNDArray;
|
static HANDLE *win32_childHNDArray;
|
||||||
static unsigned long win32_numChildren = 0;
|
static unsigned long win32_numChildren = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -310,16 +311,16 @@ static unsigned long win32_numChildren = 0;
|
|||||||
static pid_t Backend_forkexec(Port *port);
|
static pid_t Backend_forkexec(Port *port);
|
||||||
|
|
||||||
static unsigned long tmpBackendFileNum = 0;
|
static unsigned long tmpBackendFileNum = 0;
|
||||||
void read_backend_variables(unsigned long id, Port *port);
|
void read_backend_variables(unsigned long id, Port *port);
|
||||||
static bool write_backend_variables(Port *port);
|
static bool write_backend_variables(Port *port);
|
||||||
|
|
||||||
static void ShmemBackendArrayAdd(Backend *bn);
|
static void ShmemBackendArrayAdd(Backend *bn);
|
||||||
static void ShmemBackendArrayRemove(pid_t pid);
|
static void ShmemBackendArrayRemove(pid_t pid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define StartupDataBase() SSDataBase(BS_XLOG_STARTUP)
|
#define StartupDataBase() SSDataBase(BS_XLOG_STARTUP)
|
||||||
#define CheckPointDataBase() SSDataBase(BS_XLOG_CHECKPOINT)
|
#define CheckPointDataBase() SSDataBase(BS_XLOG_CHECKPOINT)
|
||||||
#define StartBackgroundWriter() SSDataBase(BS_XLOG_BGWRITER)
|
#define StartBackgroundWriter() SSDataBase(BS_XLOG_BGWRITER)
|
||||||
#define ShutdownDataBase() SSDataBase(BS_XLOG_SHUTDOWN)
|
#define ShutdownDataBase() SSDataBase(BS_XLOG_SHUTDOWN)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -462,9 +463,9 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
|
|
||||||
if (find_my_exec(argv[0], my_exec_path) < 0)
|
if (find_my_exec(argv[0], my_exec_path) < 0)
|
||||||
elog(FATAL,
|
elog(FATAL,
|
||||||
gettext("%s: could not locate my own executable path"),
|
gettext("%s: could not locate my own executable path"),
|
||||||
argv[0]);
|
argv[0]);
|
||||||
|
|
||||||
get_pkglib_path(my_exec_path, pkglib_path);
|
get_pkglib_path(my_exec_path, pkglib_path);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -610,7 +611,7 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
gettext("Try \"%s --help\" for more information.\n"),
|
gettext("Try \"%s --help\" for more information.\n"),
|
||||||
progname);
|
progname);
|
||||||
ExitPostmaster(1);
|
ExitPostmaster(1);
|
||||||
}
|
}
|
||||||
@ -635,7 +636,7 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
SetDataDir(potential_DataDir);
|
SetDataDir(potential_DataDir);
|
||||||
|
|
||||||
ProcessConfigFile(PGC_POSTMASTER);
|
ProcessConfigFile(PGC_POSTMASTER);
|
||||||
|
|
||||||
/* If timezone is not set, determine what the OS uses */
|
/* If timezone is not set, determine what the OS uses */
|
||||||
pg_timezone_initialize();
|
pg_timezone_initialize();
|
||||||
|
|
||||||
@ -687,15 +688,15 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
char **p;
|
char **p;
|
||||||
|
|
||||||
ereport(DEBUG3,
|
ereport(DEBUG3,
|
||||||
(errmsg_internal("%s: PostmasterMain: initial environ dump:",
|
(errmsg_internal("%s: PostmasterMain: initial environ dump:",
|
||||||
progname)));
|
progname)));
|
||||||
ereport(DEBUG3,
|
ereport(DEBUG3,
|
||||||
(errmsg_internal("-----------------------------------------")));
|
(errmsg_internal("-----------------------------------------")));
|
||||||
for (p = environ; *p; ++p)
|
for (p = environ; *p; ++p)
|
||||||
ereport(DEBUG3,
|
ereport(DEBUG3,
|
||||||
(errmsg_internal("\t%s", *p)));
|
(errmsg_internal("\t%s", *p)));
|
||||||
ereport(DEBUG3,
|
ereport(DEBUG3,
|
||||||
(errmsg_internal("-----------------------------------------")));
|
(errmsg_internal("-----------------------------------------")));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EXEC_BACKEND
|
#ifdef EXEC_BACKEND
|
||||||
@ -704,7 +705,7 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
(errmsg("%s: could not locate postgres executable or non-matching version",
|
(errmsg("%s: could not locate postgres executable or non-matching version",
|
||||||
progname)));
|
progname)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize SSL library, if specified.
|
* Initialize SSL library, if specified.
|
||||||
*/
|
*/
|
||||||
@ -772,7 +773,7 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
endptr++;
|
endptr++;
|
||||||
c = *endptr;
|
c = *endptr;
|
||||||
*endptr = '\0';
|
*endptr = '\0';
|
||||||
if (strcmp(curhost,"*") == 0)
|
if (strcmp(curhost, "*") == 0)
|
||||||
status = StreamServerPort(AF_UNSPEC, NULL,
|
status = StreamServerPort(AF_UNSPEC, NULL,
|
||||||
(unsigned short) PostPortNumber,
|
(unsigned short) PostPortNumber,
|
||||||
UnixSocketDir,
|
UnixSocketDir,
|
||||||
@ -784,11 +785,11 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
ListenSocket, MAXLISTEN);
|
ListenSocket, MAXLISTEN);
|
||||||
if (status != STATUS_OK)
|
if (status != STATUS_OK)
|
||||||
ereport(WARNING,
|
ereport(WARNING,
|
||||||
(errmsg("could not create listen socket for \"%s\"",
|
(errmsg("could not create listen socket for \"%s\"",
|
||||||
curhost)));
|
curhost)));
|
||||||
*endptr = c;
|
*endptr = c;
|
||||||
if (c != '\0')
|
if (c != '\0')
|
||||||
curhost = endptr+1;
|
curhost = endptr + 1;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -803,7 +804,7 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
"",
|
"",
|
||||||
htonl(PostPortNumber),
|
htonl(PostPortNumber),
|
||||||
"",
|
"",
|
||||||
(DNSServiceRegistrationReply) reg_reply,
|
(DNSServiceRegistrationReply) reg_reply,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -833,8 +834,9 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
reset_shared(PostPortNumber);
|
reset_shared(PostPortNumber);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Estimate number of openable files. This must happen after setting up
|
* Estimate number of openable files. This must happen after setting
|
||||||
* semaphores, because on some platforms semaphores count as open files.
|
* up semaphores, because on some platforms semaphores count as open
|
||||||
|
* files.
|
||||||
*/
|
*/
|
||||||
set_max_safe_fds();
|
set_max_safe_fds();
|
||||||
|
|
||||||
@ -844,11 +846,12 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
BackendList = DLNewList();
|
BackendList = DLNewList();
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the child pid/HANDLE arrays
|
* Initialize the child pid/HANDLE arrays
|
||||||
*/
|
*/
|
||||||
win32_childPIDArray = (pid_t*)malloc(NUM_BACKENDARRAY_ELEMS*sizeof(pid_t));
|
win32_childPIDArray = (pid_t *) malloc(NUM_BACKENDARRAY_ELEMS * sizeof(pid_t));
|
||||||
win32_childHNDArray = (HANDLE*)malloc(NUM_BACKENDARRAY_ELEMS*sizeof(HANDLE));
|
win32_childHNDArray = (HANDLE *) malloc(NUM_BACKENDARRAY_ELEMS * sizeof(HANDLE));
|
||||||
if (!win32_childPIDArray || !win32_childHNDArray)
|
if (!win32_childPIDArray || !win32_childHNDArray)
|
||||||
ereport(FATAL,
|
ereport(FATAL,
|
||||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||||
@ -947,7 +950,7 @@ pmdaemonize(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/* not supported */
|
/* not supported */
|
||||||
elog(FATAL,"SilentMode not supported under WIN32");
|
elog(FATAL, "SilentMode not supported under WIN32");
|
||||||
#else
|
#else
|
||||||
int i;
|
int i;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@ -1105,16 +1108,14 @@ ServerLoop(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If no background writer process is running and we should
|
* If no background writer process is running and we should do
|
||||||
* do background writing, start one. It doesn't matter if
|
* background writing, start one. It doesn't matter if this fails,
|
||||||
* this fails, we'll just try again later.
|
* we'll just try again later.
|
||||||
*/
|
*/
|
||||||
if (BgWriterPID == 0 && BgWriterPercent > 0 &&
|
if (BgWriterPID == 0 && BgWriterPercent > 0 &&
|
||||||
StartupPID == 0 && Shutdown == NoShutdown &&
|
StartupPID == 0 && Shutdown == NoShutdown &&
|
||||||
!FatalError && random_seed != 0)
|
!FatalError && random_seed != 0)
|
||||||
{
|
|
||||||
BgWriterPID = StartBackgroundWriter();
|
BgWriterPID = StartBackgroundWriter();
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait for something to happen.
|
* Wait for something to happen.
|
||||||
@ -1349,7 +1350,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
|
|||||||
* Now fetch parameters out of startup packet and save them into the
|
* Now fetch parameters out of startup packet and save them into the
|
||||||
* Port structure. All data structures attached to the Port struct
|
* Port structure. All data structures attached to the Port struct
|
||||||
* must be allocated in TopMemoryContext so that they won't disappear
|
* must be allocated in TopMemoryContext so that they won't disappear
|
||||||
* when we pass them to PostgresMain (see BackendRun). We need not
|
* when we pass them to PostgresMain (see BackendRun). We need not
|
||||||
* worry about leaking this storage on failure, since we aren't in the
|
* worry about leaking this storage on failure, since we aren't in the
|
||||||
* postmaster process anymore.
|
* postmaster process anymore.
|
||||||
*/
|
*/
|
||||||
@ -1523,10 +1524,12 @@ processCancelRequest(Port *port, void *pkt)
|
|||||||
int backendPID;
|
int backendPID;
|
||||||
long cancelAuthCode;
|
long cancelAuthCode;
|
||||||
Backend *bp;
|
Backend *bp;
|
||||||
|
|
||||||
#ifndef EXEC_BACKEND
|
#ifndef EXEC_BACKEND
|
||||||
Dlelem *curr;
|
Dlelem *curr;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
int i;
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
backendPID = (int) ntohl(canc->backendPID);
|
backendPID = (int) ntohl(canc->backendPID);
|
||||||
@ -1555,7 +1558,7 @@ processCancelRequest(Port *port, void *pkt)
|
|||||||
#else
|
#else
|
||||||
for (i = 0; i < NUM_BACKENDARRAY_ELEMS; i++)
|
for (i = 0; i < NUM_BACKENDARRAY_ELEMS; i++)
|
||||||
{
|
{
|
||||||
bp = (Backend*) &ShmemBackendArray[i];
|
bp = (Backend *) &ShmemBackendArray[i];
|
||||||
#endif
|
#endif
|
||||||
if (bp->pid == backendPID)
|
if (bp->pid == backendPID)
|
||||||
{
|
{
|
||||||
@ -1733,8 +1736,8 @@ SIGHUP_handler(SIGNAL_ARGS)
|
|||||||
load_ident();
|
load_ident();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tell the background writer to terminate so that we
|
* Tell the background writer to terminate so that we will start a
|
||||||
* will start a new one with a possibly changed config
|
* new one with a possibly changed config
|
||||||
*/
|
*/
|
||||||
if (BgWriterPID != 0)
|
if (BgWriterPID != 0)
|
||||||
kill(BgWriterPID, SIGTERM);
|
kill(BgWriterPID, SIGTERM);
|
||||||
@ -1829,8 +1832,8 @@ pmdie(SIGNAL_ARGS)
|
|||||||
* No children left. Shutdown data base system.
|
* No children left. Shutdown data base system.
|
||||||
*
|
*
|
||||||
* Unlike the previous case, it is not an error for the shutdown
|
* Unlike the previous case, it is not an error for the shutdown
|
||||||
* process to be running already (we could get SIGTERM followed
|
* process to be running already (we could get SIGTERM
|
||||||
* shortly later by SIGINT).
|
* followed shortly later by SIGINT).
|
||||||
*/
|
*/
|
||||||
if (StartupPID > 0 || FatalError) /* let reaper() handle
|
if (StartupPID > 0 || FatalError) /* let reaper() handle
|
||||||
* this */
|
* this */
|
||||||
@ -1874,6 +1877,7 @@ reaper(SIGNAL_ARGS)
|
|||||||
|
|
||||||
#ifdef HAVE_WAITPID
|
#ifdef HAVE_WAITPID
|
||||||
int status; /* backend exit status */
|
int status; /* backend exit status */
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
union wait status; /* backend exit status */
|
union wait status; /* backend exit status */
|
||||||
@ -1899,10 +1903,10 @@ reaper(SIGNAL_ARGS)
|
|||||||
while ((pid = win32_waitpid(&exitstatus)) > 0)
|
while ((pid = win32_waitpid(&exitstatus)) > 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We need to do this here, and not in CleanupProc, since this
|
* We need to do this here, and not in CleanupProc, since this is
|
||||||
* is to be called on all children when we are done with them.
|
* to be called on all children when we are done with them. Could
|
||||||
* Could move to LogChildExit, but that seems like asking for
|
* move to LogChildExit, but that seems like asking for future
|
||||||
* future trouble...
|
* trouble...
|
||||||
*/
|
*/
|
||||||
win32_RemoveChild(pid);
|
win32_RemoveChild(pid);
|
||||||
#endif
|
#endif
|
||||||
@ -2087,7 +2091,7 @@ CleanupProc(int pid,
|
|||||||
if (!FatalError)
|
if (!FatalError)
|
||||||
{
|
{
|
||||||
LogChildExit(LOG,
|
LogChildExit(LOG,
|
||||||
(pid == CheckPointPID) ? gettext("checkpoint process") :
|
(pid == CheckPointPID) ? gettext("checkpoint process") :
|
||||||
(pid == BgWriterPID) ? gettext("bgwriter process") :
|
(pid == BgWriterPID) ? gettext("bgwriter process") :
|
||||||
gettext("server process"),
|
gettext("server process"),
|
||||||
pid, exitstatus);
|
pid, exitstatus);
|
||||||
@ -2115,7 +2119,7 @@ CleanupProc(int pid,
|
|||||||
{
|
{
|
||||||
ereport(DEBUG2,
|
ereport(DEBUG2,
|
||||||
(errmsg_internal("sending %s to process %d",
|
(errmsg_internal("sending %s to process %d",
|
||||||
(SendStop ? "SIGSTOP" : "SIGQUIT"),
|
(SendStop ? "SIGSTOP" : "SIGQUIT"),
|
||||||
(int) bp->pid)));
|
(int) bp->pid)));
|
||||||
kill(bp->pid, (SendStop ? SIGSTOP : SIGQUIT));
|
kill(bp->pid, (SendStop ? SIGSTOP : SIGQUIT));
|
||||||
}
|
}
|
||||||
@ -2141,9 +2145,7 @@ CleanupProc(int pid,
|
|||||||
checkpointed = 0;
|
checkpointed = 0;
|
||||||
}
|
}
|
||||||
else if (pid == BgWriterPID)
|
else if (pid == BgWriterPID)
|
||||||
{
|
|
||||||
BgWriterPID = 0;
|
BgWriterPID = 0;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -2398,8 +2400,8 @@ split_opts(char **argv, int *argcp, char *s)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* BackendInit/Run -- perform authentication [BackendInit], and if successful,
|
* BackendInit/Run -- perform authentication [BackendInit], and if successful,
|
||||||
* set up the backend's argument list [BackendRun] and invoke
|
* set up the backend's argument list [BackendRun] and invoke
|
||||||
* backend main()
|
* backend main()
|
||||||
*
|
*
|
||||||
* returns:
|
* returns:
|
||||||
* Shouldn't return at all.
|
* Shouldn't return at all.
|
||||||
@ -2427,7 +2429,7 @@ BackendInit(Port *port)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* save start time for end of session reporting */
|
/* save start time for end of session reporting */
|
||||||
gettimeofday(&(port->session_start),NULL);
|
gettimeofday(&(port->session_start), NULL);
|
||||||
|
|
||||||
/* set these to empty in case they are needed before we set them up */
|
/* set these to empty in case they are needed before we set them up */
|
||||||
port->remote_host = "";
|
port->remote_host = "";
|
||||||
@ -2469,14 +2471,15 @@ BackendInit(Port *port)
|
|||||||
remote_port, sizeof(remote_port),
|
remote_port, sizeof(remote_port),
|
||||||
(log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV))
|
(log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV))
|
||||||
{
|
{
|
||||||
int ret = getnameinfo_all(&port->raddr.addr, port->raddr.salen,
|
int ret = getnameinfo_all(&port->raddr.addr, port->raddr.salen,
|
||||||
remote_host, sizeof(remote_host),
|
remote_host, sizeof(remote_host),
|
||||||
remote_port, sizeof(remote_port),
|
remote_port, sizeof(remote_port),
|
||||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
ereport(WARNING,
|
ereport(WARNING,
|
||||||
(errmsg("getnameinfo_all() failed: %s",
|
(errmsg("getnameinfo_all() failed: %s",
|
||||||
gai_strerror(ret))));
|
gai_strerror(ret))));
|
||||||
}
|
}
|
||||||
snprintf(remote_ps_data, sizeof(remote_ps_data),
|
snprintf(remote_ps_data, sizeof(remote_ps_data),
|
||||||
remote_port[0] == '\0' ? "%s" : "%s(%s)",
|
remote_port[0] == '\0' ? "%s" : "%s(%s)",
|
||||||
@ -2558,8 +2561,8 @@ BackendRun(Port *port)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Let's clean up ourselves as the postmaster child, and
|
* Let's clean up ourselves as the postmaster child, and close the
|
||||||
* close the postmaster's other sockets
|
* postmaster's other sockets
|
||||||
*/
|
*/
|
||||||
ClosePostmasterPorts(true);
|
ClosePostmasterPorts(true);
|
||||||
|
|
||||||
@ -2571,7 +2574,7 @@ BackendRun(Port *port)
|
|||||||
* PGOPTIONS, but it is not honored until after authentication.)
|
* PGOPTIONS, but it is not honored until after authentication.)
|
||||||
*/
|
*/
|
||||||
if (PreAuthDelay > 0)
|
if (PreAuthDelay > 0)
|
||||||
pg_usleep(PreAuthDelay*1000000L);
|
pg_usleep(PreAuthDelay * 1000000L);
|
||||||
|
|
||||||
/* Will exit on failure */
|
/* Will exit on failure */
|
||||||
BackendInit(port);
|
BackendInit(port);
|
||||||
@ -2686,12 +2689,12 @@ BackendRun(Port *port)
|
|||||||
* Shouldn't return at all.
|
* Shouldn't return at all.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SubPostmasterMain(int argc, char* argv[])
|
SubPostmasterMain(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
unsigned long backendID;
|
unsigned long backendID;
|
||||||
Port port;
|
Port port;
|
||||||
|
|
||||||
memset((void*)&port, 0, sizeof(Port));
|
memset((void *) &port, 0, sizeof(Port));
|
||||||
Assert(argc == 2);
|
Assert(argc == 2);
|
||||||
|
|
||||||
/* Do this sooner rather than later... */
|
/* Do this sooner rather than later... */
|
||||||
@ -2707,11 +2710,11 @@ SubPostmasterMain(int argc, char* argv[])
|
|||||||
|
|
||||||
/* Parse passed-in context */
|
/* Parse passed-in context */
|
||||||
argc = 0;
|
argc = 0;
|
||||||
backendID = (unsigned long)atol(argv[argc++]);
|
backendID = (unsigned long) atol(argv[argc++]);
|
||||||
DataDir = strdup(argv[argc++]);
|
DataDir = strdup(argv[argc++]);
|
||||||
|
|
||||||
/* Read in file-based context */
|
/* Read in file-based context */
|
||||||
read_backend_variables(backendID,&port);
|
read_backend_variables(backendID, &port);
|
||||||
read_nondefault_variables();
|
read_nondefault_variables();
|
||||||
|
|
||||||
/* Remaining initialization */
|
/* Remaining initialization */
|
||||||
@ -2740,20 +2743,22 @@ SubPostmasterMain(int argc, char* argv[])
|
|||||||
static pid_t
|
static pid_t
|
||||||
Backend_forkexec(Port *port)
|
Backend_forkexec(Port *port)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char *av[5];
|
char *av[5];
|
||||||
int ac = 0, bufc = 0, i;
|
int ac = 0,
|
||||||
char buf[2][MAXPGPATH];
|
bufc = 0,
|
||||||
|
i;
|
||||||
|
char buf[2][MAXPGPATH];
|
||||||
|
|
||||||
if (!write_backend_variables(port))
|
if (!write_backend_variables(port))
|
||||||
return -1; /* log made by write_backend_variables */
|
return -1; /* log made by write_backend_variables */
|
||||||
|
|
||||||
av[ac++] = "postgres";
|
av[ac++] = "postgres";
|
||||||
av[ac++] = "-forkexec";
|
av[ac++] = "-forkexec";
|
||||||
|
|
||||||
/* Format up context to pass to exec'd process */
|
/* Format up context to pass to exec'd process */
|
||||||
snprintf(buf[bufc++],MAXPGPATH,"%lu",tmpBackendFileNum);
|
snprintf(buf[bufc++], MAXPGPATH, "%lu", tmpBackendFileNum);
|
||||||
snprintf(buf[bufc++],MAXPGPATH,"\"%s\"",DataDir);
|
snprintf(buf[bufc++], MAXPGPATH, "\"%s\"", DataDir);
|
||||||
|
|
||||||
/* Add to the arg list */
|
/* Add to the arg list */
|
||||||
Assert(bufc <= lengthof(buf));
|
Assert(bufc <= lengthof(buf));
|
||||||
@ -2762,23 +2767,23 @@ Backend_forkexec(Port *port)
|
|||||||
|
|
||||||
/* FIXME: [fork/exec] ExtraOptions? */
|
/* FIXME: [fork/exec] ExtraOptions? */
|
||||||
|
|
||||||
av[ac++] = NULL;
|
av[ac++] = NULL;
|
||||||
Assert(ac <= lengthof(av));
|
Assert(ac <= lengthof(av));
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
pid = win32_forkexec(postgres_exec_path, av); /* logs on error */
|
pid = win32_forkexec(postgres_exec_path, av); /* logs on error */
|
||||||
#else
|
#else
|
||||||
/* Fire off execv in child */
|
/* Fire off execv in child */
|
||||||
if ((pid = fork()) == 0 && (execv(postgres_exec_path, av) == -1))
|
if ((pid = fork()) == 0 && (execv(postgres_exec_path, av) == -1))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: [fork/exec] suggestions for what to do here?
|
* FIXME: [fork/exec] suggestions for what to do here? Probably OK
|
||||||
* Probably OK to issue error (unlike pgstat case)
|
* to issue error (unlike pgstat case)
|
||||||
*/
|
*/
|
||||||
abort();
|
abort();
|
||||||
#endif
|
#endif
|
||||||
return pid; /* Parent returns pid */
|
return pid; /* Parent returns pid */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -2833,7 +2838,7 @@ sigusr1_handler(SIGNAL_ARGS)
|
|||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errmsg("checkpoints are occurring too frequently (%d seconds apart)",
|
(errmsg("checkpoints are occurring too frequently (%d seconds apart)",
|
||||||
elapsed_secs),
|
elapsed_secs),
|
||||||
errhint("Consider increasing the configuration parameter \"checkpoint_segments\".")));
|
errhint("Consider increasing the configuration parameter \"checkpoint_segments\".")));
|
||||||
}
|
}
|
||||||
LastSignalledCheckpoint = now;
|
LastSignalledCheckpoint = now;
|
||||||
}
|
}
|
||||||
@ -2865,8 +2870,9 @@ sigusr1_handler(SIGNAL_ARGS)
|
|||||||
if (CheckPostmasterSignal(PMSIGNAL_WAKEN_CHILDREN))
|
if (CheckPostmasterSignal(PMSIGNAL_WAKEN_CHILDREN))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Send SIGUSR1 to all children (triggers CatchupInterruptHandler).
|
* Send SIGUSR1 to all children (triggers
|
||||||
* See storage/ipc/sinval[adt].c for the use of this.
|
* CatchupInterruptHandler). See storage/ipc/sinval[adt].c for the
|
||||||
|
* use of this.
|
||||||
*/
|
*/
|
||||||
if (Shutdown == NoShutdown)
|
if (Shutdown == NoShutdown)
|
||||||
SignalChildren(SIGUSR1);
|
SignalChildren(SIGUSR1);
|
||||||
@ -2999,8 +3005,7 @@ SSDataBaseInit(int xlop)
|
|||||||
{
|
{
|
||||||
const char *statmsg;
|
const char *statmsg;
|
||||||
|
|
||||||
IsUnderPostmaster = true; /* we are a postmaster subprocess
|
IsUnderPostmaster = true; /* we are a postmaster subprocess now */
|
||||||
* now */
|
|
||||||
|
|
||||||
#ifdef EXEC_BACKEND
|
#ifdef EXEC_BACKEND
|
||||||
/* In EXEC case we will not have inherited these settings */
|
/* In EXEC case we will not have inherited these settings */
|
||||||
@ -3044,6 +3049,7 @@ SSDataBase(int xlop)
|
|||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
Backend *bn;
|
Backend *bn;
|
||||||
|
|
||||||
#ifndef EXEC_BACKEND
|
#ifndef EXEC_BACKEND
|
||||||
#ifdef LINUX_PROFILE
|
#ifdef LINUX_PROFILE
|
||||||
struct itimerval prof_itimer;
|
struct itimerval prof_itimer;
|
||||||
@ -3092,7 +3098,7 @@ SSDataBase(int xlop)
|
|||||||
SSDataBaseInit(xlop);
|
SSDataBaseInit(xlop);
|
||||||
#else
|
#else
|
||||||
if (!write_backend_variables(NULL))
|
if (!write_backend_variables(NULL))
|
||||||
return -1; /* log issued by write_backend_variables */
|
return -1; /* log issued by write_backend_variables */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set up command-line arguments for subprocess */
|
/* Set up command-line arguments for subprocess */
|
||||||
@ -3128,7 +3134,7 @@ SSDataBase(int xlop)
|
|||||||
#ifdef EXEC_BACKEND
|
#ifdef EXEC_BACKEND
|
||||||
/* EXEC_BACKEND case; fork/exec here */
|
/* EXEC_BACKEND case; fork/exec here */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
pid = win32_forkexec(postgres_exec_path, av); /* logs on error */
|
pid = win32_forkexec(postgres_exec_path, av); /* logs on error */
|
||||||
#else
|
#else
|
||||||
if ((pid = fork()) == 0 && (execv(postgres_exec_path, av) == -1))
|
if ((pid = fork()) == 0 && (execv(postgres_exec_path, av) == -1))
|
||||||
{
|
{
|
||||||
@ -3164,7 +3170,7 @@ SSDataBase(int xlop)
|
|||||||
break;
|
break;
|
||||||
case BS_XLOG_BGWRITER:
|
case BS_XLOG_BGWRITER:
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
(errmsg("could not fork bgwriter process: %m")));
|
(errmsg("could not fork bgwriter process: %m")));
|
||||||
break;
|
break;
|
||||||
case BS_XLOG_SHUTDOWN:
|
case BS_XLOG_SHUTDOWN:
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
@ -3190,8 +3196,8 @@ SSDataBase(int xlop)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The startup and shutdown processes are not considered normal
|
* The startup and shutdown processes are not considered normal
|
||||||
* backends, but the checkpoint and bgwriter processes are.
|
* backends, but the checkpoint and bgwriter processes are. They must
|
||||||
* They must be added to the list of backends.
|
* be added to the list of backends.
|
||||||
*/
|
*/
|
||||||
if (xlop == BS_XLOG_CHECKPOINT || xlop == BS_XLOG_BGWRITER)
|
if (xlop == BS_XLOG_CHECKPOINT || xlop == BS_XLOG_BGWRITER)
|
||||||
{
|
{
|
||||||
@ -3288,7 +3294,7 @@ extern slock_t *ShmemIndexLock;
|
|||||||
extern void *ShmemIndexAlloc;
|
extern void *ShmemIndexAlloc;
|
||||||
typedef struct LWLock LWLock;
|
typedef struct LWLock LWLock;
|
||||||
extern LWLock *LWLockArray;
|
extern LWLock *LWLockArray;
|
||||||
extern slock_t *ProcStructLock;
|
extern slock_t *ProcStructLock;
|
||||||
extern int pgStatSock;
|
extern int pgStatSock;
|
||||||
|
|
||||||
#define write_var(var,fp) fwrite((void*)&(var),sizeof(var),1,fp)
|
#define write_var(var,fp) fwrite((void*)&(var),sizeof(var),1,fp)
|
||||||
@ -3297,7 +3303,7 @@ extern int pgStatSock;
|
|||||||
do { \
|
do { \
|
||||||
Assert(DataDir); \
|
Assert(DataDir); \
|
||||||
sprintf((buf), \
|
sprintf((buf), \
|
||||||
"%s/%s/%s.backend_var.%lu", \
|
"%s/%s/%s.backend_var.%lu", \
|
||||||
DataDir, \
|
DataDir, \
|
||||||
PG_TEMP_FILES_DIR, \
|
PG_TEMP_FILES_DIR, \
|
||||||
PG_TEMP_FILE_PREFIX, \
|
PG_TEMP_FILE_PREFIX, \
|
||||||
@ -3307,24 +3313,26 @@ extern int pgStatSock;
|
|||||||
static bool
|
static bool
|
||||||
write_backend_variables(Port *port)
|
write_backend_variables(Port *port)
|
||||||
{
|
{
|
||||||
char filename[MAXPGPATH];
|
char filename[MAXPGPATH];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
get_tmp_backend_file_name(filename,++tmpBackendFileNum);
|
|
||||||
|
get_tmp_backend_file_name(filename, ++tmpBackendFileNum);
|
||||||
|
|
||||||
/* Open file */
|
/* Open file */
|
||||||
fp = AllocateFile(filename, PG_BINARY_W);
|
fp = AllocateFile(filename, PG_BINARY_W);
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
/* As per OpenTemporaryFile... */
|
/* As per OpenTemporaryFile... */
|
||||||
char dirname[MAXPGPATH];
|
char dirname[MAXPGPATH];
|
||||||
sprintf(dirname,"%s/%s",DataDir,PG_TEMP_FILES_DIR);
|
|
||||||
|
sprintf(dirname, "%s/%s", DataDir, PG_TEMP_FILES_DIR);
|
||||||
mkdir(dirname, S_IRWXU);
|
mkdir(dirname, S_IRWXU);
|
||||||
|
|
||||||
fp = AllocateFile(filename, PG_BINARY_W);
|
fp = AllocateFile(filename, PG_BINARY_W);
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode_for_file_access(),
|
(errcode_for_file_access(),
|
||||||
errmsg("could not write to file \"%s\": %m", filename)));
|
errmsg("could not write to file \"%s\": %m", filename)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3333,37 +3341,37 @@ write_backend_variables(Port *port)
|
|||||||
/* Write vars */
|
/* Write vars */
|
||||||
if (port)
|
if (port)
|
||||||
{
|
{
|
||||||
write_var(port->sock,fp);
|
write_var(port->sock, fp);
|
||||||
write_var(port->proto,fp);
|
write_var(port->proto, fp);
|
||||||
write_var(port->laddr,fp);
|
write_var(port->laddr, fp);
|
||||||
write_var(port->raddr,fp);
|
write_var(port->raddr, fp);
|
||||||
write_var(port->canAcceptConnections,fp);
|
write_var(port->canAcceptConnections, fp);
|
||||||
write_var(port->cryptSalt,fp);
|
write_var(port->cryptSalt, fp);
|
||||||
write_var(port->md5Salt,fp);
|
write_var(port->md5Salt, fp);
|
||||||
}
|
}
|
||||||
write_var(MyCancelKey,fp);
|
write_var(MyCancelKey, fp);
|
||||||
|
|
||||||
write_var(RedoRecPtr,fp);
|
write_var(RedoRecPtr, fp);
|
||||||
write_var(LogwrtResult,fp);
|
write_var(LogwrtResult, fp);
|
||||||
|
|
||||||
write_var(UsedShmemSegID,fp);
|
write_var(UsedShmemSegID, fp);
|
||||||
write_var(UsedShmemSegAddr,fp);
|
write_var(UsedShmemSegAddr, fp);
|
||||||
|
|
||||||
write_var(ShmemLock,fp);
|
write_var(ShmemLock, fp);
|
||||||
write_var(ShmemIndexLock,fp);
|
write_var(ShmemIndexLock, fp);
|
||||||
write_var(ShmemVariableCache,fp);
|
write_var(ShmemVariableCache, fp);
|
||||||
write_var(ShmemIndexAlloc,fp);
|
write_var(ShmemIndexAlloc, fp);
|
||||||
write_var(ShmemBackendArray,fp);
|
write_var(ShmemBackendArray, fp);
|
||||||
|
|
||||||
write_var(LWLockArray,fp);
|
write_var(LWLockArray, fp);
|
||||||
write_var(ProcStructLock,fp);
|
write_var(ProcStructLock, fp);
|
||||||
write_var(pgStatSock,fp);
|
write_var(pgStatSock, fp);
|
||||||
|
|
||||||
write_var(PreAuthDelay,fp);
|
write_var(PreAuthDelay, fp);
|
||||||
write_var(debug_flag,fp);
|
write_var(debug_flag, fp);
|
||||||
write_var(PostmasterPid,fp);
|
write_var(PostmasterPid, fp);
|
||||||
|
|
||||||
fwrite((void *)my_exec_path, MAXPGPATH, 1, fp);
|
fwrite((void *) my_exec_path, MAXPGPATH, 1, fp);
|
||||||
|
|
||||||
/* Release file */
|
/* Release file */
|
||||||
if (FreeFile(fp))
|
if (FreeFile(fp))
|
||||||
@ -3380,54 +3388,55 @@ write_backend_variables(Port *port)
|
|||||||
void
|
void
|
||||||
read_backend_variables(unsigned long id, Port *port)
|
read_backend_variables(unsigned long id, Port *port)
|
||||||
{
|
{
|
||||||
char filename[MAXPGPATH];
|
char filename[MAXPGPATH];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
get_tmp_backend_file_name(filename,id);
|
|
||||||
|
get_tmp_backend_file_name(filename, id);
|
||||||
|
|
||||||
/* Open file */
|
/* Open file */
|
||||||
fp = AllocateFile(filename, PG_BINARY_R);
|
fp = AllocateFile(filename, PG_BINARY_R);
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode_for_file_access(),
|
(errcode_for_file_access(),
|
||||||
errmsg("could not read from backend_variables file \"%s\": %m", filename)));
|
errmsg("could not read from backend_variables file \"%s\": %m", filename)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read vars */
|
/* Read vars */
|
||||||
if (port)
|
if (port)
|
||||||
{
|
{
|
||||||
read_var(port->sock,fp);
|
read_var(port->sock, fp);
|
||||||
read_var(port->proto,fp);
|
read_var(port->proto, fp);
|
||||||
read_var(port->laddr,fp);
|
read_var(port->laddr, fp);
|
||||||
read_var(port->raddr,fp);
|
read_var(port->raddr, fp);
|
||||||
read_var(port->canAcceptConnections,fp);
|
read_var(port->canAcceptConnections, fp);
|
||||||
read_var(port->cryptSalt,fp);
|
read_var(port->cryptSalt, fp);
|
||||||
read_var(port->md5Salt,fp);
|
read_var(port->md5Salt, fp);
|
||||||
}
|
}
|
||||||
read_var(MyCancelKey,fp);
|
read_var(MyCancelKey, fp);
|
||||||
|
|
||||||
read_var(RedoRecPtr,fp);
|
read_var(RedoRecPtr, fp);
|
||||||
read_var(LogwrtResult,fp);
|
read_var(LogwrtResult, fp);
|
||||||
|
|
||||||
read_var(UsedShmemSegID,fp);
|
read_var(UsedShmemSegID, fp);
|
||||||
read_var(UsedShmemSegAddr,fp);
|
read_var(UsedShmemSegAddr, fp);
|
||||||
|
|
||||||
read_var(ShmemLock,fp);
|
read_var(ShmemLock, fp);
|
||||||
read_var(ShmemIndexLock,fp);
|
read_var(ShmemIndexLock, fp);
|
||||||
read_var(ShmemVariableCache,fp);
|
read_var(ShmemVariableCache, fp);
|
||||||
read_var(ShmemIndexAlloc,fp);
|
read_var(ShmemIndexAlloc, fp);
|
||||||
read_var(ShmemBackendArray,fp);
|
read_var(ShmemBackendArray, fp);
|
||||||
|
|
||||||
read_var(LWLockArray,fp);
|
read_var(LWLockArray, fp);
|
||||||
read_var(ProcStructLock,fp);
|
read_var(ProcStructLock, fp);
|
||||||
read_var(pgStatSock,fp);
|
read_var(pgStatSock, fp);
|
||||||
|
|
||||||
read_var(PreAuthDelay,fp);
|
read_var(PreAuthDelay, fp);
|
||||||
read_var(debug_flag,fp);
|
read_var(debug_flag, fp);
|
||||||
read_var(PostmasterPid,fp);
|
read_var(PostmasterPid, fp);
|
||||||
|
|
||||||
fread((void *)my_exec_path, MAXPGPATH, 1, fp);
|
fread((void *) my_exec_path, MAXPGPATH, 1, fp);
|
||||||
|
|
||||||
/* Release file */
|
/* Release file */
|
||||||
FreeFile(fp);
|
FreeFile(fp);
|
||||||
@ -3438,21 +3447,26 @@ read_backend_variables(unsigned long id, Port *port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t ShmemBackendArraySize(void)
|
size_t
|
||||||
|
ShmemBackendArraySize(void)
|
||||||
{
|
{
|
||||||
return (NUM_BACKENDARRAY_ELEMS*sizeof(Backend));
|
return (NUM_BACKENDARRAY_ELEMS * sizeof(Backend));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShmemBackendArrayAllocation(void)
|
void
|
||||||
|
ShmemBackendArrayAllocation(void)
|
||||||
{
|
{
|
||||||
size_t size = ShmemBackendArraySize();
|
size_t size = ShmemBackendArraySize();
|
||||||
ShmemBackendArray = (Backend*)ShmemAlloc(size);
|
|
||||||
|
ShmemBackendArray = (Backend *) ShmemAlloc(size);
|
||||||
memset(ShmemBackendArray, 0, size);
|
memset(ShmemBackendArray, 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShmemBackendArrayAdd(Backend *bn)
|
static void
|
||||||
|
ShmemBackendArrayAdd(Backend *bn)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NUM_BACKENDARRAY_ELEMS; i++)
|
for (i = 0; i < NUM_BACKENDARRAY_ELEMS; i++)
|
||||||
{
|
{
|
||||||
/* Find an empty slot */
|
/* Find an empty slot */
|
||||||
@ -3467,9 +3481,11 @@ static void ShmemBackendArrayAdd(Backend *bn)
|
|||||||
(errmsg_internal("unable to add backend entry")));
|
(errmsg_internal("unable to add backend entry")));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShmemBackendArrayRemove(pid_t pid)
|
static void
|
||||||
|
ShmemBackendArrayRemove(pid_t pid)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NUM_BACKENDARRAY_ELEMS; i++)
|
for (i = 0; i < NUM_BACKENDARRAY_ELEMS; i++)
|
||||||
{
|
{
|
||||||
if (ShmemBackendArray[i].pid == pid)
|
if (ShmemBackendArray[i].pid == pid)
|
||||||
@ -3484,51 +3500,52 @@ static void ShmemBackendArrayRemove(pid_t pid)
|
|||||||
(errmsg_internal("unable to find backend entry with pid %d",
|
(errmsg_internal("unable to find backend entry with pid %d",
|
||||||
pid)));
|
pid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
pid_t win32_forkexec(const char* path, char *argv[])
|
pid_t
|
||||||
|
win32_forkexec(const char *path, char *argv[])
|
||||||
{
|
{
|
||||||
STARTUPINFO si;
|
STARTUPINFO si;
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
char *p;
|
char *p;
|
||||||
int i;
|
int i;
|
||||||
char cmdLine[MAXPGPATH];
|
char cmdLine[MAXPGPATH];
|
||||||
HANDLE childHandleCopy;
|
HANDLE childHandleCopy;
|
||||||
HANDLE waiterThread;
|
HANDLE waiterThread;
|
||||||
|
|
||||||
/* Format the cmd line */
|
/* Format the cmd line */
|
||||||
snprintf(cmdLine,sizeof(cmdLine),"\"%s\"",path);
|
snprintf(cmdLine, sizeof(cmdLine), "\"%s\"", path);
|
||||||
i = 0;
|
i = 0;
|
||||||
while (argv[++i] != NULL)
|
while (argv[++i] != NULL)
|
||||||
{
|
{
|
||||||
/* FIXME: [fork/exec] some strlen checks might be prudent here */
|
/* FIXME: [fork/exec] some strlen checks might be prudent here */
|
||||||
strcat(cmdLine," ");
|
strcat(cmdLine, " ");
|
||||||
strcat(cmdLine,argv[i]);
|
strcat(cmdLine, argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following snippet can disappear when we consistently
|
* The following snippet can disappear when we consistently use
|
||||||
* use forward slashes.
|
* forward slashes.
|
||||||
*/
|
*/
|
||||||
p = cmdLine;
|
p = cmdLine;
|
||||||
while (*(p++) != '\0')
|
while (*(p++) != '\0')
|
||||||
if (*p == '/') *p = '\\';
|
if (*p == '/')
|
||||||
|
*p = '\\';
|
||||||
|
|
||||||
memset(&pi,0,sizeof(pi));
|
memset(&pi, 0, sizeof(pi));
|
||||||
memset(&si,0,sizeof(si));
|
memset(&si, 0, sizeof(si));
|
||||||
si.cb = sizeof(si);
|
si.cb = sizeof(si);
|
||||||
if (!CreateProcess(NULL,cmdLine,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi))
|
if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
|
||||||
{
|
{
|
||||||
elog(ERROR,"CreateProcess call failed (%i): %m",(int)GetLastError());
|
elog(ERROR, "CreateProcess call failed (%i): %m", (int) GetLastError());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsUnderPostmaster)
|
if (!IsUnderPostmaster)
|
||||||
/* We are the Postmaster creating a child... */
|
/* We are the Postmaster creating a child... */
|
||||||
win32_AddChild(pi.dwProcessId,pi.hProcess);
|
win32_AddChild(pi.dwProcessId, pi.hProcess);
|
||||||
|
|
||||||
if (!DuplicateHandle(GetCurrentProcess(),
|
if (!DuplicateHandle(GetCurrentProcess(),
|
||||||
pi.hProcess,
|
pi.hProcess,
|
||||||
@ -3538,11 +3555,11 @@ pid_t win32_forkexec(const char* path, char *argv[])
|
|||||||
FALSE,
|
FALSE,
|
||||||
DUPLICATE_SAME_ACCESS))
|
DUPLICATE_SAME_ACCESS))
|
||||||
ereport(FATAL,
|
ereport(FATAL,
|
||||||
(errmsg_internal("failed to duplicate child handle: %i",(int)GetLastError())));
|
(errmsg_internal("failed to duplicate child handle: %i", (int) GetLastError())));
|
||||||
waiterThread = CreateThread(NULL, 64*1024, win32_sigchld_waiter, (LPVOID)childHandleCopy, 0, NULL);
|
waiterThread = CreateThread(NULL, 64 * 1024, win32_sigchld_waiter, (LPVOID) childHandleCopy, 0, NULL);
|
||||||
if (!waiterThread)
|
if (!waiterThread)
|
||||||
ereport(FATAL,
|
ereport(FATAL,
|
||||||
(errmsg_internal("failed to create sigchld waiter thread: %i",(int)GetLastError())));
|
(errmsg_internal("failed to create sigchld waiter thread: %i", (int) GetLastError())));
|
||||||
CloseHandle(waiterThread);
|
CloseHandle(waiterThread);
|
||||||
|
|
||||||
if (IsUnderPostmaster)
|
if (IsUnderPostmaster)
|
||||||
@ -3554,15 +3571,16 @@ pid_t win32_forkexec(const char* path, char *argv[])
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: The following three functions must not be interrupted (eg. by signals).
|
* Note: The following three functions must not be interrupted (eg. by signals).
|
||||||
* As the Postgres Win32 signalling architecture (currently) requires polling,
|
* As the Postgres Win32 signalling architecture (currently) requires polling,
|
||||||
* or APC checking functions which aren't used here, this is not an issue.
|
* or APC checking functions which aren't used here, this is not an issue.
|
||||||
*
|
*
|
||||||
* We keep two separate arrays, instead of a single array of pid/HANDLE structs,
|
* We keep two separate arrays, instead of a single array of pid/HANDLE structs,
|
||||||
* to avoid having to re-create a handle array for WaitForMultipleObjects on
|
* to avoid having to re-create a handle array for WaitForMultipleObjects on
|
||||||
* each call to win32_waitpid.
|
* each call to win32_waitpid.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void win32_AddChild(pid_t pid, HANDLE handle)
|
static void
|
||||||
|
win32_AddChild(pid_t pid, HANDLE handle)
|
||||||
{
|
{
|
||||||
Assert(win32_childPIDArray && win32_childHNDArray);
|
Assert(win32_childPIDArray && win32_childHNDArray);
|
||||||
if (win32_numChildren < NUM_BACKENDARRAY_ELEMS)
|
if (win32_numChildren < NUM_BACKENDARRAY_ELEMS)
|
||||||
@ -3577,9 +3595,11 @@ static void win32_AddChild(pid_t pid, HANDLE handle)
|
|||||||
pid)));
|
pid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void win32_RemoveChild(pid_t pid)
|
static void
|
||||||
|
win32_RemoveChild(pid_t pid)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
Assert(win32_childPIDArray && win32_childHNDArray);
|
Assert(win32_childPIDArray && win32_childHNDArray);
|
||||||
|
|
||||||
for (i = 0; i < win32_numChildren; i++)
|
for (i = 0; i < win32_numChildren; i++)
|
||||||
@ -3601,27 +3621,28 @@ static void win32_RemoveChild(pid_t pid)
|
|||||||
pid)));
|
pid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static pid_t win32_waitpid(int *exitstatus)
|
static pid_t
|
||||||
|
win32_waitpid(int *exitstatus)
|
||||||
{
|
{
|
||||||
Assert(win32_childPIDArray && win32_childHNDArray);
|
Assert(win32_childPIDArray && win32_childHNDArray);
|
||||||
elog(DEBUG3,"waiting on %lu children",win32_numChildren);
|
elog(DEBUG3, "waiting on %lu children", win32_numChildren);
|
||||||
|
|
||||||
if (win32_numChildren > 0)
|
if (win32_numChildren > 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Note: Do NOT use WaitForMultipleObjectsEx, as we don't
|
* Note: Do NOT use WaitForMultipleObjectsEx, as we don't want to
|
||||||
* want to run queued APCs here.
|
* run queued APCs here.
|
||||||
*/
|
*/
|
||||||
int index;
|
int index;
|
||||||
DWORD exitCode;
|
DWORD exitCode;
|
||||||
DWORD ret = WaitForMultipleObjects(win32_numChildren,win32_childHNDArray,FALSE,0);
|
DWORD ret = WaitForMultipleObjects(win32_numChildren, win32_childHNDArray, FALSE, 0);
|
||||||
|
|
||||||
switch (ret)
|
switch (ret)
|
||||||
{
|
{
|
||||||
case WAIT_FAILED:
|
case WAIT_FAILED:
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errmsg_internal("failed to wait on %lu children: %i",
|
(errmsg_internal("failed to wait on %lu children: %i",
|
||||||
win32_numChildren,(int)GetLastError())));
|
win32_numChildren, (int) GetLastError())));
|
||||||
/* Fall through to WAIT_TIMEOUTs return */
|
/* Fall through to WAIT_TIMEOUTs return */
|
||||||
|
|
||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
@ -3629,18 +3650,24 @@ static pid_t win32_waitpid(int *exitstatus)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Get the exit code, and return the PID of, the respective process */
|
|
||||||
index = ret-WAIT_OBJECT_0;
|
/*
|
||||||
|
* Get the exit code, and return the PID of, the
|
||||||
|
* respective process
|
||||||
|
*/
|
||||||
|
index = ret - WAIT_OBJECT_0;
|
||||||
Assert(index >= 0 && index < win32_numChildren);
|
Assert(index >= 0 && index < win32_numChildren);
|
||||||
if (!GetExitCodeProcess(win32_childHNDArray[index],&exitCode))
|
if (!GetExitCodeProcess(win32_childHNDArray[index], &exitCode))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we get this far, this should never happen, but, then again...
|
* If we get this far, this should never happen, but,
|
||||||
* No choice other than to assume a catastrophic failure.
|
* then again... No choice other than to assume a
|
||||||
|
* catastrophic failure.
|
||||||
*/
|
*/
|
||||||
ereport(FATAL,
|
ereport(FATAL,
|
||||||
(errmsg_internal("failed to get exit code for child %lu",
|
(errmsg_internal("failed to get exit code for child %lu",
|
||||||
win32_childPIDArray[index])));
|
win32_childPIDArray[index])));
|
||||||
*exitstatus = (int)exitCode;
|
*exitstatus = (int) exitCode;
|
||||||
return win32_childPIDArray[index];
|
return win32_childPIDArray[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3651,14 +3678,17 @@ static pid_t win32_waitpid(int *exitstatus)
|
|||||||
|
|
||||||
/* Note! Code belows executes on separate threads, one for
|
/* Note! Code belows executes on separate threads, one for
|
||||||
each child process created */
|
each child process created */
|
||||||
static DWORD WINAPI win32_sigchld_waiter(LPVOID param) {
|
static DWORD WINAPI
|
||||||
HANDLE procHandle = (HANDLE)param;
|
win32_sigchld_waiter(LPVOID param)
|
||||||
|
{
|
||||||
|
HANDLE procHandle = (HANDLE) param;
|
||||||
|
|
||||||
|
DWORD r = WaitForSingleObject(procHandle, INFINITE);
|
||||||
|
|
||||||
DWORD r = WaitForSingleObject(procHandle, INFINITE);
|
|
||||||
if (r == WAIT_OBJECT_0)
|
if (r == WAIT_OBJECT_0)
|
||||||
pg_queue_signal(SIGCHLD);
|
pg_queue_signal(SIGCHLD);
|
||||||
else
|
else
|
||||||
fprintf(stderr,"ERROR: Failed to wait on child process handle: %i\n",(int)GetLastError());
|
fprintf(stderr, "ERROR: Failed to wait on child process handle: %i\n", (int) GetLastError());
|
||||||
CloseHandle(procHandle);
|
CloseHandle(procHandle);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user