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);
main(int argc, char *argv[])
{
bool do_check_root = true;
+ DispatchOption dispatch_option = DISPATCH_POSTMASTER;
reached_main = true;
* 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