|
1 | 1 | /* |
2 | | - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * The Universal Permissive License (UPL), Version 1.0 |
|
47 | 47 | #include <string.h> |
48 | 48 | #include <limits.h> |
49 | 49 | #include <stdarg.h> |
| 50 | +#include <wordexp.h> |
50 | 51 | #include <mach-o/dyld.h> |
51 | 52 |
|
52 | 53 | #define GRAAL_PYTHON_EXE_ARG "--python.Executable=" |
@@ -105,11 +106,11 @@ char *get_pyenvcfg_command(const char *pyenv_cfg_path) { |
105 | 106 | exit(1); |
106 | 107 | } |
107 | 108 | while (isspace((unsigned char) *p)) p++; |
| 109 | + char *end = p + strlen(p); |
| 110 | + while (end > p && isspace((unsigned char) end[-1])) { |
| 111 | + *--end = '\0'; |
| 112 | + } |
108 | 113 | if (*p == '\"') { |
109 | | - char *end = p + strlen(p); |
110 | | - while (end > p && (isspace((unsigned char) end[-1]) || end[-1] == '\n')) { |
111 | | - *--end = '\0'; |
112 | | - } |
113 | 114 | if (end <= p + 1 || end[-1] != '\"') { |
114 | 115 | fprintf(stderr, "venv command is not in correct format"); |
115 | 116 | free(current_line); |
@@ -140,38 +141,56 @@ char *get_pyenvcfg_command(const char *pyenv_cfg_path) { |
140 | 141 | exit(1); |
141 | 142 | } |
142 | 143 |
|
143 | | -int count_args(const char *cmd) { |
144 | | - char *copy = strdup(cmd); |
145 | | - int count = 0; |
146 | | - char *token = strtok(copy, " "); |
147 | | - while (token) { |
148 | | - count++; |
149 | | - token = strtok(NULL, " "); |
| 144 | +char **split_venv_command_into_args(const char *venv_command, int *argc_out) { |
| 145 | + if (access(venv_command, X_OK) == 0) { |
| 146 | + char **args = malloc(sizeof(char *)); |
| 147 | + if (!args) { |
| 148 | + fprintf(stderr, "allocation failed\n"); |
| 149 | + exit(1); |
| 150 | + } |
| 151 | + args[0] = strdup(venv_command); |
| 152 | + if (!args[0]) { |
| 153 | + fprintf(stderr, "allocation failed\n"); |
| 154 | + free(args); |
| 155 | + exit(1); |
| 156 | + } |
| 157 | + *argc_out = 1; |
| 158 | + return args; |
150 | 159 | } |
151 | 160 |
|
152 | | - free(copy); |
153 | | - return count; |
154 | | -} |
155 | | - |
156 | | -char **split_venv_command_into_args(const char *venv_command, int *argc_out) { |
| 161 | + wordexp_t expanded; |
| 162 | + int rc = wordexp(venv_command, &expanded, WRDE_NOCMD); |
| 163 | + if (rc != 0 || expanded.we_wordc == 0) { |
| 164 | + fprintf(stderr, "Failed to parse venvlauncher_command\n"); |
| 165 | + if (rc == 0) { |
| 166 | + wordfree(&expanded); |
| 167 | + } |
| 168 | + exit(1); |
| 169 | + } |
157 | 170 |
|
158 | | - char *copy = strdup(venv_command); |
159 | | - const int capacity = count_args(copy); |
| 171 | + const int capacity = (int) expanded.we_wordc; |
160 | 172 | char **args = malloc(capacity * sizeof(char *)); |
161 | 173 | if (!args) { |
162 | 174 | fprintf(stderr, "allocation failed\n"); |
163 | | - free(copy); |
| 175 | + wordfree(&expanded); |
164 | 176 | exit(1); |
165 | 177 | } |
166 | 178 |
|
167 | 179 | int count = 0; |
168 | | - char *current_token = strtok(copy, " "); |
169 | | - while (current_token) { |
170 | | - args[count++] = strdup(current_token); |
171 | | - current_token = strtok(NULL, " "); |
| 180 | + for (size_t i = 0; i < expanded.we_wordc; i++) { |
| 181 | + args[count] = strdup(expanded.we_wordv[i]); |
| 182 | + if (!args[count]) { |
| 183 | + fprintf(stderr, "allocation failed\n"); |
| 184 | + for (int j = 0; j < count; j++) { |
| 185 | + free(args[j]); |
| 186 | + } |
| 187 | + free(args); |
| 188 | + wordfree(&expanded); |
| 189 | + exit(1); |
| 190 | + } |
| 191 | + count++; |
172 | 192 | } |
173 | | - |
174 | | - free(copy); |
| 193 | + wordfree(&expanded); |
175 | 194 | assert(capacity == count); |
176 | 195 | *argc_out = count; |
177 | 196 | return args; |
|
0 commit comments