diff options
Diffstat (limited to 'src/backend/main/main.c')
-rw-r--r-- | src/backend/main/main.c | 86 |
1 files changed, 73 insertions, 13 deletions
diff --git a/src/backend/main/main.c b/src/backend/main/main.c index aea93a02298..3acb46bd464 100644 --- a/src/backend/main/main.c +++ b/src/backend/main/main.c @@ -43,6 +43,19 @@ const char *progname; static bool reached_main = false; +/* names of special must-be-first options for dispatching to subprograms */ +static const char *const DispatchOptionNames[] = +{ + [DISPATCH_CHECK] = "check", + [DISPATCH_BOOT] = "boot", + [DISPATCH_FORKCHILD] = "forkchild", + [DISPATCH_DESCRIBE_CONFIG] = "describe-config", + [DISPATCH_SINGLE] = "single", + /* DISPATCH_POSTMASTER has no name */ +}; + +StaticAssertDecl(lengthof(DispatchOptionNames) == DISPATCH_POSTMASTER, + "array length mismatch"); static void startup_hacks(const char *progname); static void init_locale(const char *categoryname, int category, const char *locale); @@ -57,6 +70,7 @@ int main(int argc, char *argv[]) { bool do_check_root = true; + DispatchOption dispatch_option = DISPATCH_POSTMASTER; reached_main = true; @@ -179,26 +193,72 @@ main(int argc, char *argv[]) * Dispatch to one of various subprograms depending on first argument. */ - if (argc > 1 && strcmp(argv[1], "--check") == 0) - BootstrapModeMain(argc, argv, true); - else if (argc > 1 && strcmp(argv[1], "--boot") == 0) - BootstrapModeMain(argc, argv, false); + if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-') + dispatch_option = parse_dispatch_option(&argv[1][2]); + + switch (dispatch_option) + { + case DISPATCH_CHECK: + BootstrapModeMain(argc, argv, true); + break; + case DISPATCH_BOOT: + BootstrapModeMain(argc, argv, false); + break; + case DISPATCH_FORKCHILD: #ifdef EXEC_BACKEND - else if (argc > 1 && strncmp(argv[1], "--forkchild", 11) == 0) - SubPostmasterMain(argc, argv); + SubPostmasterMain(argc, argv); +#else + Assert(false); /* should never happen */ #endif - else if (argc > 1 && strcmp(argv[1], "--describe-config") == 0) - GucInfoMain(); - else if (argc > 1 && strcmp(argv[1], "--single") == 0) - PostgresSingleUserMain(argc, argv, - strdup(get_user_name_or_exit(progname))); - else - PostmasterMain(argc, argv); + break; + case DISPATCH_DESCRIBE_CONFIG: + GucInfoMain(); + break; + case DISPATCH_SINGLE: + PostgresSingleUserMain(argc, argv, + strdup(get_user_name_or_exit(progname))); + break; + case DISPATCH_POSTMASTER: + PostmasterMain(argc, argv); + break; + } + /* the functions above should not return */ abort(); } +/* + * Returns the matching DispatchOption value for the given option name. If no + * match is found, DISPATCH_POSTMASTER is returned. + */ +DispatchOption +parse_dispatch_option(const char *name) +{ + for (int i = 0; i < lengthof(DispatchOptionNames); i++) + { + /* + * Unlike the other dispatch options, "forkchild" takes an argument, + * so we just look for the prefix for that one. For non-EXEC_BACKEND + * builds, we never want to return DISPATCH_FORKCHILD, so skip over it + * in that case. + */ + if (i == DISPATCH_FORKCHILD) + { +#ifdef EXEC_BACKEND + if (strncmp(DispatchOptionNames[DISPATCH_FORKCHILD], name, + strlen(DispatchOptionNames[DISPATCH_FORKCHILD])) == 0) + return DISPATCH_FORKCHILD; +#endif + continue; + } + + if (strcmp(DispatchOptionNames[i], name) == 0) + return (DispatchOption) i; + } + /* no match means this is a postmaster */ + return DISPATCH_POSTMASTER; +} /* * Place platform-specific startup hacks here. This is the right |