1 | /*
|
---|
2 | * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use
|
---|
5 | * this file except in compliance with the License. You can obtain a copy
|
---|
6 | * in the file LICENSE in the source distribution or at
|
---|
7 | * https://www.openssl.org/source/license.html
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include <stdlib.h>
|
---|
11 | #include <openssl/crypto.h>
|
---|
12 | #include "platform.h" /* for copy_argv() */
|
---|
13 |
|
---|
14 | char **newargv = NULL;
|
---|
15 |
|
---|
16 | static void cleanup_argv(void)
|
---|
17 | {
|
---|
18 | OPENSSL_free(newargv);
|
---|
19 | newargv = NULL;
|
---|
20 | }
|
---|
21 |
|
---|
22 | char **copy_argv(int *argc, char *argv[])
|
---|
23 | {
|
---|
24 | /*-
|
---|
25 | * The note below is for historical purpose. On VMS now we always
|
---|
26 | * copy argv "safely."
|
---|
27 | *
|
---|
28 | * 2011-03-22 SMS.
|
---|
29 | * If we have 32-bit pointers everywhere, then we're safe, and
|
---|
30 | * we bypass this mess, as on non-VMS systems.
|
---|
31 | * Problem 1: Compaq/HP C before V7.3 always used 32-bit
|
---|
32 | * pointers for argv[].
|
---|
33 | * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers
|
---|
34 | * everywhere else, we always allocate and use a 64-bit
|
---|
35 | * duplicate of argv[].
|
---|
36 | * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed
|
---|
37 | * to NULL-terminate a 64-bit argv[]. (As this was written, the
|
---|
38 | * compiler ECO was available only on IA64.)
|
---|
39 | * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a
|
---|
40 | * 64-bit argv[argc] for NULL, and, if necessary, use a
|
---|
41 | * (properly) NULL-terminated (64-bit) duplicate of argv[].
|
---|
42 | * The same code is used in either case to duplicate argv[].
|
---|
43 | * Some of these decisions could be handled in preprocessing,
|
---|
44 | * but the code tends to get even uglier, and the penalty for
|
---|
45 | * deciding at compile- or run-time is tiny.
|
---|
46 | */
|
---|
47 |
|
---|
48 | int i, count = *argc;
|
---|
49 | char **p = newargv;
|
---|
50 |
|
---|
51 | cleanup_argv();
|
---|
52 |
|
---|
53 | /*
|
---|
54 | * We purposefully use OPENSSL_malloc() rather than app_malloc() here,
|
---|
55 | * to avoid symbol name clashes in test programs that would otherwise
|
---|
56 | * get them when linking with all of libapps.a.
|
---|
57 | * See comment in test/build.info.
|
---|
58 | */
|
---|
59 | newargv = OPENSSL_malloc(sizeof(*newargv) * (count + 1));
|
---|
60 | if (newargv == NULL)
|
---|
61 | return NULL;
|
---|
62 |
|
---|
63 | /* Register automatic cleanup on first use */
|
---|
64 | if (p == NULL)
|
---|
65 | OPENSSL_atexit(cleanup_argv);
|
---|
66 |
|
---|
67 | for (i = 0; i < count; i++)
|
---|
68 | newargv[i] = argv[i];
|
---|
69 | newargv[i] = NULL;
|
---|
70 | *argc = i;
|
---|
71 | return newargv;
|
---|
72 | }
|
---|