Exemplo n.º 1
0
/* return codes: -1 is error; 0 is everything OK but did not find shebang;
   if shebang is found, does an exec */
static int attempt_shebang_launch(char *program_to_launch, char *origin, char *profile_bin_dir,
                                  int argc, char **argv) {
    /* Attempt to open the file to scan for a shebang, which we handle
       ourself.  (If a script is executable but not readable then no
       interpreter can read it anyway; assume such a thing doesn't
       exist.) */
    FILE *f;
    char shebang[SHEBANG_MAX], interpreter[SHEBANG_MAX], arg[SHEBANG_MAX];
    char *r, *s, *interpreter_part, *arg_part = NULL;
    char **new_argv;
    char **p;
    /* read first line */
    if ((f = fopen(program_to_launch, "r")) == NULL) return -1;
    r = fgets(shebang, SHEBANG_MAX, f);
    fclose(f);
    if (r == NULL) return -1;
    /* Reference: http://homepages.cwi.nl/~aeb/std/hashexclam.html */
    /* TODO: There's a Mac OS X special case on interpreter handling.. */

    /* shebang header */
    if (r[0] != '#' || r[1] != '!') return 0; /* shebang not present return code */
    r += 2;
    skip_whites(&r);
    if (r == '\0') return -1;
    interpreter_part = r;
    skip_nonwhites(&r);
    if (*r != '\0') {
        *r = '\0'; /* terminate 'interpreter' string */
        ++r;
        skip_whites(&r);
        /* there may be an argument: */
        arg_part = r;
        rstrip(arg_part);
    }
    if (expandvars(interpreter, interpreter_part, origin, profile_bin_dir, SHEBANG_MAX) != 0) return -1;
    if (arg_part != NULL) {
        if (expandvars(arg, arg_part, origin, profile_bin_dir, SHEBANG_MAX) != 0) return -1;
    } else {
        arg[0] = '\0';
    }
    if (debug) {
        fprintf(stderr, "%sshebang_cmd=%s\n", debug_header, interpreter);
        fprintf(stderr, "%sshebang_arg=%s\n", debug_header, arg);
    }

    /* Done parsing, do launch */
    new_argv = malloc(sizeof(char*) * (argc + 3));
    p = new_argv;
    p++; /* we'll set interpreter below */
    if (arg[0]) *p++ = arg;
    /* substitute argv[0] with program_to_launch */
    argv++;
    *p++ = program_to_launch;
    while (*argv) *p++ = *argv++;
    *p = NULL;
    
    /* The interpreter string may contain : to separate many possible interpreters;
       try them in turn. */
    s = interpreter;
    for (;;) {
        r = strstr(s, ":");
        if (r != NULL) r[0] = '\0';
        new_argv[0] = s;
        execv(s, new_argv);
        if (r == NULL) break;
        s = r + 1;
    }
    /* failed to execute */
    free(new_argv);
    return -1;
}
Exemplo n.º 2
0
std::string path::expand(const std::string &path) {
    return normpath(expandvars(expanduser(path)));
}