diff options
author | Robert de Bath <rdebath@poboxes.com> | 1996-05-31 21:33:17 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:30:46 +0200 |
commit | e85ee07172eccafd9441362e774f7b184810d008 (patch) | |
tree | 5dc12259ab7a61b12d9df284fe58ad5cb312c526 /elksemu/binfmt_elks.c | |
parent | dcc973ea3e31710429858c99d4f040334ac67c06 (diff) | |
download | dev86-e85ee07172eccafd9441362e774f7b184810d008.tar.gz |
Import Dev86-0.0.6.tar.gzv0.0.6
Diffstat (limited to 'elksemu/binfmt_elks.c')
-rw-r--r-- | elksemu/binfmt_elks.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/elksemu/binfmt_elks.c b/elksemu/binfmt_elks.c new file mode 100644 index 0000000..09e5a29 --- /dev/null +++ b/elksemu/binfmt_elks.c @@ -0,0 +1,118 @@ +/* + * linux/fs/binfmt_elks.c + * + * Copyright (C) 1996 Martin von Löwis + * original #!-checking implemented by tytso. + * ELKS hack added by Chad Page... + * Cleaned up some more by Robert de Bath + * I can't make it work with 1.2.13 tho! :-( + */ + +#include <linux/module.h> +#ifndef LINUX_VERSION_CODE +#include <linux/version.h> +#endif +#include <linux/string.h> +#include <linux/stat.h> +#include <linux/malloc.h> +#include <linux/binfmts.h> + +static int do_load_elksaout(struct linux_binprm *bprm,struct pt_regs *regs) +{ + char *cp, *interp, *i_name, *i_arg; + int retval; + + /* What a horrible hack! :-) */ + if ((bprm->buf[0] != 1) || (bprm->buf[1] != 3) || + (bprm->buf[2] != 0x20) || (bprm->buf[3] != 4) || + bprm->sh_bang) + return -ENOEXEC; + + bprm->sh_bang++; + iput(bprm->inode); +#if LINUX_VERSION_CODE >= 0x010300 + bprm->dont_iput=1; +#endif + + interp = "/lib/elksemu"; + i_name = interp; + i_arg = 0; + + for (cp=i_name; *cp && (*cp != ' ') && (*cp != '\t'); cp++) { + if (*cp == '/') + i_name = cp+1; + } + + /* + * 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. + * 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; +#if LINUX_VERSION_CODE >= 0x010300 + bprm->dont_iput=0; +#endif + retval=prepare_binprm(bprm); + if(retval<0) + return retval; + return search_binary_handler(bprm,regs); +} + +static int load_elksaout(struct linux_binprm *bprm,struct pt_regs *regs) +{ + int retval; + MOD_INC_USE_COUNT; + retval = do_load_elksaout(bprm,regs); + MOD_DEC_USE_COUNT; + return retval; +} + +struct linux_binfmt elksaout_format = { +#ifndef MODULE + NULL, 0, load_elksaout, NULL, NULL +#else + NULL, &mod_use_count_, load_elksaout, NULL, NULL +#endif +}; + +int init_elksaout_binfmt(void) { + return register_binfmt(&elksaout_format); +} + +#ifdef MODULE +#if LINUX_VERSION_CODE < 0x010300 +#include <linux/version.h> +char kernel_version[] = UTS_RELEASE; +#endif +int init_module(void) +{ + return init_elksaout_binfmt(); +} + +void cleanup_module( void) { + unregister_binfmt(&elksaout_format); +} +#endif |