[comp.sys.atari.st] shell p usage

dal@stag.UUCP (Dale Schumacher) (02/03/88)

  <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')

rogers@ncrcce.StPaul.NCR.COM (Bob Rogers) (02/06/88)

In article <326@stag.UUCP> syntel!dal@stag.UUCP (Dale Schumacher) writes:
>
>  <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,

When msh spawns another instance of itself (e.g., msh starts EMACS which 
spawns another copy of msh) is does not read the profile file.  I presume that
this difference in behaviour is why msh has to know where it came from.

It also does not inherit shell variables (it does, however, inherit 
environment variables) which means that commands defined in the .bin or .cmd 
pseudo-directories are not available in 2nd (and subsequent) copy of the shell.

>PS.  For those waiting for dLibs

Does dLibs or any other public domain library contain a version of "regexp"?
-- 
-----------------------------------------------------------------------------
Bob Rogers					        rogers@StPaul.NCR.COM
NCR Comten, St. Paul, MN