🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.atari.st
Article #38723

Preloading revised

#38723
From: Leo de Wit
Date: Thu, 11 May 1989 07:10
167 lines
5702 bytes
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 <stdio.h>
#include <osbind.h>

#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
Technical Details
Message-ID: <1028@philmds.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!ames!sun-barr!texsun!pitstop!sundc!seismo!uunet!mcvax!hp4nl!phigate!philmds!leo

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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