]>
Commit | Line | Data |
---|---|---|
9b542d72 RL |
1 | /* |
2 | * Copyright 2015-2019 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> | |
ce506d27 RL |
12 | #include "platform.h" /* for copy_argv() */ |
13 | #include "apps.h" /* for app_malloc() */ | |
9b542d72 RL |
14 | |
15 | char **newargv = NULL; | |
16 | ||
17 | static void cleanup_argv(void) | |
18 | { | |
19 | OPENSSL_free(newargv); | |
20 | newargv = NULL; | |
21 | } | |
22 | ||
23 | char **copy_argv(int *argc, char *argv[]) | |
24 | { | |
25 | /*- | |
26 | * The note below is for historical purpose. On VMS now we always | |
27 | * copy argv "safely." | |
28 | * | |
29 | * 2011-03-22 SMS. | |
30 | * If we have 32-bit pointers everywhere, then we're safe, and | |
31 | * we bypass this mess, as on non-VMS systems. | |
32 | * Problem 1: Compaq/HP C before V7.3 always used 32-bit | |
33 | * pointers for argv[]. | |
34 | * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers | |
35 | * everywhere else, we always allocate and use a 64-bit | |
36 | * duplicate of argv[]. | |
37 | * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed | |
38 | * to NULL-terminate a 64-bit argv[]. (As this was written, the | |
39 | * compiler ECO was available only on IA64.) | |
40 | * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a | |
41 | * 64-bit argv[argc] for NULL, and, if necessary, use a | |
42 | * (properly) NULL-terminated (64-bit) duplicate of argv[]. | |
43 | * The same code is used in either case to duplicate argv[]. | |
44 | * Some of these decisions could be handled in preprocessing, | |
45 | * but the code tends to get even uglier, and the penalty for | |
46 | * deciding at compile- or run-time is tiny. | |
47 | */ | |
48 | ||
49 | int i, count = *argc; | |
50 | char **p = newargv; | |
51 | ||
52 | cleanup_argv(); | |
53 | ||
54 | newargv = app_malloc(sizeof(*newargv) * (count + 1), "argv copy"); | |
55 | if (newargv == NULL) | |
56 | return NULL; | |
57 | ||
58 | /* Register automatic cleanup on first use */ | |
59 | if (p == NULL) | |
60 | OPENSSL_atexit(cleanup_argv); | |
61 | ||
62 | for (i = 0; i < count; i++) | |
63 | newargv[i] = argv[i]; | |
64 | newargv[i] = NULL; | |
65 | *argc = i; | |
66 | return newargv; | |
67 | } |