home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3349 / shell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-17  |  2.5 KB  |  113 lines

  1. /*
  2.  * Copyright 1989, 1990, 1991, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Use, duplication, and disclosure prohibited without
  6.  * the express written permission of the author.
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <errno.h>
  11. #ifndef    BSD
  12. #include <string.h>
  13. #include <memory.h>
  14. #else
  15. #include <strings.h>
  16. #define    strchr    index
  17. #define    strrchr    rindex
  18. #endif
  19. #include "config.h"
  20.  
  21. #ifndef    lint
  22. static    char    _sccsid[] = "@(#)shell.c    3.2    07:55:08    2/6/91";
  23. #endif
  24.  
  25. extern    char    *newenvp[];
  26.  
  27. /*
  28.  * shell - execute the named program
  29.  *
  30.  *    shell begins by trying to figure out what argv[0] is going to
  31.  *    be for the named process.  The user may pass in that argument,
  32.  *    or it will be the last pathname component of the file with a
  33.  *    '-' prepended.  The first attempt is to just execute the named
  34.  *    file.  If the errno comes back "ENOEXEC", the file is assumed
  35.  *    at first glance to be a shell script.  The first two characters
  36.  *    must be "#!", in which case "/bin/sh" is executed to process
  37.  *    the file.  If all that fails, give up in disgust ...
  38.  */
  39.  
  40. void    shell (file, arg)
  41. char    *file;
  42. char    *arg;
  43. {
  44.     char    arg0[BUFSIZ];
  45.     FILE    *fp;
  46.     char    *path;
  47.     int    err;
  48.  
  49.     if (file == (char *) 0)
  50.         exit (1);
  51.  
  52.     /*
  53.      * The argv[0]'th entry is usually the path name, but
  54.      * for various reasons the invoker may want to override
  55.      * that.  So, we determine the 0'th entry only if they
  56.      * don't want to tell us what it is themselves.
  57.      */
  58.  
  59.     if (arg == (char *) 0) {
  60.         if (path = strrchr (file, '/'))
  61.             path++;
  62.         else
  63.             path = file;
  64.  
  65.         (void) strcpy (arg0 + 1, path);
  66.         arg0[0] = '-';
  67.         arg = arg0;
  68.     }
  69. #ifndef    NDEBUG
  70.     printf ("Executing shell %s\n", file);
  71. #endif
  72.  
  73.     /*
  74.      * First we try the direct approach.  The system should be
  75.      * able to figure out what we are up to without too much
  76.      * grief.
  77.      */
  78.  
  79.     execle (file, arg, (char *) 0, newenvp);
  80.     err = errno;
  81.  
  82.     /*
  83.      * It is perfectly OK to have a shell script for a login
  84.      * shell, and this code attempts to support that.  It
  85.      * relies on the standard shell being able to make sense
  86.      * of the "#!" magic number.
  87.      */
  88.  
  89.     if (err == ENOEXEC) {
  90.         if (fp = fopen (file, "r")) {
  91.             if (getc (fp) == '#' && getc (fp) == '!') {
  92.                 fclose (fp);
  93.                 execle ("/bin/sh", "sh",
  94.                     file, (char *) 0, newenvp);
  95.                 err = errno;
  96.             } else {
  97.                 fclose (fp);
  98.             }
  99.         }
  100.     }
  101.  
  102.     /*
  103.      * Obviously something is really wrong - I can't figure out
  104.      * how to execute this stupid shell, so I might as well give
  105.      * up in disgust ...
  106.      */
  107.  
  108.     sprintf (arg0, "Cannot execute %s", file);
  109.     errno = err;
  110.     perror (arg0);
  111.     exit (err);
  112. }
  113.