[comp.sys.ibm.pc] Turbo C PUTENV/GETENV

cs4g6ag@maccs.dcss.mcmaster.ca (Stephen M. Dunn) (11/28/89)

   I'm writing a program under Turbo C 2.0 which has to be able to maniuplate
its own environment (I'm not talking about updating the previous shell's
copy of the enviornment, just its own) and I'd like to be able to pass
this environment along to child processes.  The problems I've discovered are:

- although the documentation says that the environment table may be moved
  and reorganized depending on its space needs, the most I can add is usually
  one entry.  Any subsequent entires added overwrite the first one I add.

- the manual says "Delete an existing entry by making the variable value
  empty (for example, MYVAR=)"  When this is done, however, I end up with
  an entry in the table saying exactly that:  MYVAR=, which is not what is
  wanted.

- if I add a line (say FOO=BAR) to the environment and then invoke a child
  process, with through system or by spawnle-ing, that line will be changed
  to an entry saying simply "and".  This will appear in the environment of
  the child and also in the parent's environment.

   If it matters, I'm using the small memory model.  Is there any way to
fix these problems short of writing my own environment management routines?
-- 
Stephen M. Dunn                               cs4g6ag@maccs.dcss.mcmaster.ca
          <std_disclaimer.h> = "\nI'm only an undergraduate!!!\n";
****************************************************************************
They say the best in life is free // but if you don't pay then you don't eat

mlord@bmers58.UUCP (Mark Lord) (11/29/89)

In article <2572998E.2456@maccs.dcss.mcmaster.ca> cs4g6ag@maccs.dcss.mcmaster.ca (Stephen M. Dunn) writes:
>
>   I'm writing a program under Turbo C 2.0 which has to be able to maniuplate
>its own environment (I'm not talking about updating the previous shell's
>copy of the enviornment, just its own) and I'd like to be able to pass
>this environment along to child processes.  The problems I've discovered are:
>...

The environment you get passed from DOS is always the smallest multiple of 16
bytes that can hold all of the existing environment variables at the time your
program is invoked.  Thus, even if the COMMAND.COM environment size was, say,
256 bytes, your program will be allocated with a much smaller environment if
there are only a few variables defined.

The problem here is that you need room to grow.. so you have to allocate a new
environment for yourself, and copy the old one to it (for initialization),
and then get rid of the old one.

I don't have my DOS references here, but somewhere in the psp is the pointer
to your environment, that both DOS and TURBOC use (offset 16?).  A pointer to
your psp is in _PSP, a predefined turbo-c variable that you can use.
The current size is stored in the MCB (memory control block) which immediately
preceeds it in memory (again.. no books = no offset for now..).

Just retrieve the size, add the amount you need for new stuff, use malloc to
get a new block, use a for-loop or something to copy the old env to the new 
block (based on the old size for how much to copy), change the _PSP+?? pointer
to point at the new one, and then deallocate the old one.  

-- 
+----------------------------------------+----------------------------+
| Mark S. Lord                           | Hey, It's only MY opinion. |
| ..!utgpu!bnr-vpa!bnr-fos!mlord%bmers58 | Feel free to have your own.|
+----------------------------------------+----------------------------+
-- 
+----------------------------------------+----------------------------+
| Mark S. Lord                           | Hey, It's only MY opinion. |
| ..!utgpu!bnr-vpa!bnr-fos!mlord%bmers58 | Feel free to have your own.|
+----------------------------------------+----------------------------+

richard@calvin.EE.CORNELL.EDU (Richard Brittain) (11/30/89)

In article <569@bmers58.UUCP> mlord@bmers58.UUCP (Mark Lord) writes:
>In article <2572998E.2456@maccs.dcss.mcmaster.ca> cs4g6ag@maccs.dcss.mcmaster.ca (Stephen M. Dunn) writes:
>>   I'm writing a program under Turbo C 2.0 which has to be able to maniuplate
>>its own environment (I'm not talking about updating the previous shell's
>>copy of the enviornment, just its own) and I'd like to be able to pass
>>this environment along to child processes.  The problems I've discovered are:
>>...
>
>The problem here is that you need room to grow.. so you have to allocate a new
>environment for yourself, and copy the old one to it (for initialization),
>and then get rid of the old one.
>...
 The standard Turbo-C startup code (at least in version 2) copies the entire
environment somewhere (I'm not sure if it the stack or malloced memory), and
putenv() will expand it as needed - the programmer doesn't have to.  When you
shell out to a child program, spawn() and system() seem to do the right thing
and create a genuine environment block for the child process using the modified
environment.  The real problem here (I think) is the re-use of the character
pointers used for putenv() - that is a big no-no in my experience and it isn't
explained in the manuals.  It seems that putenv() makes a copy of it's argument
(i.e. the pointer), not the string it points to.

Richard Brittain,                   School of Elect. Eng.,  Upson Hall   
                                    Cornell University, Ithaca, NY 14853
ARPA: richard@calvin.spp.cornell.edu	
UUCP: {uunet,uw-beaver,rochester,cmcl2}!cornell!calvin!richard

cs4g6ag@maccs.dcss.mcmaster.ca (Stephen M. Dunn) (12/02/89)

In article <569@bmers58.UUCP> mlord@bmers58.UUCP (Mark Lord) writes:
$Stephen M. Dunn (hey, that's me!) writes of a problem with putenv in Turbo
$C
$I don't have my DOS references here, but somewhere in the psp is the pointer
$to your environment, that both DOS and TURBOC use (offset 16?).  A pointer to
$your psp is in _PSP, a predefined turbo-c variable that you can use.
$The current size is stored in the MCB (memory control block) which immediately
$preceeds it in memory (again.. no books = no offset for now..).

   The pointer is at offset 2Ch, if memory serves ... but I don't have my
book here, anyway.

[method for solving problem deleted]

   Actually, someone wrote to me with a better answer, which is that
Turbo C doesn't copy your string, it actually just hangs on to the pointer
to it, so you can't reuse the variable.  Now it works.

-- 
Stephen M. Dunn                               cs4g6ag@maccs.dcss.mcmaster.ca
          <std_disclaimer.h> = "\nI'm only an undergraduate!!!\n";
****************************************************************************
They say the best in life is free // but if you don't pay then you don't eat