Skip to content

Commit fe6ff98

Browse files
Preamble: open .pex file from its canonical path (#292)
`argv[0]` might look like a relative path without actually existing relative to the current working directory - this is the case if (e.g.) the .pex file has been copied into a directory in `PATH` and the shell's `PATH` search behaviour is being relied upon to locate the .pex file. Get the canonical path to `argv[0]` before attempting to open it and read the preamble configuration within it.
1 parent d5a1121 commit fe6ff98

File tree

3 files changed

+21
-16
lines changed

3 files changed

+21
-16
lines changed

tools/please_pex/preamble/path.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@
1313
#include "util.h"
1414

1515
/*
16-
* get_pex_dir stores the canonical absolute path to the .pex file in pex_dir. It returns NULL on
16+
* get_pex_path stores the canonical absolute path to the .pex file in pex_dir. It returns NULL on
1717
* success and an error on failure.
1818
*/
19-
err_t *get_pex_dir(char **pex_dir) {
19+
err_t *get_pex_path(char **pex_path) {
2020
char *exe_path = NULL;
21-
char *exe_realpath = NULL;
22-
char *exe_dir = NULL;
2321
err_t *err = NULL;
2422

2523
#if defined(__linux__)
@@ -54,22 +52,20 @@ err_t *get_pex_dir(char **pex_dir) {
5452
#error "Unsupported operating system"
5553
#endif
5654

57-
if ((exe_realpath = realpath(exe_path, NULL)) == NULL) {
55+
if (((*pex_path) = realpath(exe_path, NULL)) == NULL) {
5856
err = err_from_errno("realpath");
5957
goto end;
6058
}
61-
62-
exe_dir = dirname(exe_realpath);
63-
if (((*pex_dir) = strdup(exe_dir)) == NULL) {
64-
err = err_from_errno("strdup");
65-
goto end;
66-
}
59+
log_debug("Canonical path of .pex file is %s", (*pex_path));
6760

6861
end:
6962
#ifndef __linux__
7063
FREE(exe_path);
7164
#endif
72-
FREE(exe_realpath);
65+
66+
if (err != NULL) {
67+
FREE(pex_path);
68+
}
7369

7470
return err;
7571
}
@@ -86,17 +82,19 @@ err_t *get_pex_dir(char **pex_dir) {
8682
* tree, get_plz_bin_path fails.
8783
*/
8884
err_t *get_plz_bin_path(char **path) {
85+
char *pex_path = NULL;
8986
char *pex_dir = NULL;
9087
char *tmp_dir = NULL;
9188
char *tmp_dir_realpath = NULL;
9289
size_t pex_dir_len = 0;
9390
size_t tmp_dir_len = 0;
9491
err_t *err = NULL;
9592

96-
if ((err = get_pex_dir(&pex_dir)) != NULL) {
97-
err = err_wrap("get_pex_dir", err);
93+
if ((err = get_pex_path(&pex_path)) != NULL) {
94+
err = err_wrap("get_pex_path", err);
9895
goto end;
9996
}
97+
pex_dir = dirname(pex_path);
10098

10199
if (getenv("PLZ_ENV") != NULL) {
102100
if ((tmp_dir = getenv("TMP_DIR")) == NULL) {
@@ -153,7 +151,7 @@ err_t *get_plz_bin_path(char **path) {
153151
}
154152

155153
end:
156-
FREE(pex_dir);
154+
FREE(pex_path);
157155
FREE(tmp_dir_realpath);
158156

159157
return err;

tools/please_pex/preamble/path.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "pexerror.h"
66

7+
err_t *get_pex_path(char **pex_path);
78
err_t *get_plz_bin_path(char **path);
89

910
#endif /* !__PATH_H__ */

tools/please_pex/preamble/preamble.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ static err_t *get_interpreters(const cJSON *config, strlist_t **interps) {
285285

286286
int main(int argc, char **argv) {
287287
err_t *err = NULL;
288+
char *pex_path = NULL;
288289
const cJSON *config = NULL;
289290
int config_args_len = 0;
290291
strlist_t *config_args = NULL;
@@ -301,7 +302,12 @@ int main(int argc, char **argv) {
301302
return 1;
302303
}
303304

304-
if ((err = get_config(argv[0], &config)) != NULL) {
305+
if ((err = get_pex_path(&pex_path)) != NULL) {
306+
log_fatal("Failed to resolve path to .pex file: %s", err_str(err));
307+
return 1;
308+
}
309+
310+
if ((err = get_config(pex_path, &config)) != NULL) {
305311
log_fatal("Failed to get .pex preamble configuration: %s", err_str(err));
306312
return 1;
307313
}

0 commit comments

Comments
 (0)