mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
Check for /proc/self/cmdline
Instead of hardcoding /proc/self/cmdline use for __linux__ only, do a configure-time test for it. Specifically, this enables /proc/self/cmdline use on Cygwin. The configure-time test is very primitive (just tests that the file exists and that it's possible to read more than one byte from it), relying on the testsuite for more extensive checks. The test in the testsuite is modified to always run, even on platforms where it isn't supposed to pass. If it fails there, the testing framework skips it. If the test unexpectedly passes, that is reported too.
This commit is contained in:
parent
cf54fc3600
commit
4c038a27ff
@ -1815,7 +1815,7 @@ free_pending_nulls (GOptionContext *context,
|
|||||||
static char *
|
static char *
|
||||||
platform_get_argv0 (void)
|
platform_get_argv0 (void)
|
||||||
{
|
{
|
||||||
#if defined __linux
|
#ifdef HAVE_PROC_SELF_CMDLINE
|
||||||
char *cmdline;
|
char *cmdline;
|
||||||
char *base_arg0;
|
char *base_arg0;
|
||||||
gsize len;
|
gsize len;
|
||||||
|
@ -21,13 +21,13 @@
|
|||||||
* Authors: Colin Walters <walters@verbum.org>
|
* Authors: Colin Walters <walters@verbum.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if defined __linux || defined __OpenBSD__
|
|
||||||
static void
|
static void
|
||||||
test_platform_argv0 (void)
|
test_platform_argv0 (void)
|
||||||
{
|
{
|
||||||
@ -36,19 +36,65 @@ test_platform_argv0 (void)
|
|||||||
GOptionEntry entries [] =
|
GOptionEntry entries [] =
|
||||||
{ { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
|
{ { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
const gchar * const expected_prgnames[] =
|
||||||
|
{
|
||||||
|
"option-argv0",
|
||||||
|
"lt-option-argv0",
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
"option-argv0.exe",
|
||||||
|
#endif
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
gboolean retval;
|
gboolean retval;
|
||||||
|
gboolean fatal_errors = TRUE;
|
||||||
|
|
||||||
|
/* This test must pass on platforms where platform_get_argv0()
|
||||||
|
* is implemented. At the moment that means Linux/Cygwin,
|
||||||
|
* (which uses /proc/self/cmdline) or OpenBSD (which uses
|
||||||
|
* sysctl and KERN_PROC_ARGS). On other platforms the test
|
||||||
|
* is not expected to pass, but we'd still want to know
|
||||||
|
* how it does (the test code itself doesn't use any platform-specific
|
||||||
|
* functionality, the difference is internal to glib, so it's quite
|
||||||
|
* possible to run this test everywhere - it just won't pass on some
|
||||||
|
* platforms). Make errors non-fatal on these other plaforms,
|
||||||
|
* to prevent them from crashing hard on failed assertions,
|
||||||
|
* and make them call g_test_skip() instead.
|
||||||
|
*/
|
||||||
|
#if !defined HAVE_PROC_SELF_CMDLINE && !defined __OpenBSD__
|
||||||
|
fatal_errors = FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
context = g_option_context_new (NULL);
|
context = g_option_context_new (NULL);
|
||||||
g_option_context_add_main_entries (context, entries, NULL);
|
g_option_context_add_main_entries (context, entries, NULL);
|
||||||
|
|
||||||
retval = g_option_context_parse (context, NULL, NULL, NULL);
|
retval = g_option_context_parse (context, NULL, NULL, NULL);
|
||||||
g_assert (retval == TRUE);
|
if (fatal_errors)
|
||||||
g_assert (strcmp (g_get_prgname(), "option-argv0") == 0
|
{
|
||||||
|| strcmp (g_get_prgname (), "lt-option-argv0") == 0);
|
g_assert_true (retval);
|
||||||
|
g_assert_true (g_strv_contains (expected_prgnames, g_get_prgname ()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gboolean failed = FALSE;
|
||||||
|
|
||||||
|
if (!retval)
|
||||||
|
{
|
||||||
|
g_print ("g_option_context_parse() failed\n");
|
||||||
|
failed = TRUE;
|
||||||
|
}
|
||||||
|
else if (!g_strv_contains (expected_prgnames, g_get_prgname ()))
|
||||||
|
{
|
||||||
|
g_print ("program name `%s' is neither `option-argv0', nor `lt-option-argv0'\n", g_get_prgname());
|
||||||
|
failed = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_print ("The test unexpectedly passed\n");
|
||||||
|
if (failed)
|
||||||
|
g_test_skip ("platform_get_argv0() is not implemented [correctly?] on this platform");
|
||||||
|
}
|
||||||
|
|
||||||
g_option_context_free (context);
|
g_option_context_free (context);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
@ -56,9 +102,7 @@ main (int argc,
|
|||||||
{
|
{
|
||||||
g_test_init (&argc, &argv, "no_g_set_prgname", NULL);
|
g_test_init (&argc, &argv, "no_g_set_prgname", NULL);
|
||||||
|
|
||||||
#if defined __linux || defined __OpenBSD__
|
|
||||||
g_test_add_func ("/option/argv0", test_platform_argv0);
|
g_test_add_func ("/option/argv0", test_platform_argv0);
|
||||||
#endif
|
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
47
meson.build
47
meson.build
@ -1898,6 +1898,53 @@ if cc.has_function('strlcpy')
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
cmdline_test_code = '''
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#undef NDEBUG
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
__getcmdline (void)
|
||||||
|
{
|
||||||
|
/* This code is a dumbed-down version of g_file_get_contents() */
|
||||||
|
#define BUFSIZE 1024
|
||||||
|
char result[BUFSIZE];
|
||||||
|
struct stat stat_buf;
|
||||||
|
|
||||||
|
int fd = open ("/proc/self/cmdline", O_RDONLY|O_BINARY);
|
||||||
|
assert (fd >= 0);
|
||||||
|
assert (fstat (fd, &stat_buf) == 0);
|
||||||
|
|
||||||
|
if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
|
||||||
|
assert (read (fd, result, BUFSIZE) > 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FILE *f = fdopen (fd, "r");
|
||||||
|
assert (f != NULL);
|
||||||
|
assert (fread (result, 1, BUFSIZE, f) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
exit (__getcmdline ());
|
||||||
|
}'''
|
||||||
|
|
||||||
|
if cc_can_run
|
||||||
|
rres = cc.run(cmdline_test_code, name : '/proc/self/cmdline')
|
||||||
|
have_proc_self_cmdline = rres.compiled() and rres.returncode() == 0
|
||||||
|
else
|
||||||
|
have_proc_self_cmdline = meson.get_cross_property('have_proc_self_cmdline', false)
|
||||||
|
endif
|
||||||
|
|
||||||
|
glib_conf.set('HAVE_PROC_SELF_CMDLINE', have_proc_self_cmdline)
|
||||||
|
|
||||||
python = import('python').find_installation('python3')
|
python = import('python').find_installation('python3')
|
||||||
# used for '#!/usr/bin/env <name>'
|
# used for '#!/usr/bin/env <name>'
|
||||||
python_name = 'python3'
|
python_name = 'python3'
|
||||||
|
Loading…
Reference in New Issue
Block a user