httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mar...@hyperreal.org
Subject cvs commit: apache-1.3/src/ap ap_execve.c
Date Wed, 23 Dec 1998 00:20:59 GMT
martin      98/12/22 16:20:59

  Modified:    src/ap   ap_execve.c
  Log:
  The hashbang emulation code was "forgetting" to use the default shell
  for scripts without a "#!/interpreter" staring line. Now it behaves
  like a regular shell or a regular OS's execve() implementation.
  
  Revision  Changes    Path
  1.10      +59 -17    apache-1.3/src/ap/ap_execve.c
  
  Index: ap_execve.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/ap/ap_execve.c,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ap_execve.c	1998/03/31 12:52:10	1.9
  +++ ap_execve.c	1998/12/23 00:20:58	1.10
  @@ -126,7 +126,8 @@
       }
       va_end(adummy);
   
  -    argv = (char **) malloc((argc + 2) * sizeof(*argv));
  +    if ((argv = (char **) malloc((argc + 2) * sizeof(*argv))) == NULL)
  +	return -1;
   
       /* Pass two --- copy the argument strings into the result space */
       va_start(adummy, argv0);
  @@ -143,10 +144,27 @@
       return ret;
   }
   
  +/* Count number of entries in vector "args", including the trailing NULL entry
  + */
  +static int
  +count_args(const char **args)
  +{
  +    int i;
  +    for (i = 0; args[i] != NULL; ++i) {
  +	continue;
  +    }
  +    return i+1;
  +}
  +
  +/* Emulate the execve call, respecting a #!/interpreter line if present.
  + * On "real" unixes, the kernel does this.
  + * We have to fiddle with the argv array to make it work on platforms
  + * which don't support the "hashbang" interpreter line by default.
  + */
   int ap_execve(const char *filename, const char *argv[],
   	      const char *envp[])
   {
  -    const char *argv0 = argv[0];
  +    const char **script_argv;
       extern char **environ;
   
       if (envp == NULL) {
  @@ -174,26 +192,50 @@
        * ELOOP  filename contains a circular reference (i.e., via a symbolic link)
        */
   
  -    if (errno == ENOEXEC
  -    /* Probably a script.
  -     * Have a look; if there's a "#!" header then try to emulate
  -     * the feature found in all modern OS's:
  -     * Interpret the line following the #! as a command line
  -     * in shell style.
  -     */
  -	&& (argv = hashbang(filename, argv)) != NULL) {
  +    if (errno == ENOEXEC) {
  +	/* Probably a script.
  +	 * Have a look; if there's a "#!" header then try to emulate
  +	 * the feature found in all modern OS's:
  +	 * Interpret the line following the #! as a command line
  +	 * in shell style.
  +	 */
  +	if ((script_argv = hashbang(filename, argv)) != NULL) {
  +
  +	    /* new filename is the interpreter to call */
  +	    filename = script_argv[0];
  +
  +	    /* Restore argv[0] as on entry */
  +	    if (argv[0] != NULL) {
  +		script_argv[0] = argv[0];
  +	    }
   
  -	/* new filename is the interpreter to call */
  -	filename = argv[0];
  +	    execve(filename, script_argv, envp);
   
  -	/* Restore argv[0] as on entry */
  -	if (argv0 != NULL) {
  -	    argv[0] = argv0;
  +	    free(script_argv);
   	}
  +	/*
  +	 * Script doesn't start with a hashbang line!
  +	 * So, try to have the default shell execute it.
  +	 * For this, the size of argv must be increased by one
  +	 * entry: the shell's name. The remaining args are appended.
  +	 */
  +	else {
  +	    int i = count_args(argv) + 1;   /* +1 for leading SHELL_PATH */
  +
  +	    if ((script_argv = malloc(sizeof(*script_argv) * i)) == NULL)
  +		return -1;
  +
  +	    script_argv[0] = SHELL_PATH;
  +
  +	    while (i > 0) {
  +		script_argv[i] = argv[i-1];
  +		--i;
  +	    }
   
  -	execve(filename, argv, envp);
  +	    execve(SHELL_PATH, script_argv, envp);
   
  -	free(argv);
  +	    free(script_argv);
  +	}
       }
       return -1;
   }
  
  
  

Mime
View raw message