--- /dev/null
+/*
+ * fork_process.c
+ * A simple wrapper on top of fork(). This does not handle the
+ * EXEC_BACKEND case; it might be extended to do so, but it would be
+ * considerably more complex.
+ *
+ * Copyright (c) 1996-2005, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/postmaster/fork_process.c,v 1.1 2005/03/10 07:14:03 neilc Exp $
+ */
+#include "postgres.h"
+#include "postmaster/fork_process.h"
+
+#include <unistd.h>
+
+/*
+ * Wrapper for fork(). Return values are the same as those for fork():
+ * -1 if the fork failed, 0 in the child process, and the PID of the
+ * child in the parent process.
+ */
+pid_t
+fork_process(void)
+{
+ pid_t result;
+#ifdef LINUX_PROFILE
+ struct itimerval prof_itimer;
+#endif
+
+ /*
+ * Flush stdio channels just before fork, to avoid double-output
+ * problems. Ideally we'd use fflush(NULL) here, but there are still a
+ * few non-ANSI stdio libraries out there (like SunOS 4.1.x) that
+ * coredump if we do. Presently stdout and stderr are the only stdio
+ * output channels used by the postmaster, so fflush'ing them should
+ * be sufficient.
+ */
+ fflush(stdout);
+ fflush(stderr);
+
+#ifdef LINUX_PROFILE
+ /*
+ * Linux's fork() resets the profiling timer in the child process. If
+ * we want to profile child processes then we need to save and restore
+ * the timer setting. This is a waste of time if not profiling,
+ * however, so only do it if commanded by specific -DLINUX_PROFILE
+ * switch.
+ */
+ getitimer(ITIMER_PROF, &prof_itimer);
+#endif
+
+#ifdef __BEOS__
+ /* Specific beos actions before backend startup */
+ beos_before_backend_startup();
+#endif
+
+ result = fork();
+ if (result == (pid_t) -1)
+ {
+ /* fork failed */
+#ifdef __BEOS__
+ /* Specific beos backend startup actions */
+ beos_backend_startup_failed();
+#endif
+ }
+ else if (result == 0)
+ {
+ /* fork succeeded, in child */
+#ifdef LINUX_PROFILE
+ setitimer(ITIMER_PROF, &prof_itimer, NULL);
+#endif
+
+#ifdef __BEOS__
+ /* Specific beos backend startup actions */
+ beos_backend_startup();
+#endif
+ }
+
+ return result;
+}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.14 2004/12/31 22:00:40 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.15 2005/03/10 07:14:03 neilc Exp $
*
*-------------------------------------------------------------------------
*/
#include "access/xlog_internal.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
+#include "postmaster/fork_process.h"
#include "postmaster/pgarch.h"
#include "postmaster/postmaster.h"
#include "storage/fd.h"
return 0;
last_pgarch_start_time = curtime;
- fflush(stdout);
- fflush(stderr);
-
-#ifdef __BEOS__
- /* Specific beos actions before backend startup */
- beos_before_backend_startup();
-#endif
-
#ifdef EXEC_BACKEND
switch ((pgArchPid = pgarch_forkexec()))
#else
- switch ((pgArchPid = fork()))
+ switch ((pgArchPid = fork_process()))
#endif
{
case -1:
-#ifdef __BEOS__
- /* Specific beos actions */
- beos_backend_startup_failed();
-#endif
ereport(LOG,
(errmsg("could not fork archiver: %m")));
return 0;
#ifndef EXEC_BACKEND
case 0:
/* in postmaster child ... */
-#ifdef __BEOS__
- /* Specific beos actions after backend startup */
- beos_backend_startup();
-#endif
/* Close the postmaster's sockets */
ClosePostmasterPorts(false);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.445 2005/02/22 04:36:36 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.446 2005/03/10 07:14:03 neilc Exp $
*
* NOTES
*
#include <DNSServiceDiscovery/DNSServiceDiscovery.h>
#endif
+#include "access/xlog.h"
+#include "bootstrap/bootstrap.h"
#include "catalog/pg_control.h"
#include "catalog/pg_database.h"
#include "commands/async.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "nodes/nodes.h"
-#include "postmaster/postmaster.h"
+#include "pgstat.h"
+#include "postmaster/fork_process.h"
#include "postmaster/pgarch.h"
+#include "postmaster/postmaster.h"
#include "postmaster/syslogger.h"
+#include "storage/bufmgr.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/pg_shmem.h"
#include "storage/pmsignal.h"
#include "storage/proc.h"
-#include "storage/bufmgr.h"
-#include "access/xlog.h"
#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
-#include "bootstrap/bootstrap.h"
-#include "pgstat.h"
#ifdef EXEC_BACKEND
#include "storage/spin.h"
int i;
pid_t pid;
-#ifdef LINUX_PROFILE
- struct itimerval prof_itimer;
-#endif
-
-#ifdef LINUX_PROFILE
- /* see comments in BackendStartup */
- getitimer(ITIMER_PROF, &prof_itimer);
-#endif
-
- pid = fork();
+ pid = fork_process();
if (pid == (pid_t) -1)
{
write_stderr("%s: could not fork background process: %s\n",
_exit(0);
}
-#ifdef LINUX_PROFILE
- setitimer(ITIMER_PROF, &prof_itimer, NULL);
-#endif
-
MyProcPid = PostmasterPid = getpid(); /* reset PID vars to child */
/* GH: If there's no setsid(), we hopefully don't need silent mode.
Backend *bn; /* for backend cleanup */
pid_t pid;
-#ifdef LINUX_PROFILE
- struct itimerval prof_itimer;
-#endif
-
/*
* Compute the cancel key that will be assigned to this backend. The
* backend will have its own copy in the forked-off process' value of
/* Pass down canAcceptConnections state (kluge for EXEC_BACKEND case) */
port->canAcceptConnections = canAcceptConnections();
- /*
- * Flush stdio channels just before fork, to avoid double-output
- * problems. Ideally we'd use fflush(NULL) here, but there are still a
- * few non-ANSI stdio libraries out there (like SunOS 4.1.x) that
- * coredump if we do. Presently stdout and stderr are the only stdio
- * output channels used by the postmaster, so fflush'ing them should
- * be sufficient.
- */
- fflush(stdout);
- fflush(stderr);
-
#ifdef EXEC_BACKEND
-
pid = backend_forkexec(port);
-
#else /* !EXEC_BACKEND */
-
-#ifdef LINUX_PROFILE
-
- /*
- * Linux's fork() resets the profiling timer in the child process. If
- * we want to profile child processes then we need to save and restore
- * the timer setting. This is a waste of time if not profiling,
- * however, so only do it if commanded by specific -DLINUX_PROFILE
- * switch.
- */
- getitimer(ITIMER_PROF, &prof_itimer);
-#endif
-
-#ifdef __BEOS__
- /* Specific beos actions before backend startup */
- beos_before_backend_startup();
-#endif
-
- pid = fork();
-
+ pid = fork_process();
if (pid == 0) /* child */
{
-#ifdef LINUX_PROFILE
- setitimer(ITIMER_PROF, &prof_itimer, NULL);
-#endif
-
-#ifdef __BEOS__
- /* Specific beos backend startup actions */
- beos_backend_startup();
-#endif
free(bn);
-
proc_exit(BackendRun(port));
}
#endif /* EXEC_BACKEND */
/* in parent, fork failed */
int save_errno = errno;
-#ifdef __BEOS__
- /* Specific beos backend startup actions */
- beos_backend_startup_failed();
-#endif
free(bn);
errno = save_errno;
ereport(LOG,
argv[2] = tmpfilename;
/* Fire off execv in child */
- if ((pid = fork()) == 0)
+ if ((pid = fork_process()) == 0)
{
if (execv(postgres_exec_path, argv) < 0)
{
int ac = 0;
char xlbuf[32];
-#ifdef LINUX_PROFILE
- struct itimerval prof_itimer;
-#endif
-
/*
* Set up command-line arguments for subprocess
*/
av[ac] = NULL;
Assert(ac < lengthof(av));
- /*
- * Flush stdio channels (see comments in BackendStartup)
- */
- fflush(stdout);
- fflush(stderr);
-
#ifdef EXEC_BACKEND
-
pid = postmaster_forkexec(ac, av);
-
#else /* !EXEC_BACKEND */
-
-#ifdef LINUX_PROFILE
- /* see comments in BackendStartup */
- getitimer(ITIMER_PROF, &prof_itimer);
-#endif
-
-#ifdef __BEOS__
- /* Specific beos actions before backend startup */
- beos_before_backend_startup();
-#endif
-
- pid = fork();
+ pid = fork_process();
if (pid == 0) /* child */
{
-#ifdef LINUX_PROFILE
- setitimer(ITIMER_PROF, &prof_itimer, NULL);
-#endif
-
-#ifdef __BEOS__
- /* Specific beos actions after backend startup */
- beos_backend_startup();
-#endif
-
IsUnderPostmaster = true; /* we are a postmaster subprocess
* now */
{
/* in parent, fork failed */
int save_errno = errno;
-
-#ifdef __BEOS__
- /* Specific beos actions before backend startup */
- beos_backend_startup_failed();
-#endif
errno = save_errno;
switch (xlop)
{
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.12 2005/01/01 20:44:16 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.13 2005/03/10 07:14:03 neilc Exp $
*
*-------------------------------------------------------------------------
*/
#include "libpq/pqsignal.h"
#include "miscadmin.h"
+#include "postmaster/fork_process.h"
#include "postmaster/postmaster.h"
#include "postmaster/syslogger.h"
#include "pgtime.h"
pfree(filename);
- /*
- * Now we can fork off the syslogger subprocess.
- */
- fflush(stdout);
- fflush(stderr);
-
-#ifdef __BEOS__
- /* Specific beos actions before backend startup */
- beos_before_backend_startup();
-#endif
-
#ifdef EXEC_BACKEND
switch ((sysloggerPid = syslogger_forkexec()))
#else
- switch ((sysloggerPid = fork()))
+ switch ((sysloggerPid = fork_process()))
#endif
{
case -1:
-#ifdef __BEOS__
- /* Specific beos actions */
- beos_backend_startup_failed();
-#endif
ereport(LOG,
(errmsg("could not fork system logger: %m")));
return 0;
#ifndef EXEC_BACKEND
case 0:
/* in postmaster child ... */
-#ifdef __BEOS__
- /* Specific beos actions after backend startup */
- beos_backend_startup();
-#endif
/* Close the postmaster's sockets */
ClosePostmasterPorts(true);