|
|
1.1 root 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.3 89/03/05 ";
10:
11: #include <sys/file.h>
12: #include <a.out.h>
13: int filesize; /* accessible to caller */
14:
15: char *sbrk();
16:
17: save(cmdfile,outfile) /* save core image */
18: char *cmdfile,*outfile;
19: { register char *c;
20: register int i,fd;
21: int fdaout;
22: struct exec header;
23: int counter;
24: char buff[512],pwbuf[120];
25: fdaout = open(cmdfile, O_RDONLY, 0); /* open command */
26: if (fdaout<0) return(-1); /* can do nothing without text */
27: if ((fd=creat(outfile,0755))== -1)
28: { printf("Cannot create %s\n",outfile);
29: return(-1);
30: }
31: /* can get the text segment from the command that we were
32: * called with, and change all data from uninitialized to
33: * initialized. It will start at the top again, so the user
34: * is responsible for checking whether it was restarted
35: * could ignore sbrks and breaks for the first pass
36: */
37: read(fdaout,&header,sizeof header);/* get the header */
38: header.a_bss = 0; /* no data uninitialized */
39: header.a_syms = 0; /* throw away symbol table */
40: switch (header.a_magic) /* find data segment */
41: { case 0407: /* non sharable code */
42: c = (char *) header.a_text;/* data starts right after text */
43: header.a_data=sbrk(0)-c; /* current size (incl allocs) */
44: break;
45: case 0410: /* sharable code */
46: c = (char *)
47: #ifdef pdp11
48: (header.a_text /* starts after text */
49: & 0160000) /* on an 8K boundary */
50: + 020000; /* i.e. the next one up */
51: #endif
52: #ifdef vax
53: (header.a_text /* starts after text */
54: & 037777776000) /* on an 1K boundary */
55: + 02000; /* i.e. the next one up */
56: #endif
57: #ifdef tahoe
58: (header.a_text /* starts after text */
59: & 037777776000) /* on an 1K boundary */
60: + 02000; /* i.e. the next one up */
61: #endif
62: #ifdef z8000
63: (header.a_text /* starts after text */
64: & 0174000) /* on an 2K boundary */
65: + 004000; /* i.e. the next one up */
66: #endif
67: header.a_data=sbrk(0)-c; /* current size (incl allocs) */
68: break;
69: case 0411: /* sharable with split i/d */
70: c = 0; /* can't reach text */
71: header.a_data=(int)sbrk(0);/* current size (incl allocs) */
72: break;
73: case 0413:
74: c = (char *) header.a_text;/* starts after text */
75: lseek(fdaout, 1024L, 0); /* skip unused part of 1st block*/
76: }
77: if (header.a_data<0) /* data area very big */
78: return(-1); /* fail for now */
79:
80: filesize=sizeof header+header.a_text+header.a_data;
81: write(fd,&header,sizeof header); /* make the new header */
82: if (header.a_magic==0413)
83: lseek(fd, 1024L, 0); /* Start on 1K boundary */
84: counter=header.a_text; /* size of text */
85: while (counter>512) /* copy 512-byte blocks */
86: { read(fdaout,buff,512); /* as long as possible */
87: write(fd,buff,512);
88: counter -= 512;
89: }
90: read(fdaout,buff,counter); /* then pick up the rest */
91: write(fd,buff,counter);
92: write(fd,c,header.a_data); /* write all data in 1 glob */
93: close(fd);
94: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.