[net.micro.pc] Simple Environment Question

p40001@mcomp.UUCP (07/12/86)

It is nice to know that there is a "getenv()" function in MS-C,
but some of us have compilers which don't provide this function
(I've got DeSmet from C Ware).

Is there someone out there in NetLand who has a getenv() function 
which he/she would make available to those of us who don't have one?
Should be in source, so we'll learn how it's done, as well as because
of differing object formats (DeSmet doesn't use the MS *.obj format).

Thanks in advance!
-----------------------------------------------------
Wolf N. Paul, 290 Dogwood, Plano, Tx. 75075
UUCP:   { convex, infoswx, texsun!rrm }!mcomp!p40001
BIX: wnp    Phone: (214) 578-8023  W.U.ESL: 6283-2882

chapman@pavepaws.UUCP (07/15/86)

The following information is for DOS 3.x; I am unsure of its applicability
to earlier versions.

The segment address of a program's copy of the environment is stored at
offset 0x2C in the PSP.  It is stored as a series of ASCII strings
(totallyng less than 32K) in the form "NAME=parameter".  Each string is
terminated by a byte of zeros.  A second byte of zeros follows the last
string in the environment.

The address of the PSP can be obtained by using interrupt 0x21, function
0x62.  Set AH to 0x62, cause an interrupt 0x21, and read the PSP
address from register BX.

Note that what your program sees is a COPY of the environment of the
calling process (generally COMMAND.COM).  Therefore, any changes you
make to this environment will be visible to sub-programs that your
program calls, but will "disappear" when your program terminates.


Brent

--

Brent Chapman
chapman@pavepaws.berkeley.edu
ucbvax!pavepaws!chapman

TANSTAAFL!  (There Ain't No Such Thing As A Free Lunch!)

bet@ecsvax.UUCP (Bennett E. Todd III) (07/16/86)

Here's a getenv() in C source that I wrote for DeSmet. It differs from
the UNIX function in that it malloc()s space for the returned string,
rather than just returning a pointer into a copy of the environment (if
I were to write it again I'd write it differently). For any other
compiler, all you should need is to find a way to get a pointer to the
PSP (Program Segment Prefix) to replace my call to _showcs() (which
returns the segment pointer to the .EXE load point, 0x100 bytes or 0x10
paragraphs past the PSP), and to give it an _peek() function that takes
a pointer and a segment and returns the byte found there.

--- cut here -- *not* a shell archive; save as getenv.c ---
#include <stdio.h>
/*
 * PD rewrite of UNIX subroutine of the same name
 * for DeSmet C
 * by Bennett Todd
 * differs from the UNIX utility in that it malloc()s space for
 * the string to return
 */

char *getenv(name)
char *name;
{
	char *found, *malloc();
	char *offset, *tmp, _peek(), toupper();
	int i;
	unsigned segment, _showcs();

	/* PSP is at CS-10H */
	segment = _showcs() - 0x10;

	/*
	** The environment is stored starting at a segment whose segment address
	** can be found 2Ch into the PSP -- a word address...
	*/
	segment = _peek(0x2c, segment) + 256*_peek(0x2d, segment);

	/* Look for the string NAME= in the environment */
	for (offset=NULL; _peek(offset, segment) != NULL; offset++) {
		i = 0; /* i scans through name */
		while (name[i] != NULL &&
			   toupper(_peek(offset, segment)) == toupper(name[i])) {
			i++;
			offset++;
		}
		if (name[i] == NULL && _peek(offset, segment) == '=') {
			/* then we found it -- get it and return it */
			tmp = ++offset;
			while (_peek(tmp, segment) != NULL)
				tmp++;
			found = malloc(1 + tmp-offset);
			if (found == NULL) {
				fprintf(stderr, "getenv: malloc failed. Bye....\n");
				exit(1);
			}
			tmp = found;
			while ((*tmp++ = _peek(offset++, segment)) !=NULL)
				/* NULL BODY */;
			return(found);
		}
		/* We didn't found it -- clean up and try next entry */
		while (_peek(offset, segment) != NULL)
			offset++;
	}
	/* Ain't no sech beastie. Sorry, boss... */
	return((char *) NULL);
}
---------------------- end of getenv.c -------------------------------
Enjoy!
-Bennett
-- 

Bennett Todd -- Duke Computation Center, Durham, NC 27706-7756; (919) 684-3695
UUCP: ...{decvax,seismo,philabs,ihnp4,akgua}!mcnc!ecsvax!duccpc!bet

rde@ukc.UUCP (07/18/86)

In article <854@ucbcad.BERKELEY.EDU> chapman@pavepaws.UUCP (Brent Chapman) writes:
>The following information is for DOS 3.x; I am unsure of its applicability
>to earlier versions.
>
>The segment address of a program's copy of the environment is stored at
>offset 0x2C in the PSP.  It is stored as a series of ASCII strings
>(totallyng less than 32K) in the form "NAME=parameter".  Each string is
>terminated by a byte of zeros.  A second byte of zeros follows the last
>string in the environment.
>
>The address of the PSP can be obtained by using interrupt 0x21, function
>0x62.  Set AH to 0x62, cause an interrupt 0x21, and read the PSP
>address from register BX.
>

All versions of DOS from 2.00 onwards have a way of getting to the PSP.
It isn't however the INT 21H call with AH=62H, which appeared later.

This generic method (and it *is* documented) is that DS and ES both point
to the PSP when the program is entered from DOS....

Hope this helps,
-- 
           Bob Eager

           rde@ukc.UUCP
           rde@ukc
           ...!mcvax!ukc!rde

           Phone: +44 227 66822 ext 7589