yuezonghe | 824eb0c | 2024-06-27 02:32:26 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2015-2022 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 "apps.h" /* for app_malloc() and 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 | newargv = app_malloc(sizeof(*newargv) * (count + 1), "argv copy"); |
| 54 | if (newargv == NULL) |
| 55 | return NULL; |
| 56 | |
| 57 | /* Register automatic cleanup on first use */ |
| 58 | if (p == NULL) |
| 59 | OPENSSL_atexit(cleanup_argv); |
| 60 | |
| 61 | for (i = 0; i < count; i++) |
| 62 | newargv[i] = argv[i]; |
| 63 | newargv[i] = NULL; |
| 64 | *argc = i; |
| 65 | return newargv; |
| 66 | } |