diff --git a/src/backend/main/main.c b/src/backend/main/main.c index a4a9c84ce0..685989ecf8 100644 --- a/src/backend/main/main.c +++ b/src/backend/main/main.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/main/main.c,v 1.73 2004/02/02 00:11:31 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/main/main.c,v 1.74 2004/02/22 21:26:55 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -49,8 +49,6 @@ int main(int argc, char *argv[]) { - char **new_argv; - int i; int len; struct passwd *pw; char *pw_name_persist; @@ -116,30 +114,18 @@ main(int argc, char *argv[]) */ /* - * Remember the physical location of the initially given argv[] array, - * since on some platforms that storage must be overwritten in order - * to set the process title for ps. Then make a copy of the argv[] - * array for subsequent use, so that argument parsing doesn't get - * affected if init_ps_display overwrites the original argv[]. + * Remember the physical location of the initially given argv[] array + * for possible use by ps display. On some platforms, the argv[] + * storage must be overwritten in order to set the process title for ps. + * In such cases save_ps_display_args makes and returns a new copy of + * the argv[] array. * - * (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.) - * - * On some platforms, save_ps_display_args moves the environment strings - * to make extra room. Therefore this should be done as early as - * possible during startup, to avoid entanglements with code that - * might save a getenv() result pointer. + * save_ps_display_args may also move the environment strings to make + * extra room. Therefore this should be done as early as possible during + * startup, to avoid entanglements with code that might save a getenv() + * result pointer. */ - save_ps_display_args(argc, argv); - - new_argv = (char **) malloc((argc + 1) * sizeof(char *)); - for (i = 0; i < argc; i++) - new_argv[i] = strdup(argv[i]); - new_argv[argc] = NULL; + argv = save_ps_display_args(argc, argv); /* * Set up locale information from environment. Note that LC_CTYPE and @@ -225,33 +211,33 @@ main(int argc, char *argv[]) * depending on the program name (and possibly first argument) we * were called with. The lack of consistency here is historical. */ - len = strlen(new_argv[0]); + len = strlen(argv[0]); - if ((len >= 10 && strcmp(new_argv[0] + len - 10, "postmaster") == 0) + if ((len >= 10 && strcmp(argv[0] + len - 10, "postmaster") == 0) #ifdef WIN32 - || (len >= 14 && strcmp(new_argv[0] + len - 14, "postmaster.exe") == 0) + || (len >= 14 && strcmp(argv[0] + len - 14, "postmaster.exe") == 0) #endif ) { /* Called as "postmaster" */ - exit(PostmasterMain(argc, new_argv)); + exit(PostmasterMain(argc, argv)); } /* * If the first argument is "-boot", then invoke bootstrap mode. Note * we remove "-boot" from the arguments passed on to BootstrapMain. */ - if (argc > 1 && strcmp(new_argv[1], "-boot") == 0) - exit(BootstrapMain(argc - 1, new_argv + 1)); + if (argc > 1 && strcmp(argv[1], "-boot") == 0) + exit(BootstrapMain(argc - 1, argv + 1)); #ifdef EXEC_BACKEND /* * If the first argument is "-forkexec", then invoke SubPostmasterMain. Note * we remove "-forkexec" from the arguments passed on to SubPostmasterMain. */ - if (argc > 1 && strcmp(new_argv[1], "-forkexec") == 0) + if (argc > 1 && strcmp(argv[1], "-forkexec") == 0) { - SubPostmasterMain(argc - 2, new_argv + 2); + SubPostmasterMain(argc - 2, argv + 2); exit(0); } @@ -259,9 +245,9 @@ main(int argc, char *argv[]) * If the first argument is "-statBuf", then invoke pgstat_main. Note * we remove "-statBuf" from the arguments passed on to pgstat_main. */ - if (argc > 1 && strcmp(new_argv[1], "-statBuf") == 0) + if (argc > 1 && strcmp(argv[1], "-statBuf") == 0) { - pgstat_main(argc - 2, new_argv + 2); + pgstat_main(argc - 2, argv + 2); exit(0); } @@ -269,9 +255,9 @@ main(int argc, char *argv[]) * If the first argument is "-statCol", then invoke pgstat_mainChild. Note * we remove "-statCol" from the arguments passed on to pgstat_mainChild. */ - if (argc > 1 && strcmp(new_argv[1], "-statCol") == 0) + if (argc > 1 && strcmp(argv[1], "-statCol") == 0) { - pgstat_mainChild(argc - 2, new_argv + 2); + pgstat_mainChild(argc - 2, argv + 2); exit(0); } #endif @@ -280,7 +266,7 @@ main(int argc, char *argv[]) * If the first argument is "--describe-config", then invoke runtime * configuration option display mode. */ - if (argc > 1 && strcmp(new_argv[1], "--describe-config") == 0) + if (argc > 1 && strcmp(argv[1], "--describe-config") == 0) exit(GucInfoMain()); /* @@ -293,7 +279,7 @@ main(int argc, char *argv[]) if (pw == NULL) { fprintf(stderr, gettext("%s: invalid effective UID: %d\n"), - new_argv[0], (int) geteuid()); + argv[0], (int) geteuid()); exit(1); } /* Allocate new memory because later getpwuid() calls can overwrite it */ @@ -306,11 +292,11 @@ main(int argc, char *argv[]) if (!GetUserName(pw_name_persist, &namesize)) { fprintf(stderr, gettext("%s: could not determine user name (GetUserName failed)\n"), - new_argv[0]); + argv[0]); exit(1); } } #endif - exit(PostgresMain(argc, new_argv, pw_name_persist)); + exit(PostgresMain(argc, argv, pw_name_persist)); } diff --git a/src/backend/utils/misc/ps_status.c b/src/backend/utils/misc/ps_status.c index 19e9aecad0..fcd236d001 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 /* for old BSD */ #include #endif +#if defined(__darwin__) +#include +#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; } /* diff --git a/src/include/utils/ps_status.h b/src/include/utils/ps_status.h index 97870d38af..6855d34a34 100644 --- a/src/include/utils/ps_status.h +++ b/src/include/utils/ps_status.h @@ -4,7 +4,7 @@ * * Declarations for backend/utils/misc/ps_status.c * - * $PostgreSQL: pgsql/src/include/utils/ps_status.h,v 1.24 2003/11/29 22:41:16 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/utils/ps_status.h,v 1.25 2004/02/22 21:26:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -12,7 +12,7 @@ #ifndef PS_STATUS_H #define PS_STATUS_H -extern void save_ps_display_args(int argc, char *argv[]); +extern char **save_ps_display_args(int argc, char **argv); extern void init_ps_display(const char *username, const char *dbname, const char *host_info);