🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.atari.st
Article #30421

shell p usage

#30421
From: Dale Schumacher
Date: Wed, 03 Feb 1988 14:17
176 lines
5803 bytes
  <dumas@sumex-aim.stanford.edu> writes...
> Question #1 : How MWC's msh is discovering who called it ?
>  (desktop, or other...) it is in the local shell variable 'calledfrom'.
> An other shell is able to tell the list of all parents programs...
> The base page does not contain any backward pointer, so what is it ?

I'm not sure that MSH does* detect being called from the desktop.  What
difference would it make (or does it in MSH).  The basepage, however,
DOES* contain a "backward pointer" to the parent processes basepage.
Here is a struct to clarify...

typedef struct
	{
	char	*p_lowtpa;		/* pointer to self (bottom of TPA) */
	char	*p_hitpa;		/* pointer to top of TPA + 1 */
	char	*p_tbase;		/* base of text segment */
	long	p_tlen;			/* length of text segment */
	char	*p_dbase;		/* base of data segment */
	long	p_dlen;			/* length of data segment */
	char	*p_bbase;		/* base of BSS segment */
	long	p_blen;			/* length of BSS segment */
	char	*p_dta;			/* pointer to current DTA */
	char	*p_parent;		/* pointer to parent's basepage */
	char	*p_reserved;		/* reserved for future use */
	char	*p_env;			/* pointer to environment string */
	long	p_undefined[20];	/* scratch area... don't touch */
	char	p_cmdlin[128];		/* command line image */
	}
	BASEPAGE;

> Question #2 : I read again the dev kit doc on shell_p, the posting
> by A.Pratt about it, and I still wonder : what is it ?
> I would infer it is a pointer to a string telling the file name of a shell...
> I am right ?
> What would be the use otherwise ?

The shell_p variable, if it is valid, should point to a routine which
will take a string argument and process it like the Un*x system() call.
Here is an example implementation of system() which tries to use the
shell_p variable, if possible.

/*----------------------------------------------------------------------*/
#include <osbind.h>
#include <stdio.h>
#include <string.h>
#include <basepage.h>

static parse_args(cmdln, argv)
	char *cmdln;
	register char *argv[];
	{
	register char *p;
	static char delim[] = " \t\r\n";

	if(p = strtok(cmdln, delim))
		{
		do
			{
			*argv++ = p;
			} while(p = strtok(NULL, delim));
		}
	}

int system(command)
	register char *command;
/*
 *	Attempts to pass <command> to the shell program pointed to by
 *	the system variable "_shell_p".  If a valid shell can't be found
 *	there, the "SHELL" environment variable is searched for.  If it
 *	exists and is not empty, it will be the name of the shell program
 *	to execute the given command.  If "SHELL" is not valid, the
 *	"PATH" variable is used as a list of directories to search for
 *	the program name which is the first token of the command.  The
 *	extensions tried (if none is specified) are ".TTP", ".TOS",
 *	".PRG" and ".APP".
 */
{
	register char *p;
	register int (*shell)();
	char rv[2];
	char cmdln[1024];
	char *args[64];
	char *getenv();

	if(!command)
		return(ERROR);

	/* get _shell_p value */
	p = Super(0L);
	shell = *((long *) 0x4F6L);
	Super(p);

	/* validate _shell_p */
	if((shell) &&				/* Shell available. */
	   (((long) shell) < ((long) _base)) &&	/* Reasonable shell pointer. */
	   (strncmp(shell, "PATH", 4)))		/* Not corrupted */
		{
		/* execute the command */
		return((*shell)(command));
		}

	/* copy the command line for parsing */
	strcpy(cmdln, command);

	/* SHELL= variable? */
	if((p = getenv("SHELL")) && (*p))
		{
		args[0] = p;
		parse_args(cmdln, args+1);
		forkvpe(p, args, NULL);
		wait(&rv);
		return((rv[1] == 0) ? rv[0] : rv[1]);
		}

	/* attempt to find first token as a program on the path */
	parse_args(cmdln, args);
	if(p = pfindfile(args[0], ".ttp\0.tos\0.prg\0.app"))
		{
		forkvpe(p, args, NULL);
		wait(&rv);
		return((rv[1] == 0) ? rv[0] : rv[1]);
		}
	return(ERROR);
}
/*----------------------------------------------------------------------*/

I hope this answers your question.  It's so easy for a shell to install
itself on the shell_p vector and it's so convenient if other program
which support shell escapes use a system() call like the one above.
In case there is any question about installing and removing the shell_p
vector, the following routines will handle it nicely.

/*----------------------------------------------------------------------*/
long (*sh_save)();	/* previous value of _shell_p variable */

sh_install(new_shell)
	int (*new_shell)();
/*
 * install _shell_p vector
 */
	{
	register long *ssp;
	register (**shell_p)() = 0x4F6L;

	ssp = Super(0L);
	sh_save = *shell_p;
	*shell_p = new_shell;
	Super(ssp);
	}

sh_restore()
/*
 * restore old _shell_p vector
 */
	{
	register long *ssp;
	register (**shell_p)() = 0x4F6L;

	ssp = Super(0L);
	*shell_p = sh_save;
	Super(ssp);
	}
/*----------------------------------------------------------------------*/

PS.  For those waiting for dLibs v1.1 and/or MicroEMACS 2.19, I have
sent out disks for all the requests I had outstanding, you should either
already have them, or should receive them soon.  Sorry for the delays.
I hope you're happy with the results.  I'd like to hear from some of you
after you've used dLibs a bit.  I'd be happy to receive bug reports,
suggested enhancements or just experiences so that I know they're being
put to good use.

                Dale Schumacher
                ..ihnp4!meccts!stag!syntel!dal
                (alias: Dalnefre')
Technical Details
Message-ID: <326@stag.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!amdcad!ames!rutgers!uwvax!umn-d-ub!umn-cs!ems!nis!stag!daemon

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!amdcad!ames!rutgers!uwvax!umn-d-ub!umn-cs!ems!nis!stag!daemon
From: syntel!dal@stag.UUCP (Dale Schumacher)
Newsgroups: comp.sys.atari.st
Subject: shell p usage
Message-ID: <326@stag.UUCP>
Date: 3 Feb 88 14:17:46 GMT
Sender: daemon@stag.UUCP
Lines: 176