-
-
Save phlummox/80c79c679400d2f2076f7b72280a7dca to your computer and use it in GitHub Desktop.
Interpreter path relative to script location in shebang
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Helper program for resolving the path to the interpreter executable | |
relative to the script location in shebangs. | |
Sample usage: | |
#!/usr/bin/delegate ../my-virtualenv/bin/python | |
import sys | |
def main(): | |
print sys.executable | |
if __name__ == '__main__': | |
main() | |
*/ | |
#include <stdio.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#define MAX_PATH_SIZE 4096 | |
int main(int argc, char **argv) { | |
if (argc < 3) { | |
fprintf(stderr, "usage: %s <interpreter> <file>\n", argv[0]); | |
return -1; | |
} | |
char *interp_path = argv[1]; | |
char *script_path = argv[2]; | |
int ret; | |
if (strchr(interp_path, '/') == NULL) { | |
ret = execvp(interp_path, argv + 1); | |
} else if (interp_path[0] == '/') { | |
ret = execv(interp_path, argv + 1); | |
} else { | |
char *base_high = strrchr(script_path, '/'); | |
size_t base_len = base_high != NULL ? base_high - script_path + 1 : 0; | |
size_t interp_len = strlen(interp_path); | |
if (base_len + interp_len < MAX_PATH_SIZE) { | |
char buf[MAX_PATH_SIZE]; | |
memcpy(buf, script_path, base_len); | |
memcpy(buf + base_len, interp_path, interp_len + 1); // with '\0' | |
argv[1] = buf; | |
ret = execv(buf, argv + 1); | |
} else { | |
errno = ENAMETOOLONG; | |
ret = -1; | |
} | |
} | |
perror(argv[0]); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment