summaryrefslogtreecommitdiff
path: root/src/backend/utils/misc/ps_status.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-02-22 21:26:55 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-02-22 21:26:55 +0000
commit780cba98805be80e33836c6cd4e69f3247881aa0 (patch)
tree4e76854446db265e994dc7fb16307af6ff1b11df /src/backend/utils/misc/ps_status.c
parent45f5eba90b8dfbd966784b836fface3390615a43 (diff)
Move responsibility for copying argv[] array into ps_status.c, where it
logically belongs. Arrange to update the _NSGetArgv() copy of the argv pointer on Darwin. (It seems likely that other NeXT-derived platforms also have an _NSGetArgv() problem, but until we have some reports I'll just make this #ifdef __darwin__.)
Diffstat (limited to 'src/backend/utils/misc/ps_status.c')
-rw-r--r--src/backend/utils/misc/ps_status.c62
1 files changed, 52 insertions, 10 deletions
diff --git a/src/backend/utils/misc/ps_status.c b/src/backend/utils/misc/ps_status.c
index 19e9aecad06..fcd236d0012 100644
--- a/src/backend/utils/misc/ps_status.c
+++ b/src/backend/utils/misc/ps_status.c
@@ -5,7 +5,7 @@
* to contain some useful information. Mechanism differs wildly across
* platforms.
*
- * $PostgreSQL: pgsql/src/backend/utils/misc/ps_status.c,v 1.16 2003/11/29 19:52:04 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/ps_status.c,v 1.17 2004/02/22 21:26:55 tgl Exp $
*
* Copyright (c) 2000-2003, PostgreSQL Global Development Group
* various details abducted from various places
@@ -22,6 +22,9 @@
#include <machine/vmparam.h> /* for old BSD */
#include <sys/exec.h>
#endif
+#if defined(__darwin__)
+#include <crt_externs.h>
+#endif
#include "miscadmin.h"
#include "utils/ps_status.h"
@@ -94,19 +97,21 @@ static char **save_argv;
/*
* Call this early in startup to save the original argc/argv values.
+ * If needed, we make a copy of the original argv[] array to preserve it
+ * from being clobbered by subsequent ps_display actions.
*
- * argv[] will not be overwritten by this routine, but may be overwritten
- * during init_ps_display. Also, the physical location of the environment
- * strings may be moved, so this should be called before any code that
- * might try to hang onto a getenv() result.
+ * (The original argv[] will not be overwritten by this routine, but may be
+ * overwritten during init_ps_display. Also, the physical location of the
+ * environment strings may be moved, so this should be called before any code
+ * that might try to hang onto a getenv() result.)
*/
-void
-save_ps_display_args(int argc, char *argv[])
+char **
+save_ps_display_args(int argc, char **argv)
{
save_argc = argc;
save_argv = argv;
-#ifdef PS_USE_CLOBBER_ARGV
+#if defined(PS_USE_CLOBBER_ARGV)
/*
* If we're going to overwrite the argv area, count the available
@@ -130,7 +135,7 @@ save_ps_display_args(int argc, char *argv[])
{
ps_buffer = NULL;
ps_buffer_size = 0;
- return;
+ return argv;
}
/*
@@ -148,13 +153,50 @@ save_ps_display_args(int argc, char *argv[])
/*
* move the environment out of the way
*/
- new_environ = malloc(sizeof(char *) * (i + 1));
+ new_environ = (char **) malloc((i + 1) * sizeof(char *));
for (i = 0; environ[i] != NULL; i++)
new_environ[i] = strdup(environ[i]);
new_environ[i] = NULL;
environ = new_environ;
}
#endif /* PS_USE_CLOBBER_ARGV */
+
+#if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV)
+
+ /*
+ * If we're going to change the original argv[] then make a copy for
+ * argument parsing purposes.
+ *
+ * (NB: do NOT think to remove the copying of argv[], even though
+ * postmaster.c finishes looking at argv[] long before we ever
+ * consider changing the ps display. On some platforms, getopt()
+ * keeps pointers into the argv array, and will get horribly confused
+ * when it is re-called to analyze a subprocess' argument string if
+ * the argv storage has been clobbered meanwhile. Other platforms
+ * have other dependencies on argv[].
+ */
+ {
+ char **new_argv;
+ int i;
+
+ new_argv = (char **) malloc((argc + 1) * sizeof(char *));
+ for (i = 0; i < argc; i++)
+ new_argv[i] = strdup(argv[i]);
+ new_argv[argc] = NULL;
+
+#if defined(__darwin__)
+ /*
+ * Darwin (and perhaps other NeXT-derived platforms?) has a static
+ * copy of the argv pointer, which we may fix like so:
+ */
+ *_NSGetArgv() = new_argv;
+#endif
+
+ argv = new_argv;
+ }
+#endif /* PS_USE_CHANGE_ARGV or PS_USE_CLOBBER_ARGV */
+
+ return argv;
}
/*