4.1cBSD/usr/src/ucb/lisp/franz/fex3.c

Compare this file to the similar file:
Show the results in this format:

#ifndef lint
static char *rcsid =
   "$Header: /na/franz/franz/RCS/fex3.c,v 1.1 83/01/29 12:49:27 jkf Exp $";
#endif

/*					-[Sat Jan 29 12:36:38 1983 by jkf]-
 * 	fex3.c				$Locker:  $
 * nlambda functions
 *
 * (c) copyright 1982, Regents of the University of California
 */


#include "global.h"
#include <vadvise.h>


/*
 *Ndumplisp -- create executable version of current state of this lisp.
 */
#ifndef	VMS
#include "a.out.h"

lispval
Ndumplisp()
{
	register struct exec *workp;
	register lispval argptr, temp;
	register char *fname;
	extern int reborn;
	struct exec work, old;
	extern etext;
	extern int dmpmode,usehole;
	extern char holend[], *curhbeg;
	int descrip, des2, ax,mode;
	char tbuf[BUFSIZ], *gstab();
	long count, lseek();


#ifndef UNIXTS
	vadvise(VA_ANOM);
#endif

	/* dump mode is kept in decimal (which looks like octal in dmpmode)
	   and is changeable via (sstatus dumpmode n) where n is 413 or 410
	   base 10		
	*/
	if(dmpmode == 413) mode = 0413;
	else mode = 0410;

	workp = &work;
	workp->a_magic	= mode;
	if(usehole)
		workp->a_text = ((int)curhbeg) & (~PAGRND);
	else
	workp->a_text	= ((((unsigned) (holend)) - 1) & (~PAGRND)) + PAGSIZ;
	workp->a_data	= (unsigned) sbrk(0) - workp->a_text;
	workp->a_bss	= 0;
	workp->a_syms	= 0;
	workp->a_entry	= (unsigned) gstart();
	workp->a_trsize	= 0;
	workp->a_drsize	= 0;

	fname = "savedlisp"; /*set defaults*/
	reborn = (int) CNIL;
	argptr = lbot->val;
	if (argptr != nil) {
		temp = argptr->d.car;
		if((TYPE(temp))==ATOM)
			fname = temp->a.pname;
	}
	des2 = open(gstab(),0);
	if(des2 >= 0) {
		if(read(des2,(char *)&old,sizeof(old))>=0)
			work.a_syms = old.a_syms;
	}
	descrip=creat(fname,0777); /*doit!*/
	if(-1==write(descrip,(char *)workp,sizeof(work)))
	{
		close(descrip);
		error("Dumplisp failed",FALSE);
	}
	if(mode == 0413) lseek(descrip,(long)PAGSIZ,0); 
	if( -1==write(descrip,(char *)0,(int)workp->a_text)    ||
	    -1==write(descrip,(char *)workp->a_text,(int)workp->a_data) ) {
		close(descrip);
		error("Dumplisp failed",FALSE);
	}
	if(des2>0  && work.a_syms) {
		count = old.a_text + old.a_data + (old.a_magic == 0413 ? PAGSIZ 
							       : sizeof(old));
		if(-1==lseek(des2,count,0))
			error("Could not seek to stab",FALSE);
		for(count = old.a_syms;count > 0; count -=BUFSIZ) {
			ax = read(des2,tbuf,(int)(count < BUFSIZ ? count : BUFSIZ));
			if(ax==0) {
				printf("Unexpected end of syms",count);
				fflush(stdout);
				break;
			} else if(ax >  0)
				write(descrip,tbuf,ax);
			else 
				error("Failure to write dumplisp stab",FALSE);
		}
		if(-1 == lseek(des2,(long)
			((old.a_magic == 0413 ? PAGSIZ : sizeof(old))
			+ old.a_text + old.a_data
				+ old.a_trsize + old.a_drsize + old.a_syms),
			       0))
			error(" Could not seek to string table ",FALSE);
		for( ax = 1 ; ax > 0;) {
		     ax = read(des2,tbuf,BUFSIZ);
		     if(ax > 0)
			 write(descrip,tbuf,ax);
		     else if (ax < 0)
			 error("Error in string table read ",FALSE);
		}
	}
	close(descrip);
	if(des2>0) close(des2);
	reborn = 0;

#ifndef UNIXTS
	vadvise(VA_NORM);
#endif
	return(nil);
}


