patch-1.3.71 linux/fs/binfmt_script.c
Next file: linux/fs/block_dev.c
Previous file: linux/fs/binfmt_elf.c
Back to the patch index
Back to the overall index
- Lines: 129
- Date:
Sat Mar 2 13:18:47 1996
- Orig file:
v1.3.70/linux/fs/binfmt_script.c
- Orig date:
Thu Jan 1 02:00:00 1970
diff -u --recursive --new-file v1.3.70/linux/fs/binfmt_script.c linux/fs/binfmt_script.c
@@ -0,0 +1,128 @@
+/*
+ * 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, *interp, *i_name, *i_arg, *page;
+ int retval, offset;
+ 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 || *cp == '\0')
+ return -ENOEXEC; /* No interpreter name found */
+ interp = 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;
+ /*
+ * 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.
+ */
+ if (bprm->argc) {
+ offset = bprm->p % PAGE_SIZE;
+ page = (char*)bprm->page[bprm->p/PAGE_SIZE];
+ while(bprm->p++,*(page+offset++))
+ if(offset==PAGE_SIZE){
+ offset=0;
+ page = (char*)bprm->page[bprm->p/PAGE_SIZE];
+ }
+ bprm->argc--;
+ }
+ 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.
+ * Note that we use open_namei() as the name is now in kernel
+ * space, and we don't need to copy it.
+ */
+ 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
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this