Commit | Line | Data |
---|---|---|
0294e1a5 RH |
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 | ||
01eb5674 | 9 | static char sccsid[] = " save.c 4.1 82/05/11 "; |
0294e1a5 RH |
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 | } |