Path: 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 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 #include #include #include 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 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')