Created
January 13, 2009 05:40
-
-
Save pete/46344 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| cter.c | |
| Elmore wins prize for most hacky, unsafe, ugly semi-implementation of a C | |
| interpreter. Took an hour to write, took almost as long to do a full run of | |
| the stress test. Compared to its trim 202 megs of actual memory used after | |
| 21,840 printf()s ran (each from its own separate .so), it seems obscene that | |
| the cost in virtual memory was in excess of 40 gigs (at which point Linux | |
| became angry with me and refused to allow my little program to continue). | |
| Was basically a proof-of-concept for something completely unrelated to | |
| C. Note the lack of calls to dlclose(): this was neither an accident nor | |
| laziness. (All the other things that never got cleaned up, though? Those | |
| were laziness.) | |
| I highly recommend you use rlwrap if you want to run this interactively. | |
| cc -pipe -fPIC -DPIC -rdynamic -o cter cter.c -ldl | |
| -rdynamic and -ldl are the two important ones. | |
| */ | |
| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include <sys/stat.h> | |
| #include <sys/types.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| #include <dlfcn.h> | |
| /* | |
| We are so unconcerned with buffer overflows that it is ridiculous. | |
| */ | |
| #define BIG_ENOUGH 4096 | |
| static int is[1000]; | |
| static void *ps[1000]; | |
| int *get_is() { return is; } | |
| void **get_ps() { return ps; } | |
| int main(int argc, char *argv[]) | |
| { | |
| FILE *outfile; | |
| void (*f)(); | |
| void *genhan; | |
| char name[BIG_ENOUGH], | |
| sourcename[4 + BIG_ENOUGH + 2], | |
| soname[4 + BIG_ENOUGH + 3], | |
| cmd[BIG_ENOUGH], | |
| line[BIG_ENOUGH]; | |
| unsigned long int i = 1, ttyp = isatty(0); | |
| if(stat("sos", NULL) < 0) | |
| mkdir("sos", 0755); | |
| while(1) { | |
| sprintf(name, "cter%d", i); | |
| sprintf(sourcename, "sos/%s.c", name); | |
| sprintf(soname, "sos/%s.so", name); | |
| if(ttyp) { printf("%4d > ", i); fflush(stdout); } | |
| sprintf(*argv, "cter(%d)", i); | |
| /* I told you we didn't care about buffer overflows. */ | |
| if(!gets(line)) { // <-- See? | |
| fprintf(stderr, __FILE__ ":%d: Oops, failgets().\n", | |
| __LINE__); | |
| fflush(stderr); | |
| exit(0); | |
| } | |
| outfile = fopen(sourcename, "w"); | |
| if(!outfile) { | |
| fprintf(stderr, __FILE__ ":%d: Oops, failwrite.\n", | |
| __LINE__); | |
| fflush(stderr); | |
| continue; | |
| } | |
| fprintf(outfile, | |
| "#include <stdio.h>\n" | |
| "#include <stdlib.h>\n" | |
| "#include <math.h>\n" | |
| "#include <unistd.h>\n" | |
| "#include <time.h>\n" | |
| "\n" | |
| "int *get_is();\n" | |
| "void *get_ps();\n" | |
| "\n" | |
| "void f() {\n" | |
| "int *is = get_is();\nvoid **ps = get_ps();\n" | |
| "\n" | |
| "\t%s;\n" | |
| "}\n", | |
| line); | |
| fclose(outfile); | |
| sprintf(cmd, "gcc %s -o %s %s " | |
| "-pipe -shared -fPIC -DPIC -DREENTRANT", | |
| getenv("CFLAGS"), soname, sourcename); | |
| // if(ttyp) puts(cmd); | |
| system(cmd); | |
| genhan = dlopen(soname, RTLD_LAZY); | |
| if(!genhan) { | |
| fprintf(stderr, __FILE__ | |
| ":%d: Oops, failhandle (%s).\n", | |
| __LINE__, dlerror()); | |
| fflush(stderr); | |
| continue; | |
| } | |
| f = (void (*)())dlsym(genhan, "f"); | |
| if(!f) { | |
| fprintf(stderr, __FILE__ ":%d: Oops, failfunction.\n", | |
| __LINE__); | |
| fflush(stderr); | |
| continue; | |
| } | |
| f(); | |
| i++; | |
| } | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment