context->pending_nulls = NULL;
}
+/* Use a platform-specific mechanism to look up the first argument to
+ * the current process.
+ * Note if you implement this for other platforms, also add it to
+ * tests/option-argv0.c
+ */
+static char *
+platform_get_argv0 (void)
+{
+#ifdef __linux
+ char *cmdline;
+ char *base_arg0;
+ gsize len;
+
+ if (!g_file_get_contents ("/proc/self/cmdline",
+ &cmdline,
+ &len,
+ NULL))
+ return NULL;
+ /* Sanity check for a NUL terminator. */
+ if (!memchr (cmdline, 0, len))
+ return NULL;
+ /* We could just return cmdline, but I think it's better
+ * to hold on to a smaller malloc block; the arguments
+ * could be large.
+ */
+ base_arg0 = g_path_get_basename (cmdline);
+ g_free (cmdline);
+ return base_arg0;
+#endif
+
+ return NULL;
+}
+
/**
* g_option_context_parse:
* @context: a #GOptionContext
/* Set program name */
if (!g_get_prgname())
{
+ gchar *prgname;
+
if (argc && argv && *argc)
- {
- gchar *prgname;
+ prgname = g_path_get_basename ((*argv)[0]);
+ else
+ prgname = platform_get_argv0 ();
- prgname = g_path_get_basename ((*argv)[0]);
- g_set_prgname (prgname);
- g_free (prgname);
- }
+ if (prgname)
+ g_set_prgname (prgname);
else
- g_set_prgname ("<unknown>");
+ g_set_prgname ("<unknown>");
+
+ g_free (prgname);
}
/* Call pre-parse hooks */
option_context_SOURCES = option-context.c
option_context_LDADD = $(progs_ldadd)
+TEST_PROGS += option-argv0
+option_argv0_SOURCES = option-argv0.c
+option_argv0_LDADD = $(progs_ldadd)
+
TEST_PROGS += keyfile
keyfile_SOURCES = keyfile.c
keyfile_LDADD = $(progs_ldadd)
--- /dev/null
+/*
+ * Copyright (C) 2011 Red Hat, Inc.
+ *
+ * This work is provided "as is"; redistribution and modification
+ * in whole or in part, in any medium, physical or electronic is
+ * permitted without restriction.
+ *
+ * This work is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In no event shall the authors or contributors be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential
+ * damages (including, but not limited to, procurement of substitute
+ * goods or services; loss of use, data, or profits; or business
+ * interruption) however caused and on any theory of liability, whether
+ * in contract, strict liability, or tort (including negligence or
+ * otherwise) arising in any way out of the use of this software, even
+ * if advised of the possibility of such damage.
+ *
+ * Authors: Colin Walters <walters@verbum.org>
+ */
+
+#include <glib.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+static void
+test_platform_argv0 (void)
+{
+ GOptionContext *context;
+ gboolean arg;
+ GOptionEntry entries [] =
+ { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
+ { NULL } };
+ gboolean retval;
+
+ context = g_option_context_new (NULL);
+ g_option_context_add_main_entries (context, entries, NULL);
+
+ retval = g_option_context_parse (context, NULL, NULL, NULL);
+ g_assert (retval == TRUE);
+ g_assert (strcmp (g_get_prgname(), "option-argv0") == 0
+ || strcmp (g_get_prgname (), "lt-option-argv0") == 0);
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ /* Note - we can't actually use g_test_* because g_test_init mutates
+ * g_get_prgname() which is exactly what we wanted to test =/
+ */
+#ifdef __linux
+ g_print ("/option/argv0: ");
+ test_platform_argv0 ();
+ g_print ("OK\n");
+#endif
+
+ return 0;
+}
g_option_context_free (context);
}
-void
-empty_test1 (void)
-{
- GOptionContext *context;
- GOptionEntry entries [] =
- { { NULL } };
- char *prgname;
-
- g_set_prgname (NULL);
- context = g_option_context_new (NULL);
-
- g_option_context_add_main_entries (context, entries, NULL);
-
- g_option_context_parse (context, NULL, NULL, NULL);
-
- prgname = g_get_prgname ();
- g_assert (prgname && strcmp (prgname, "<unknown>") == 0);
-
- g_option_context_free (context);
-}
-
void
empty_test2 (void)
{
g_test_add_func ("/option/context/add", add_test1);
/* Test parsing empty args */
- g_test_add_func ("/option/context/empty1", empty_test1);
+ /* Note there used to be an empty1 here, but it effectively moved
+ * to option-argv0.c.
+ */
g_test_add_func ("/option/context/empty2", empty_test2);
g_test_add_func ("/option/context/empty3", empty_test3);