aboutsummaryrefslogtreecommitdiff
path: root/src/backend/postmaster/fork_process.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/postmaster/fork_process.c')
-rw-r--r--src/backend/postmaster/fork_process.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/backend/postmaster/fork_process.c b/src/backend/postmaster/fork_process.c
new file mode 100644
index 00000000000..3098087db44
--- /dev/null
+++ b/src/backend/postmaster/fork_process.c
@@ -0,0 +1,80 @@
+/*
+ * 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;
+}