pa2183@sdcc15.ucsd.edu (pa2183) (03/08/89)
Recently I have been trying to get the Sozobon C stuff to work under the Beckemeyer C-Shell products. Due to a certain lack of clarity I am posting this follow-up item. Ok so I flunked English 1-A. The "free" reference was to the Sozobon Stuff. Attached is the Sozobon argument initializer function which performs some arcane things to determine what was the name of the program that was run by the parent task. My guess is that in the MT C-Shell product, the TOS exec function is not called or not in the way this code expects. So it crashs because the pointer that is eventually found is NULL or in general bad. Since the Sozobon folks made the linker they could have embedded the program name into a standard variable location and just picked that up if all else failed. At least that's what the ancient DECUS C compiler did in RT-11 an ancestor of TOS/DOS et al. My "free" remark was directed towards this type of debugging required, i.e. there's no free lunch!! I am running Micro C-Shell 2.61 and MT C-Shell 1.10 which are not the latest versions available. John Clark pa2183@sdcc15.ucsd.edu #include <stdio.h> #include <osbind.h> #include <string.h> #include <basepage.h> #include <errno.h> typedef struct { char xarg_magic[4]; /* verification value "xArg" */ int xargc; /* argc */ char **xargv; /* argv */ char *xiovector; /* i/o handle status */ BASEPAGE *xparent; /* pointer to parent's basepage */ } XARG; extern int _argc; extern char **_argv; static char xmagic[] = "xArg"; static char hex[] = "0123456789ABCDEF"; static char *_sbrk(size) register int size; /* * Internal error checking interface for the sbrk() function */ { register char *p; char *sbrk(); size = (size + 1) & ~1; if(p = sbrk(size)) return(p); Cconws("Too many arguments\n"); _exit(ENSMEM); } /* * Retrieve extended arguments, if possible, and set up argc and argv[]. */ void _initargs(cmdline, cmdlen) char *cmdline; int cmdlen; { register XARG *xp; register char *p, **q; register int i, n; register long a; char *getenv(); if(p = getenv(xmagic)) { /* * if the "xArg" variable exists, decode the address * and assume that it points somewhere reasonable, * though possibly not to a valid XARG struct */ for(a = 0L; *p; ++p) /* convert ascii-hex to long */ a = ((a << 4) | (0xF & strpos(hex, *p))); xp = ((XARG *) a); } if((p == NULL) /* no extended args */ || (strncmp(xp->xarg_magic, xmagic, 4)) /* not XARG struct */ || (xp->xparent != _base->p_parent)) /* not right parent */ { /* copy the command line */ i = cmdlen; p = strncpy(_sbrk(i + 1), cmdline, i); p[i] = '\0'; _argv = q = (char **) _sbrk(sizeof(char *)); *q = ""; /* argv[0] == "" */ n = 1; /* * parse command line image based on whitespace */ if(p = strtok(p, " \t")) { do { q = (char **) _sbrk(sizeof(char *)); ++n; *q = p; } while(p = strtok(NULL, " \t")); } q = (char **) _sbrk(sizeof(char *)); *q = NULL; /* tie off argv */ _argc = n; } else /* EXTENDED ARGS! */ { /* * extended args are easy... just remember to copy the * data, since it resides in your parent's data space */ _argc = n = xp->xargc; /* copy argc */ i = ((n + 1) * sizeof(char *)); _argv = q = ((char **) _sbrk(i)); memcpy(q, xp->xargv, i); /* copy argv */ q[n] = NULL; do /* copy arguments */ { p = _sbrk(strlen(*q) + 1); *q = strcpy(p, *q); } while(*++q); } if((_argv[0] == NULL) || (_argv[0][0] == '\0')) { /* * argv[0] not set, extract value from parent's dta */ p = (char *) _base->p_parent; /* get parent's basepage */ if(p == NULL) _argv[0] = ""; /* for sid... */ else { p = *(char **)(p+0x7C); /* get parent's saved usp */ p = *(char **)(p+0x36); /* get Pexec'd filename */ _argv[0] = _sbrk(strlen(p) + 1); strcpy(_argv[0], p); /* copy filename */ } } }