File:  [XINU] / xinu / sys / shell / x_create.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:39:04 2018 UTC (8 years, 3 months ago) by root
Branches: xinu, MAIN
CVS tags: xinu-19870308, HEAD
Xinu for VAX

/* x_create.c - x_creat, closret */

#include <conf.h>
#include <kernel.h>
#include <mem.h>
#include <shell.h>
#include "/usr/include/a.out.h"

LOCAL	char	symfile[] = "a.out";	/* name of object file to search*/

#define	SYMBLK	42*sizeof(struct nlist)

/*------------------------------------------------------------------------
 *  x_creat  -  (command create) create a process given a starting address
 *------------------------------------------------------------------------
 */
COMMAND	x_creat(stdin, stdout, stderr, nargs, args)
int	stdin, stdout, stderr, nargs;
char	*args[];
{
	int	ssize, prio;
	struct	exec   *aoutptr;
	int	dev,   symdev,   len,    pid;
	char	*loc,  *symbuf,  *last,  *buf;
	Bool	found;
	struct	nlist  *symptr;
	unsigned stroff, symoff;
	
	if (nargs < 4 || nargs > 5) {
	    fprintf(stderr,
		"usage: create procedure stack-size prio [name]\n");
	    return(SYSERR);
	}
	ssize = atoi(args[2]);
	prio  = atoi(args[3]);
	symbuf = (char *)(symdev = SYSERR);
	if ( (dev=open(NAMESPACE, symfile, "ro")) == SYSERR ||
	     (symdev=open(NAMESPACE, symfile, "ro")) == SYSERR ) {
		fprintf(stderr, "Cannot open %s\n", symfile);
		close(dev);
		close(symdev);
		return(SYSERR);
	}
	if ( (buf=(char *)getmem(SHCMDSTK)) == (char *)SYSERR ||
	     (symbuf=(char *)getmem(SHBUFLEN)) == (char *)SYSERR) {
		fprintf(stderr, "no memory\n");
		closret(dev, symdev, buf, symbuf);
		return(SYSERR);
	}
	strcpy(args[0], "_");
	strcat(args[0], args[1]);
	printf("Looking up %s\n", args[0]);
	read(dev, buf, sizeof(struct exec));
	aoutptr = (struct exec *) buf;
	symoff = N_SYMOFF(*aoutptr);
	stroff = N_STROFF(*aoutptr);
	if (N_BADMAG(*aoutptr) || stroff < N_TXTOFF(*aoutptr)) {
		fprintf(stderr, "bad a.out format\n");
		closret(dev, symdev, buf, symbuf);
		return(SYSERR);
	}
	seek(dev, symoff);
	for (found=FALSE ; !found && symoff < stroff ; symoff += SYMBLK) {
		len = read(dev, buf,
			(symoff+SYMBLK <= stroff) ? SYMBLK : stroff-symoff);
		if (len == SYSERR) {
			fprintf(stderr, "error reading %s\n", symfile);
			break;
		}
		last = &buf[len]; 
		for (symptr=(struct nlist *)buf;(char *)symptr<last;symptr++){
			if ((symptr->n_type == (N_TEXT|N_EXT)) &&
			     symptr->n_un.n_strx) {
				seek(symdev, stroff + symptr->n_un.n_strx);
				if (read(symdev, symbuf, SHBUFLEN) <= 0) {
					fprintf(stderr,"can't read strtab\n");
					closret(dev, symdev, buf, symbuf);
					return(SYSERR);
				}
				if (strcmp(symbuf,args[0]) == 0) {
					loc = (char *)symptr->n_value;
					found = TRUE;
					break;
				}
			}
		}
	}
	closret(dev, symdev, buf, symbuf);
	if (found) {
		pid=create(loc, ssize, prio, nargs==5?args[4]:&args[0][1], 0);
		fprintf(stderr, "[%d]\n", pid );
		return(resume(pid));
	} else {
		fprintf(stderr, "%s not found\n", args[0]);
		return (SYSERR);
	}
}

/*------------------------------------------------------------------------
 *  closret  -  close devices, free memory before returning
 *------------------------------------------------------------------------
*/
LOCAL	closret(dev, symdev, buf, symbuf)
int	dev, symdev;
char	*buf, *symbuf;
{
	close(dev);
	close(symdev);
	freemem(buf, SHCMDSTK);
	freemem(symbuf, SHBUFLEN);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.