Annotation of coherent/b/lib/libc/sys/execve.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * libc/sys/i386/execve.c
        !             3:  * This version of execve() understands "#!interpreter [ arg ...]\n" lines.
        !             4:  * The original version of this source was "iexec.c" Version 1.6,
        !             5:  * written by David MacKenzie <[email protected]> and placed in the public domain.
        !             6:  * Extensively modified by steve 8/12/92 for COHERENT.
        !             7:  */
        !             8: 
        !             9: #include <errno.h>
        !            10: #include <string.h>
        !            11: #include <stdlib.h>
        !            12: #include <fcntl.h>
        !            13: 
        !            14: #define MAXLINELEN     512     /* bytes to read from first line of a script */
        !            15: #define        iswhite(c)      ((c) == ' ' || (c) == '\t')     /* whitespace */
        !            16: 
        !            17: /* Try _execve(), i.e. sys exec; then try running as a script if it fails. */
        !            18: int
        !            19: execve(cmd, argv, envp) char *cmd; char **argv; char **envp;
        !            20: {
        !            21: 
        !            22:        if (_execve(cmd, argv, envp) == -1 && errno == ENOEXEC) {
        !            23:                script_execve(cmd, argv, envp);
        !            24:                errno = ENOEXEC;
        !            25:        }
        !            26:        return -1;
        !            27: }
        !            28: 
        !            29: /*
        !            30:  * If 'file' is a script which begins "#!interp [ arg ...]\n",
        !            31:  * set 'interp' to the name of the program that should run it
        !            32:  * and 'int_args' to the given args (or NULL if none).
        !            33:  * Create a new argument list containing 'interp',
        !            34:  * expanded 'int_args' (if non-NULL), 'file', and the original argv.
        !            35:  * Then try to run 'interp' with the new argument list and 'envp'.
        !            36:  * Return -1 if it fails.
        !            37:  */
        !            38: static
        !            39: int
        !            40: script_execve(file, argv, envp) char *file, **argv, **envp;
        !            41: {
        !            42:        char line[MAXLINELEN + 1];
        !            43:        register char *cp, **ap, **nargv;
        !            44:        char *interp, *int_args;
        !            45:        register int argc, fd, n;
        !            46:        char c, inquote;
        !            47: 
        !            48:        /* Open the file, read a chunk, see how it starts. */
        !            49:        if ((fd = open(file, O_RDONLY, 0)) == -1)
        !            50:                return -1;
        !            51:        n = read(fd, line, MAXLINELEN);
        !            52:        if (close(fd) == -1 || n < 4 || line[0] != '#' || line[1] != '!')
        !            53:                return -1;
        !            54: 
        !            55:        /* The first line looks appropriate. */
        !            56:        line[n] = '\0';                         /* NUL-terminate */
        !            57:        if ((cp = strchr(line, '\n')) == NULL)
        !            58:                return -1;
        !            59:        *cp = '\0';                             /* zap newline */
        !            60: 
        !            61:        /* Find interpreter name and args. */
        !            62:        for (cp = line + 2; iswhite(*cp); ++cp)
        !            63:                ;                               /* skip whitespace after #! */
        !            64:        if (*cp == '\0')
        !            65:                return -1;
        !            66:        interp = cp;                            /* interpreter name */
        !            67:        for (; *cp != '\0' && !iswhite(*cp); ++cp)
        !            68:                ;                               /* scan to whitespace or NUL */
        !            69:        if (*cp == '\0')
        !            70:                int_args = NULL;
        !            71:        else {
        !            72:                *cp++ = '\0';                   /* NUL-terminate name */
        !            73:                int_args = cp;                  /* interpreter args */
        !            74:        }
        !            75: 
        !            76:        /* Find new arg count max and allocate space for new argv. */
        !            77:        for (argc = 2, ap = argv; *ap != NULL; ++ap)
        !            78:                ++argc;                         /* count old argv args + 1 */
        !            79:        if (int_args != NULL)
        !            80:                argc += strlen(int_args)/2;     /* add max int_args args */
        !            81:        if ((nargv = (char **)malloc(sizeof(char *) * argc)) == NULL)
        !            82:                return -1;
        !            83: 
        !            84:        /* Initialize the new argv. */
        !            85:        argc = 0;
        !            86:        nargv[argc++] = interp;                 /* interpreter name */
        !            87:        if (int_args != NULL) {
        !            88: 
        !            89:                /* Add whitespace-separated args from int_args. */
        !            90:                for (cp = int_args; (c = *cp) != '\0'; ) {
        !            91:                        while (iswhite(c))
        !            92:                                c = *++cp;      /* skip whitespace */
        !            93:                        if (c == '\0')
        !            94:                                break;
        !            95:                        else if (c == '\'' || c == '"') {
        !            96:                                inquote = c;    /* quoted arg */
        !            97:                                ++cp;
        !            98:                        } else
        !            99:                                inquote = 0;
        !           100:                        nargv[argc++] = cp;     /* start new arg */
        !           101:                        while ((c = *cp++) != '\0') {
        !           102:                                if (!inquote && iswhite(c))
        !           103:                                        break;
        !           104:                                else if (inquote && c == inquote) {
        !           105:                                        inquote = cp[-1] = '\0';        /* zap close quote */
        !           106:                                        c = *cp++;      /* next char */
        !           107:                                        break;
        !           108:                                }
        !           109:                        }
        !           110:                        if (inquote) {
        !           111:                                free(nargv);
        !           112:                                return -1;      /* fail on missing close quote */
        !           113:                        } else if (c == '\0')
        !           114:                                break;
        !           115:                        else
        !           116:                                cp[-1] = '\0';  /* NUL-terminate arg */
        !           117:                }
        !           118:        }
        !           119:        nargv[argc++] = file;                   /* script name */
        !           120: 
        !           121:        /* Copy the old arguments. */
        !           122:        for (ap = argv + 1; *ap != NULL; ++ap)
        !           123:                nargv[argc++] = *ap;
        !           124:        nargv[argc] = NULL;
        !           125: 
        !           126:        /* Go for smoke. */
        !           127:        _execve(interp, nargv, envp);
        !           128:        free(nargv);
        !           129:        return -1;
        !           130: }
        !           131: 
        !           132: /* end of libc/sys/i386/execve.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.