/*** VMS version of Ndumplisp ***/
#else
#include "aout.h"
#undef	protect
#include <vms/vmsexe.h>

#ifdef	PAGRND
#undef	PAGRND
#endif
#ifdef	PAGSIZ
#undef	PAGSIZ
#endif
#define	PAGRND	511
#define	PAGSIZ	512

lispval
Ndumplisp()
{
	register struct exec *workp;
	register lispval argptr, temp;
	char *fname;
	register ISD *Isd;
	register int i;
	extern lispval reborn;
	struct exec work,old;
	extern etext;
	extern int dmpmode,holend,curhbeg,usehole;
	int descrip, des2, count, ax,mode;
	char buf[5000],stabname[100];
	int fp,fp1;
	union {
		char Buffer[512];
		struct {
			IHD Ihd;
			IHA Iha;
			IHS Ihs;
			IHI Ihi;
			} Header;
		} Buffer;	/* VMS Header */

	/*
	 *	Dumpmode is always 413!!
	 */
	mode = 0413;

	workp = &work;
	workp->a_magic   = mode;
	workp->a_text   = ((((unsigned) (&etext)) -1) & (~PAGRND)) + PAGSIZ;
	workp->a_data   = (unsigned) sbrk(0) - workp->a_text;
	workp->a_bss    = 0;
	workp->a_syms   = 0;
	workp->a_entry  = (unsigned) gstart();
	workp->a_trsize = 0;
	workp->a_drsize = 0;

	fname = "savedlisp";	/* set defaults */
	reborn = (int) CNIL;
	argptr = lbot->val;
	if (argptr != nil) {
		temp = argptr->d.car;
		if((TYPE(temp))==ATOM)
			fname = temp->a.pname;
	}
	/*
	 *	Open the new executable file
	 */
	strcpy(buf,fname);
	if (index(buf,'.') == 0) strcat(buf,".exe");
	if ((descrip = creat(buf,0777)) < 0) error("Dumplisp failed",FALSE);
	/*
	 *	Create the VMS header
	 */
	for(i = 0; i < 512; i++) Buffer.Buffer[i] = 0;	/* Clear Header */
	Buffer.Header.Ihd.size		= sizeof(Buffer.Header);
	Buffer.Header.Ihd.activoff	= sizeof(IHD);
	Buffer.Header.Ihd.symdbgoff	= sizeof(IHD) + sizeof(IHA);
	Buffer.Header.Ihd.imgidoff	= sizeof(IHD) + sizeof(IHA) + sizeof(IHS);
	Buffer.Header.Ihd.majorid[0]	= '0';
	Buffer.Header.Ihd.majorid[1]	= '2';
	Buffer.Header.Ihd.minorid[0]	= '0';
	Buffer.Header.Ihd.minorid[1]	= '2';
	Buffer.Header.Ihd.imgtype	= IHD_EXECUTABLE;
	Buffer.Header.Ihd.privreqs[0]	= -1;
	Buffer.Header.Ihd.privreqs[1]	= -1;
	Buffer.Header.Ihd.lnkflags.nopobufs = 1;
	Buffer.Header.Ihd.imgiocnt = 250;

	Buffer.Header.Iha.tfradr1	= SYS$IMGSTA;
	Buffer.Header.Iha.tfradr2	= workp->a_entry;

	strcpy(Buffer.Header.Ihi.imgnam+1,"SAVEDLISP");
	Buffer.Header.Ihi.imgnam[0] = 9;
	Buffer.Header.Ihi.imgid[0] = 0;
	Buffer.Header.Ihi.imgid[1] = '0';
	sys$gettim(Buffer.Header.Ihi.linktime);
	strcpy(Buffer.Header.Ihi.linkid+1," Opus 38");
	Buffer.Header.Ihi.linkid[0] = 8;

	Isd = (ISD *)&Buffer.Buffer[sizeof(Buffer.Header)];
		/* Text ISD */
	Isd->size	= ISDSIZE_TEXT;
	Isd->pagcnt	= workp->a_text >> 9;
	Isd->vpnpfc.vpn = 0;
	Isd->flags.type = ISD_NORMAL;
	Isd->vbn	= 3;
	Isd = (ISD *)((char *)Isd + Isd->size);
		/* Data ISD */
	Isd->size	= ISDSIZE_TEXT;
	Isd->pagcnt	= workp->a_data >> 9;
	Isd->vpnpfc.vpn = workp->a_text >> 9;
	Isd->flags.type = ISD_NORMAL;
	Isd->flags.crf	= 1;
	Isd->flags.wrt	= 1;
	Isd->vbn	= (workp->a_text >> 9) + 3;
	Isd = (ISD *)((char *)Isd + Isd->size);
		/* Stack ISD */
	Isd->size	= ISDSIZE_DZRO;
	Isd->pagcnt	= ISDSTACK_SIZE;
	Isd->vpnpfc.vpn	= ISDSTACK_BASE;
	Isd->flags.type = ISD_USERSTACK;
	Isd->flags.dzro	= 1;
	Isd->flags.wrt	= 1;
	Isd = (ISD *)((char *)Isd + Isd->size);
		/* End of ISD List */
	Isd->size = 0;
	Isd = (ISD *)((char *)Isd + 2);
	/*
	 *	Make the rest of the header -1s
	 */
	for (i = ((char *)Isd - Buffer.Buffer); i < 512; i++)
						Buffer.Buffer[i] = -1;
	/*
	 *	Write the VMS Header
	 */
	if (write(descrip,Buffer.Buffer,512) == -1)
					error("Dumplisp failed",FALSE);
	/*
	 *	Write the UNIX Header (blank for now!!)
	 */
	/*if (write(descrip,workp,sizeof(struct exec)) == -1)
					error("Dumplisp failed",FALSE);*/
	/*
	 *	seek to 1024 (end of headers)
	 */
	if (lseek(descrip,1024,0) == -1)
				error("Dumplisp failed",FALSE);
	/*
	 *	write the world
	 */
	if (write(descrip,0,workp->a_text) == -1)
				error("Dumplisp failed",FALSE);
	if (write(descrip,workp->a_text,workp->a_data) == -1)
				error("Dumplisp failed",FALSE);
	/*
	 *	Done
	 */
	close(descrip);
	/*
	 *	Now try to write the symbol table file!
	 */
	strcpy(buf,gstab());

	strcpy(stabname,fname);
	if (index(stabname,'.') == 0) strcat(stabname,".stb");
	else strcpy(index(stabname,'.'), ".stb");

	/* Use Link/Unlink to rename the symbol table */
	if (!strcmpn(gstab(),"tmp:",4))
		if (link(buf,stabname) >= 0)
			if (unlink(buf) >= 0) return(nil);

	/* Copy the symbol table */
	if ((fp  = open(buf,0)) < 0)
			error("Symbol table file not there\n",FALSE);
	fp1 = creat(stabname,0666,"var");
	while((i = read(fp,buf,5000)) > 0)
		if (write(fp1,buf,i) == -1) {
			close(fp); close(fp1);
			error("Error writing symbol table\n",FALSE);
		}
	close(fp); close(fp1);
	if (i < 0) error("Error reading symbol table\n",FALSE);
	if (!strcmpn(gstab(),"tmp:",4)) unlink(gstab);
	/*
	 *	Done
	 */
	return(nil);
}
#endif