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
save
defined in line
16; used 2 times
Defined variables
sccsid
defined in line
9;
never used
Defined macros
NULL
defined in line
95; used 1 times