1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * The game adventure was original written Fortran by Will Crowther 6 * and Don Woods. It was later translated to C and enhanced by 7 * Jim Gillogly. 8 * 9 * %sccs.include.redist.c% 10 */ 11 12 #ifndef lint 13 static char sccsid[] = "@(#)save.c 5.1 (Berkeley) 04/08/91"; 14 #endif /* not lint */ 15 16 /* save (III) J. Gillogly 17 * save user core image for restarting 18 * usage: save(<command file (argv[0] from main)>,<output file>) 19 * bugs 20 * - impure code (i.e. changes in instructions) is not handled 21 * (but people that do that get what they deserve) 22 */ 23 24 #include <sys/file.h> 25 #include <a.out.h> 26 int filesize; /* accessible to caller */ 27 28 char *sbrk(); 29 30 save(cmdfile,outfile) /* save core image */ 31 char *cmdfile,*outfile; 32 { register char *c; 33 register int i,fd; 34 int fdaout; 35 struct exec header; 36 int counter; 37 char buff[512],pwbuf[120]; 38 fdaout = open(cmdfile, O_RDONLY, 0); /* open command */ 39 if (fdaout<0) return(-1); /* can do nothing without text */ 40 if ((fd=creat(outfile,0755))== -1) 41 { printf("Cannot create %s\n",outfile); 42 return(-1); 43 } 44 /* can get the text segment from the command that we were 45 * called with, and change all data from uninitialized to 46 * initialized. It will start at the top again, so the user 47 * is responsible for checking whether it was restarted 48 * could ignore sbrks and breaks for the first pass 49 */ 50 read(fdaout,&header,sizeof header);/* get the header */ 51 header.a_bss = 0; /* no data uninitialized */ 52 header.a_syms = 0; /* throw away symbol table */ 53 switch (header.a_magic) /* find data segment */ 54 { case 0407: /* non sharable code */ 55 c = (char *) header.a_text;/* data starts right after text */ 56 header.a_data=sbrk(0)-c; /* current size (incl allocs) */ 57 break; 58 case 0410: /* sharable code */ 59 c = (char *) 60 #ifdef pdp11 61 (header.a_text /* starts after text */ 62 & 0160000) /* on an 8K boundary */ 63 + 020000; /* i.e. the next one up */ 64 #endif 65 #ifdef vax 66 (header.a_text /* starts after text */ 67 & 037777776000) /* on an 1K boundary */ 68 + 02000; /* i.e. the next one up */ 69 #endif 70 #ifdef tahoe 71 (header.a_text /* starts after text */ 72 & 037777776000) /* on an 1K boundary */ 73 + 02000; /* i.e. the next one up */ 74 #endif 75 #ifdef z8000 76 (header.a_text /* starts after text */ 77 & 0174000) /* on an 2K boundary */ 78 + 004000; /* i.e. the next one up */ 79 #endif 80 header.a_data=sbrk(0)-c; /* current size (incl allocs) */ 81 break; 82 case 0411: /* sharable with split i/d */ 83 c = 0; /* can't reach text */ 84 header.a_data=(int)sbrk(0);/* current size (incl allocs) */ 85 break; 86 case 0413: 87 c = (char *) header.a_text;/* starts after text */ 88 lseek(fdaout, 1024L, 0); /* skip unused part of 1st block*/ 89 } 90 if (header.a_data<0) /* data area very big */ 91 return(-1); /* fail for now */ 92 93 filesize=sizeof header+header.a_text+header.a_data; 94 write(fd,&header,sizeof header); /* make the new header */ 95 if (header.a_magic==0413) 96 lseek(fd, 1024L, 0); /* Start on 1K boundary */ 97 counter=header.a_text; /* size of text */ 98 while (counter>512) /* copy 512-byte blocks */ 99 { read(fdaout,buff,512); /* as long as possible */ 100 write(fd,buff,512); 101 counter -= 512; 102 } 103 read(fdaout,buff,counter); /* then pick up the rest */ 104 write(fd,buff,counter); 105 write(fd,c,header.a_data); /* write all data in 1 glob */ 106 close(fd); 107 } 108