root/fs/binfmt_script.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. do_load_script
  2. load_script
  3. init_script_binfmt
  4. init_module
  5. cleanup_module

   1 /*
   2  *  linux/fs/binfmt_script.c
   3  *
   4  *  Copyright (C) 1996  Martin von Löwis
   5  *  original #!-checking implemented by tytso.
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <linux/string.h>
  10 #include <linux/stat.h>
  11 #include <linux/malloc.h>
  12 #include <linux/binfmts.h>
  13 
  14 static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
  15 {
  16         char *cp, *interp, *i_name, *i_arg, *page;
  17         int retval, offset;
  18         if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) 
  19                 return -ENOEXEC;
  20         /*
  21          * This section does the #! interpretation.
  22          * Sorta complicated, but hopefully it will work.  -TYT
  23          */
  24 
  25         bprm->sh_bang++;
  26         iput(bprm->inode);
  27         bprm->dont_iput=1;
  28 
  29         bprm->buf[127] = '\0';
  30         if ((cp = strchr(bprm->buf, '\n')) == NULL)
  31                 cp = bprm->buf+127;
  32         *cp = '\0';
  33         while (cp > bprm->buf) {
  34                 cp--;
  35                 if ((*cp == ' ') || (*cp == '\t'))
  36                         *cp = '\0';
  37                 else
  38                         break;
  39         }
  40         for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
  41         if (!cp || *cp == '\0') 
  42                 return -ENOEXEC; /* No interpreter name found */
  43         interp = i_name = cp;
  44         i_arg = 0;
  45         for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
  46                 if (*cp == '/')
  47                         i_name = cp+1;
  48         }
  49         while ((*cp == ' ') || (*cp == '\t'))
  50                 *cp++ = '\0';
  51         if (*cp)
  52                 i_arg = cp;
  53         /*
  54          * OK, we've parsed out the interpreter name and
  55          * (optional) argument.
  56          * Splice in (1) the interpreter's name for argv[0]
  57          *           (2) (optional) argument to interpreter
  58          *           (3) filename of shell script (replace argv[0])
  59          *
  60          * This is done in reverse order, because of how the
  61          * user environment and arguments are stored.
  62          */
  63         if (bprm->argc) {
  64                 offset = bprm->p % PAGE_SIZE;
  65                 page = (char*)bprm->page[bprm->p/PAGE_SIZE];
  66                 while(bprm->p++,*(page+offset++))
  67                         if(offset==PAGE_SIZE){
  68                                 offset=0;
  69                                 page = (char*)bprm->page[bprm->p/PAGE_SIZE];
  70                         }
  71                 bprm->argc--;
  72         }
  73         bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2);
  74         bprm->argc++;
  75         if (i_arg) {
  76                 bprm->p = copy_strings(1, &i_arg, bprm->page, bprm->p, 2);
  77                 bprm->argc++;
  78         }
  79         bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
  80         bprm->argc++;
  81         if (!bprm->p) 
  82                 return -E2BIG;
  83         /*
  84          * OK, now restart the process with the interpreter's inode.
  85          * Note that we use open_namei() as the name is now in kernel
  86          * space, and we don't need to copy it.
  87          */
  88         retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
  89         if (retval)
  90                 return retval;
  91         bprm->dont_iput=0;
  92         retval=prepare_binprm(bprm);
  93         if(retval<0)
  94                 return retval;
  95         return search_binary_handler(bprm,regs);
  96 }
  97 
  98 static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100         int retval;
 101         MOD_INC_USE_COUNT;
 102         retval = do_load_script(bprm,regs);
 103         MOD_DEC_USE_COUNT;
 104         return retval;
 105 }
 106 
 107 struct linux_binfmt script_format = {
 108 #ifndef MODULE
 109         NULL, 0, load_script, NULL, NULL
 110 #else
 111         NULL, &mod_use_count_, load_script, NULL, NULL
 112 #endif
 113 };
 114 
 115 int init_script_binfmt(void) {
     /* [previous][next][first][last][top][bottom][index][help] */
 116         return register_binfmt(&script_format);
 117 }
 118 
 119 #ifdef MODULE
 120 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 121 {
 122         return init_script_binfmt();
 123 }
 124 
 125 void cleanup_module( void) {
     /* [previous][next][first][last][top][bottom][index][help] */
 126         unregister_binfmt(&script_format);
 127 }
 128 #endif

/* [previous][next][first][last][top][bottom][index][help] */