|
|
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.2 86/11/17 ";
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 tahoe
62: (header.a_text /* starts after text */
63: & 037777776000) /* on an 1K boundary */
64: + 02000; /* i.e. the next one up */
65: #endif
66: #ifdef z8000
67: (header.a_text /* starts after text */
68: & 0174000) /* on an 2K boundary */
69: + 004000; /* i.e. the next one up */
70: #endif
71: header.a_data=sbrk(0)-c; /* current size (incl allocs) */
72: break;
73: case 0411: /* sharable with split i/d */
74: c = 0; /* can't reach text */
75: header.a_data=(int)sbrk(0);/* current size (incl allocs) */
76: break;
77: case 0413:
78: c = (char *) header.a_text;/* starts after text */
79: lseek(fdaout, 1024L, 0); /* skip unused part of 1st block*/
80: }
81: if (header.a_data<0) /* data area very big */
82: return(-1); /* fail for now */
83:
84: filesize=sizeof header+header.a_text+header.a_data;
85: write(fd,&header,sizeof header); /* make the new header */
86: if (header.a_magic==0413)
87: lseek(fd, 1024L, 0); /* Start on 1K boundary */
88: counter=header.a_text; /* size of text */
89: while (counter>512) /* copy 512-byte blocks */
90: { read(fdaout,buff,512); /* as long as possible */
91: write(fd,buff,512);
92: counter -= 512;
93: }
94: read(fdaout,buff,counter); /* then pick up the rest */
95: write(fd,buff,counter);
96: write(fd,c,header.a_data); /* write all data in 1 glob */
97: close(fd);
98: }
99:
100: #define NULL 0
101:
102: char *execat(), *getenv();
103:
104: getcmd(command) /* get command name (wherever it is) like shell */
105: char *command;
106: {
107: char *pathstr;
108: register char *cp;
109: char fname[128];
110: int fd;
111:
112: if ((pathstr = getenv("PATH")) == NULL)
113: pathstr = ":/bin:/usr/bin";
114: cp = index(command, '/')? "": pathstr;
115:
116: do {
117: cp = execat(cp, command, fname);
118: if ((fd=open(fname,0))>0)
119: return(fd);
120: } while (cp);
121:
122: printf("Couldn't open %s\n",command);
123: return(-1);
124: }
125:
126: static char *
127: execat(s1, s2, si)
128: register char *s1, *s2;
129: char *si;
130: {
131: register char *s;
132:
133: s = si;
134: while (*s1 && *s1 != ':' && *s1 != '-')
135: *s++ = *s1++;
136: if (si != s)
137: *s++ = '/';
138: while (*s2)
139: *s++ = *s2++;
140: *s = '\0';
141: return(*s1? ++s1: 0);
142: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.