* Copyright (c) 1991 The Regents of the University of California.
* The game adventure was original written Fortran by Will Crowther
* and Don Woods. It was later translated to C and enhanced by
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)save.c 5.1 (Berkeley) %G%";
/* save (III) J. Gillogly
* save user core image for restarting
* usage: save(<command file (argv[0] from main)>,<output file>)
* - impure code (i.e. changes in instructions) is not handled
* (but people that do that get what they deserve)
int filesize
; /* accessible to caller */
save(cmdfile
,outfile
) /* save core image */
char buff
[512],pwbuf
[120];
fdaout
= open(cmdfile
, O_RDONLY
, 0); /* open command */
if (fdaout
<0) return(-1); /* can do nothing without text */
if ((fd
=creat(outfile
,0755))== -1)
{ printf("Cannot create %s\n",outfile
);
/* can get the text segment from the command that we were
* called with, and change all data from uninitialized to
* initialized. It will start at the top again, so the user
* is responsible for checking whether it was restarted
* could ignore sbrks and breaks for the first pass
read(fdaout
,&header
,sizeof header
);/* get the header */
header
.a_bss
= 0; /* no data uninitialized */
header
.a_syms
= 0; /* throw away symbol table */
switch (header
.a_magic
) /* find data segment */
{ case 0407: /* non sharable code */
c
= (char *) header
.a_text
;/* data starts right after text */
header
.a_data
=sbrk(0)-c
; /* current size (incl allocs) */
case 0410: /* sharable code */
(header
.a_text
/* starts after text */
& 0160000) /* on an 8K boundary */
+ 020000; /* i.e. the next one up */
(header
.a_text
/* starts after text */
& 037777776000) /* on an 1K boundary */
+ 02000; /* i.e. the next one up */
(header
.a_text
/* starts after text */
& 037777776000) /* on an 1K boundary */
+ 02000; /* i.e. the next one up */
(header
.a_text
/* starts after text */
& 0174000) /* on an 2K boundary */
+ 004000; /* i.e. the next one up */
header
.a_data
=sbrk(0)-c
; /* current size (incl allocs) */
case 0411: /* sharable with split i/d */
c
= 0; /* can't reach text */
header
.a_data
=(int)sbrk(0);/* current size (incl allocs) */
c
= (char *) header
.a_text
;/* starts after text */
lseek(fdaout
, 1024L, 0); /* skip unused part of 1st block*/
if (header
.a_data
<0) /* data area very big */
return(-1); /* fail for now */
filesize
=sizeof header
+header
.a_text
+header
.a_data
;
write(fd
,&header
,sizeof header
); /* make the new header */
if (header
.a_magic
==0413)
lseek(fd
, 1024L, 0); /* Start on 1K boundary */
counter
=header
.a_text
; /* size of text */
while (counter
>512) /* copy 512-byte blocks */
{ read(fdaout
,buff
,512); /* as long as possible */
read(fdaout
,buff
,counter
); /* then pick up the rest */
write(fd
,c
,header
.a_data
); /* write all data in 1 glob */