1: /* save (III)   J. Gillogly
   2:  * save user core image for restarting
   3:  * usage: save(<command file (argv[0] from main)>,<output file>)
   4:  * bugs
   5:  *   -  impure code (i.e. changes in instructions) is not handled
   6:  *      (but people that do that get what they deserve)
   7:  */
   8: 
   9: static char sccsid[] = "	save.c	4.1	82/05/11	";
  10: 
  11: #include <a.out.h>
  12: int filesize;                    /* accessible to caller         */
  13: 
  14: char *sbrk();
  15: 
  16: save(cmdfile,outfile)                   /* save core image              */
  17: char *cmdfile,*outfile;
  18: {       register char *c;
  19:     register int i,fd;
  20:     int fdaout;
  21:     struct exec header;
  22:     int counter;
  23:     char buff[512],pwbuf[120];
  24:     fdaout=getcmd(cmdfile);         /* open command wherever it is  */
  25:     if (fdaout<0) return(-1);       /* can do nothing without text  */
  26:     if ((fd=open(outfile,0))>0)     /* this restriction is so that  */
  27:     {       printf("Can't use an existing file\n"); /* we don't try */
  28:         close(fd);              /* to write over the commnd file*/
  29:         return(-1);
  30:     }
  31:     if ((fd=creat(outfile,0755))== -1)
  32:     {       printf("Cannot create %s\n",outfile);
  33:         return(-1);
  34:     }
  35:     /* can get the text segment from the command that we were
  36: 	 * called with, and change all data from uninitialized to
  37: 	 * initialized.  It will start at the top again, so the user
  38: 	 * is responsible for checking whether it was restarted
  39: 	 * could ignore sbrks and breaks for the first pass
  40: 	 */
  41:     read(fdaout,&header,sizeof header);/* get the header       */
  42:     header.a_bss = 0;                  /* no data uninitialized        */
  43:     header.a_syms = 0;                 /* throw away symbol table      */
  44:     switch (header.a_magic)            /* find data segment            */
  45:     {   case 0407:                     /* non sharable code            */
  46:         c = (char *) header.a_text;/* data starts right after text */
  47:         header.a_data=sbrk(0)-c;   /* current size (incl allocs)   */
  48:         break;
  49:         case 0410:                     /* sharable code                */
  50:         c = (char *)
  51: #ifdef pdp11
  52:             (header.a_text     /* starts after text            */
  53:             & 0160000)             /* on an 8K boundary            */
  54:             +  020000;             /* i.e. the next one up         */
  55: #endif
  56: #ifdef vax
  57:             (header.a_text     /* starts after text            */
  58:             & 037777776000)        /* on an 1K boundary            */
  59:             +        02000;        /* i.e. the next one up         */
  60: #endif
  61: #ifdef z8000
  62:             (header.a_text     /* starts after text            */
  63:             & 0174000)             /* on an 2K boundary            */
  64:             +  004000;             /* i.e. the next one up         */
  65: #endif
  66:         header.a_data=sbrk(0)-c;   /* current size (incl allocs)   */
  67:         break;
  68:         case 0411:                     /* sharable with split i/d      */
  69:         c = 0;                     /* can't reach text             */
  70:         header.a_data=(int)sbrk(0);/* current size (incl allocs)   */
  71:         break;
  72:         case 0413:
  73:         c = (char *) header.a_text;/* starts after text            */
  74:         lseek(fdaout, 1024L, 0);   /* skip unused part of 1st block*/
  75:     }
  76:     if (header.a_data<0)               /* data area very big           */
  77:         return(-1);                /* fail for now                 */
  78: 
  79:     filesize=sizeof header+header.a_text+header.a_data;
  80:     write(fd,&header,sizeof header);   /* make the new header          */
  81:     if (header.a_magic==0413)
  82:         lseek(fd, 1024L, 0);       /* Start on 1K boundary	   */
  83:     counter=header.a_text;             /* size of text                 */
  84:     while (counter>512)                /* copy 512-byte blocks         */
  85:     {       read(fdaout,buff,512);     /* as long as possible          */
  86:         write(fd,buff,512);
  87:         counter -= 512;
  88:     }
  89:     read(fdaout,buff,counter);         /* then pick up the rest        */
  90:     write(fd,buff,counter);
  91:     write(fd,c,header.a_data);         /* write all data in 1 glob     */
  92:     close(fd);
  93: }
  94: 
  95: #define NULL    0
  96: 
  97: char    *execat(), *getenv();
  98: 
  99: getcmd(command)         /* get command name (wherever it is) like shell */
 100: char *command;
 101: {
 102:     char *pathstr;
 103:     register char *cp;
 104:     char fname[128];
 105:     int fd;
 106: 
 107:     if ((pathstr = getenv("PATH")) == NULL)
 108:         pathstr = ":/bin:/usr/bin";
 109:     cp = index(command, '/')? "": pathstr;
 110: 
 111:     do {
 112:         cp = execat(cp, command, fname);
 113:         if ((fd=open(fname,0))>0)
 114:             return(fd);
 115:     } while (cp);
 116: 
 117:     printf("Couldn't open %s\n",command);
 118:     return(-1);
 119: }
 120: 
 121: static char *
 122: execat(s1, s2, si)
 123: register char *s1, *s2;
 124: char *si;
 125: {
 126:     register char *s;
 127: 
 128:     s = si;
 129:     while (*s1 && *s1 != ':' && *s1 != '-')
 130:         *s++ = *s1++;
 131:     if (si != s)
 132:         *s++ = '/';
 133:     while (*s2)
 134:         *s++ = *s2++;
 135:     *s = '\0';
 136:     return(*s1? ++s1: 0);
 137: }

Defined functions

execat defined in line 121; used 2 times
getcmd defined in line 99; used 2 times
save defined in line 16; used 2 times

Defined variables

filesize defined in line 12; used 1 times
  • in line 79
sccsid defined in line 9; never used

Defined macros

NULL defined in line 95; used 1 times
Last modified: 1982-06-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2538
Valid CSS Valid XHTML 1.0 Strict