[m-rev.] for review: Handle argv[0] == NULL.
Peter Wang
novalazy at gmail.com
Mon Jan 31 13:48:36 AEDT 2022
On some operating systems, e.g. Linux, it is possible to enter main()
with argv[0] == NULL if the parent process calls execve() with
argv[0] == NULL, or equivalently, passing NULL for the argv parameter.
runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
Do not assume argc > 0 and argv[0] != NULL in MR_process_args.
If argv[0] is NULL then set MR_progname to the empty string
so users of MR_progname can assume it points to a valid string.
Add a new global variable MR_progname_is_known to indicate if
argv[0] was NULL or not.
library/io.m:
Make io.progname return the default program name if argv[0] was
NULL.
util/mkinit.c:
Set MR_progname to a valid string if argv[0] is NULL.
This is not actually necessary, since, in that case, the subsequent
call to parse_options() would immediately exit the program
as no file names will be found in argv.
---
library/io.m | 4 ++--
runtime/mercury_wrapper.c | 25 ++++++++++++++++++++++---
runtime/mercury_wrapper.h | 3 ++-
util/mkinit.c | 4 ++++
4 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/library/io.m b/library/io.m
index f3cb7d24b..4ca3774fe 100644
--- a/library/io.m
+++ b/library/io.m
@@ -2,7 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1993-2012 The University of Melbourne.
-% Copyright (C) 2013-2021 The Mercury team.
+% Copyright (C) 2013-2022 The Mercury team.
% This file is distributed under the terms specified in COPYING.LIB.
%---------------------------------------------------------------------------%
%
@@ -11551,7 +11551,7 @@ system_temp_dir("", 0, !IO).
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
does_not_affect_liveness, may_not_duplicate],
"
- if (MR_progname) {
+ if (MR_progname && MR_progname_is_known) {
MR_make_aligned_string(PrognameOut, MR_progname);
} else {
PrognameOut = DefaultProgname;
diff --git a/runtime/mercury_wrapper.c b/runtime/mercury_wrapper.c
index 5018d667b..cb656b9d5 100644
--- a/runtime/mercury_wrapper.c
+++ b/runtime/mercury_wrapper.c
@@ -328,6 +328,7 @@ enum MR_TimeProfileMethod
#endif
const char *MR_progname;
+MR_bool MR_progname_is_known;
int mercury_argc; // Not counting progname.
char **mercury_argv;
int mercury_exit_status = 0;
@@ -1032,9 +1033,27 @@ MR_make_argv(const char *string,
static void
MR_process_args(int argc, char **argv)
{
- MR_progname = argv[0];
- mercury_argc = argc - 1;
- mercury_argv = argv + 1;
+ // It is possible that argc == 0 and argv[0] == NULL on some operating
+ // systems. Since that is not actually useful, we ensure that MR_progname
+ // is always set to a valid string so that uses of MR_progname do not need
+ // to check if it is NULL.
+
+ if (argc >= 1) {
+ MR_progname = argv[0];
+ mercury_argc = argc - 1;
+ mercury_argv = argv + 1;
+ } else {
+ MR_progname = NULL;
+ mercury_argc = 0;
+ mercury_argv = argv;
+ }
+
+ if (MR_progname == NULL) {
+ MR_progname = "";
+ MR_progname_is_known = MR_FALSE;
+ } else {
+ MR_progname_is_known = MR_TRUE;
+ }
}
// MR_process_environment_options() is a function to parse the options put
diff --git a/runtime/mercury_wrapper.h b/runtime/mercury_wrapper.h
index 62c210c6c..1b28acff3 100644
--- a/runtime/mercury_wrapper.h
+++ b/runtime/mercury_wrapper.h
@@ -1,7 +1,7 @@
// vim: ts=4 sw=4 expandtab ft=c
// Copyright (C) 1994-2011 The University of Melbourne.
-// Copyright (C) 2014-2016, 2018 The Mercury team.
+// Copyright (C) 2014-2016, 2018, 2022 The Mercury team.
// This file is distributed under the terms specified in COPYING.LIB.
// mercury_wrapper.h - defines the interface to mercury_wrapper.c.
@@ -176,6 +176,7 @@ extern int MR_num_complexity_procs;
#endif
extern const char *MR_progname;
+extern MR_bool MR_progname_is_known;
extern int mercury_argc;
extern char **mercury_argv;
extern int mercury_exit_status;
diff --git a/util/mkinit.c b/util/mkinit.c
index 4629a143a..3dfcc4466 100644
--- a/util/mkinit.c
+++ b/util/mkinit.c
@@ -2,6 +2,7 @@
// vim:sw=4 ts=4 expandtab
//
// Copyright (C) 1995-2008, 2010-2012 The University of Melbourne.
+// Copyright (C) 2014-2016, 2019, 2020, 2022 The Mercury team.
// This file may only be copied under the terms of the GNU General
// Public License - see the file COPYING in the Mercury distribution.
@@ -646,6 +647,9 @@ main(int argc, char **argv)
int exit_status;
MR_progname = argv[0];
+ if (MR_progname == NULL) {
+ MR_progname = "mkinit";
+ }
parse_options(argc, argv);
--
2.31.0
More information about the reviews
mailing list