commit aead84be5857aecb84cf961972e04ab63a84eafb from: Omar Polo date: Mon Jan 10 11:37:30 2022 UTC 9ps: chdir to script basename before including it In the *-suite.9ps files we have stuff like `include "lib.9ps"`, but when ninepscript is called from the *root* directory that include will fail. This is a workaround to allow including file relatively and allows to run the regress suite. commit - 3656a5b1eb8cc258077306e04015157caca4d17d commit + aead84be5857aecb84cf961972e04ab63a84eafb blob - 6e080e055abaead5828c1c95ebd85c1aa530add6 blob + f3bf7eddb1d35506e7f7db3055d8ed8654ec8a6b --- ninepscript/parse.y +++ ninepscript/parse.y @@ -27,13 +27,16 @@ #include #include +#include #include +#include #include #include #include #include #include #include +#include #include "log.h" #include "kami.h" @@ -667,9 +670,27 @@ popfile(void) void loadfile(const char *path) { - int errors; + int pwdfd, errors; + char p[PATH_MAX], *dir; - file = pushfile(path); + /* + * Ugly workaround: we really need a smarter `include', one that + * is able to resolve path relatively from the currently processed + * file. The workaround consist to save the current directory, + * chdir(2) to the script dirname and then jump back by mean of + * fchdir. + */ + + if ((pwdfd = open(".", O_RDONLY|O_DIRECTORY)) == -1) + err(1, "can't open ."); + strlcpy(p, path, sizeof(p)); + dir = dirname(p); + if (chdir(dir) == -1) + err(1, "chdir %s", dir); + + /* XXX: include the *basename* of the file after chdir */ + strlcpy(p, path, sizeof(p)); + file = pushfile(basename(p)); if (file == NULL) err(1, "pushfile"); topfile = file; @@ -678,6 +699,9 @@ loadfile(const char *path) errors = file->errors; popfile(); + fchdir(pwdfd); + close(pwdfd); + if (errors) errx(1, "can't load %s because of errors", path); }