summaryrefslogtreecommitdiffstats
path: root/fs/binfmt_script.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
committer <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
commitbeb116954b9b7f3bb56412b2494b562f02b864b1 (patch)
tree120e997879884e1b9d93b265221b939d2ef1ade1 /fs/binfmt_script.c
parent908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff)
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'fs/binfmt_script.c')
-rw-r--r--fs/binfmt_script.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
new file mode 100644
index 000000000..9050a106c
--- /dev/null
+++ b/fs/binfmt_script.c
@@ -0,0 +1,120 @@
+/*
+ * linux/fs/binfmt_script.c
+ *
+ * Copyright (C) 1996 Martin von Löwis
+ * original #!-checking implemented by tytso.
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/malloc.h>
+#include <linux/binfmts.h>
+
+static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
+{
+ char *cp, *i_name, *i_name_start, *i_arg;
+ char interp[128];
+ int retval;
+ if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang))
+ return -ENOEXEC;
+ /*
+ * This section does the #! interpretation.
+ * Sorta complicated, but hopefully it will work. -TYT
+ */
+
+ bprm->sh_bang++;
+ iput(bprm->inode);
+ bprm->dont_iput=1;
+
+ bprm->buf[127] = '\0';
+ if ((cp = strchr(bprm->buf, '\n')) == NULL)
+ cp = bprm->buf+127;
+ *cp = '\0';
+ while (cp > bprm->buf) {
+ cp--;
+ if ((*cp == ' ') || (*cp == '\t'))
+ *cp = '\0';
+ else
+ break;
+ }
+ for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
+ if (*cp == '\0')
+ return -ENOEXEC; /* No interpreter name found */
+ i_name_start = i_name = cp;
+ i_arg = 0;
+ for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
+ if (*cp == '/')
+ i_name = cp+1;
+ }
+ while ((*cp == ' ') || (*cp == '\t'))
+ *cp++ = '\0';
+ if (*cp)
+ i_arg = cp;
+ strcpy (interp, i_name_start);
+ /*
+ * OK, we've parsed out the interpreter name and
+ * (optional) argument.
+ * Splice in (1) the interpreter's name for argv[0]
+ * (2) (optional) argument to interpreter
+ * (3) filename of shell script (replace argv[0])
+ *
+ * This is done in reverse order, because of how the
+ * user environment and arguments are stored.
+ */
+ remove_arg_zero(bprm);
+ bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2);
+ bprm->argc++;
+ if (i_arg) {
+ bprm->p = copy_strings(1, &i_arg, bprm->page, bprm->p, 2);
+ bprm->argc++;
+ }
+ bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
+ bprm->argc++;
+ if (!bprm->p)
+ return -E2BIG;
+ /*
+ * OK, now restart the process with the interpreter's inode.
+ */
+ bprm->filename = interp;
+ retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
+ if (retval)
+ return retval;
+ bprm->dont_iput=0;
+ retval=prepare_binprm(bprm);
+ if(retval<0)
+ return retval;
+ return search_binary_handler(bprm,regs);
+}
+
+static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
+{
+ int retval;
+ MOD_INC_USE_COUNT;
+ retval = do_load_script(bprm,regs);
+ MOD_DEC_USE_COUNT;
+ return retval;
+}
+
+struct linux_binfmt script_format = {
+#ifndef MODULE
+ NULL, 0, load_script, NULL, NULL
+#else
+ NULL, &mod_use_count_, load_script, NULL, NULL
+#endif
+};
+
+int init_script_binfmt(void) {
+ return register_binfmt(&script_format);
+}
+
+#ifdef MODULE
+int init_module(void)
+{
+ return init_script_binfmt();
+}
+
+void cleanup_module( void) {
+ unregister_binfmt(&script_format);
+}
+#endif