Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!ames!sun-barr!texsun!pitstop!sundc!seismo!uunet!mcvax!hp4nl!phigate!philmds!leo From: leo@philmds.UUCP (Leo de Wit) Newsgroups: comp.sys.atari.st Subject: Preloading revised Message-ID: <1028@philmds.UUCP> Date: 11 May 89 07:10:39 GMT Reply-To: leo@philmds.UUCP (Leo de Wit) Organization: Philips I&E DTS Eindhoven Lines: 167 For those who might be interested, here's a demo program that preloads some programs (whose pathnames are supplied on the command line), then executes them. It uses the Pexec variants 3, 4 and 5 to do so. Compiled with Lattice C. Enjoy! Leo. ---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8 /* preload.c */ /* Demo and routines for preloading programs */ /* Author: L.J.M. de Wit - 05/11/89 */ /* This source and its use are PD */ #include #include #define MAXLOADED 16 #define DEFMNEED 0x1200 /* default memory reservation for heap + stack */ #define ARGSTRLEN 122 #define FAIL 1 #define OK 0 typedef struct img_id { char name[64]; long basepag; } img_id; int _mneed = 20000; /* This program is Mshrinked to this size by Lattice C */ img_id load_img[MAXLOADED]; int nloaded = 0; /* Main is a demo: all args are taken to be paths of executables; they're * preloaded, then executed 10 times, then unloaded. */ main(argc,argv) int argc; char **argv; { int i,j; for (i = 1; i < argc; i++) { if (preload(argv[i],0) == FAIL) { exit(1); } } printf("Preloaded all\n"); for (j = 0; j < 10; j++) { for (i = 1; i < argc; i++) { printf("Executing \"%s\" for the %dth time\n",argv[i],j+1); execute(argv[i],""); } } for (i = 1; i < argc; i++) { if (unload(argv[i]) == FAIL) { exit(1); } } } int preload(progname,memneed) /* Preload an executable */ char *progname; long memneed; { long basaddr; int i, fd; if (memneed == 0) { memneed = DEFMNEED; /* Default mem for heap and stack */ } for (i = 0; i < MAXLOADED; i++) { if (load_img[i].basepag == 0L) { /* Found an unused slot */ break; } } if (i == MAXLOADED) { /* All slots in use */ fprintf(stderr,"Max no. of programs (%d) loaded\n",MAXLOADED); return FAIL; } if ((fd = Fopen(progname,0)) < 0) { /* Progname must exist as file */ fprintf(stderr,"Cannot open %s\n",progname); return FAIL; } Fclose(fd); basaddr = Pexec(3,progname,"",(char *)0); if (basaddr == -66) { /* Program file in wrong format */ Fclose(fd); /* This fixes a GEMDOS bug */ fprintf(stderr,"%s not in TOS program format\n",progname); return FAIL; } if (basaddr < 0) { /* Any other error */ fprintf(stderr,"%s failed with error code %d\n",progname,basaddr); return FAIL; } strcpy(load_img[i].name,progname); load_img[i].basepag = basaddr; /* Now add to memneed the program's own requirements */ memneed += 0x100 + /* Base page */ ((long *)basaddr)[3] + /* Text length */ ((long *)basaddr)[5] + /* Data length */ ((long *)basaddr)[7] + /* Bss length */ 1; /* For even adjustment */ memneed &= ~1; /* Make it even */ Mshrink(basaddr,memneed); /* Now shrink to required size */ return OK; } int unload(progname) /* Unload an executable */ char *progname; { int i; for (i = 0; i < MAXLOADED; i++) { if ((load_img[i].basepag != 0L) && !strcmp(load_img[i].name,progname)) { /* Found it */ Mfree(load_img[i].basepag); /* Free it */ load_img[i].basepag = 0L; /* Mark slot unused */ return OK; } } fprintf(stderr,"%s: command was not loaded\n",progname); return FAIL; } int execute(cmd,tail) /* Execute a preloaded program */ char *cmd, *tail; /* Prog. path & argstring */ { int err_co, i; long bp, newbp; char newtail[128]; int v; for (i = 0; i < MAXLOADED; i++) { if ((load_img[i].basepag != 0L) && !strcmp(cmd,load_img[i].name)) { /* Found it */ break; } } if (i == MAXLOADED) { /* Not found */ fprintf(stderr,"%s: command was not loaded\n",cmd); return FAIL; } if (strlen(tail) >= 128) { /* Tail must not be too long */ fprintf(stderr,"%s: command tail too long\n",cmd); return FAIL; } bp = load_img[i].basepag; /* Just for short */ strcpy(newtail+1,tail); /* Prepare real tail */ newtail[0] = (unsigned)strlen(tail); /* Length byte */ newbp = (long)Pexec(5,(char *)0,newtail,(char *)0); /* Create basepage */ Mshrink(newbp,256); /* Shrink to 256 bytes */ for (v = 1; v < 8; v++) { /* Copy over lengths and vectors */ ((long *)newbp)[v] = ((long *)bp)[v];/* from existing basepage */ } err_co = Pexec(4,(char *)0,newbp,(char *)0); /* Now execute it */ Mfree(((long *)newbp)[11]); /* Free environment space */ Mfree(newbp); /* and the basepage itself */ return err_co; } ---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8