mark@hsi.UUCP (Mark Sicignano) (10/09/87)
I am trying to change an environment variable from within a Turbo-C program. Turbo-C provides a function, putenv() which will make changes to, add, or delete environment, but any changes are made to the environment within the program, and for child processes. I need for these changes to remain. Is it possible? -mark -- Net : {uunet|ihnp4|yale}!hsi!mark Snail: Health Systems Int'l, 100 Broadway, New Haven, CT 06511 Bell : (203) 562-2101 ext. 32
ljz@fxgrp.UUCP (Lloyd Zusman) (10/11/87)
In article <700@hsi.UUCP> mark@hsi.UUCP (Mark Sicignano) writes: >I am trying to change an environment variable from within >a Turbo-C program. Turbo-C provides a function, putenv() >which will make changes to, add, or delete environment, >but any changes are made to the environment within the program, >and for child processes. > >I need for these changes to remain. Is it possible? Sorry, but what you want to do isn't possible. DOS (be it MSDOS or PCDOS) is written such that no running program can change the environment of its parent. In case you need more explanation, consider this: When you are at the command level of DOS (i.e., when you are entering commands at the terminal), you are actually in a running program. When you run a C program (or whatever), DOS causes the program running at the command level to suspend, and it starts up another program running as a "child" program. This child is somewhat akin to a subprogram. So, using this terminology, the DOS command processor is a "parent" to your C program. Every time DOS starts up a child, it copies the parent's environment into a new area and that becomes the child's environent. Hence, any changes you make to the child's environment have no effect on the parent's environment. The main use of putenv() is so that your C program can start its own child process and pass altered or new values of its environment down to it. This would be done by calling putenv() and then calling one of the spawn() functions. Lloyd Zusman ...!ames!fxgrp!ljz
psfales@ihlpe.ATT.COM (Pete Fales) (10/12/87)
In article <114@fxgrp.UUCP>, ljz@fxgrp.UUCP (Lloyd Zusman) writes: > In article <700@hsi.UUCP> mark@hsi.UUCP (Mark Sicignano) writes: > >I am trying to change an environment variable from within > >a Turbo-C program. Turbo-C provides a function, putenv() > >which will make changes to, add, or delete environment, > >but any changes are made to the environment within the program, > >and for child processes. > > > >I need for these changes to remain. Is it possible? > > > Sorry, but what you want to do isn't possible. DOS (be it MSDOS or PCDOS) ^^^^^^^^^^^^^^ > is written such that no running program can change the environment of its > parent. In case you need more explanation, consider this: > This is rather strong language for an operating system with no memory protection. I have 512 byte program downloaded from a bulletin board called SETVAR.COM that does exactly that. You type SETVAR XXX and one line of standard input is put into XXX in the PARENT environment. I don't know how it works, but it is really nifty. It provides many of the same functions as back-quote substitution under UNIX. Since the file is small, and news won't let me post this article without more text, here is the uuencoded SETVAR.ARC. begin 644 SETVAR.ARC M&@A3151605(N0T]- 2^0@$ "8*E$H"^P " ,Z0H!@%3@ST! *[8I\@ ( MP*!] >H,2(</0"(/!0(8.Q0(0(]%%B@ <"3,Q"(/+!SN U"GP2)M2QP-,S' MPP"'PP0LFJ:$I$D'-Z.%$THT7"*@ 62N^+?HVZ)H.WP,"#!G":P>Z&"Q)-+T MZ9-%#C+ZZCC 1L9^\TS5\7:DJ=8!%C*B:P3 A(X"=1(LVF?"6 $ ZRQ K#H M'MBI*YXQ N8(VUY^\T@Q0M9XZ>$ N #4W5& CH$CXO"M@S*XK<T *[ZMP!C MCY!!ZP3XZ?'PCY\!NPSJ.A!@D3Q$'&@I:!9"E@): HC+:*>(20! ^0#0T6#$ MR")O3\&*%00 ,JE%\Q8IBYP9P"I:3$ A"$!\KWA^\EP-&_(&3AXY:<Z@H0," MQ9@4(,20 PXT@"!&'B 0$88<<N3!!@A%N ""%'6(D88; _D &@A3151605(N M1$]# 2^/0, "8*O4I=N0 % ,#10$! &IP)0B5*P$D0*B10L00][ R2,G MS1DT=$"@&)("1(P<.&B $),'!)$P<N3D80.BB L04NJ(2>,FX,""5-"DF0," MCIPW9^2$:0-"3IDP9'C205,&Q!PZ8=R004D&!$TX=3)&K1IFSAR+;I2B"9/1 M3A@V=<H$I/,&Q-*F9=S82?/339NX95&F"2.&35,W0\M4?>/&+5,08]ZT:;,5 M!!N:95S85- 6TH D9@S_#5S5;$6^?D&0>5.&IYLW&<O@V4F'A=6,.Q$;)2M8 MLD#*!"]G3I-Q=&D0JEF[YFV5)YDR?ND(!M'8Z)C9RJO>X8U&,XB;!-R4N0/" M+%JUMRL/R-G4\]Z^36.?3NU&N=&J--E:CSNW[MWV5LU@?VNTN)L3[+U1QT5% MO:$8"&:\(<=KS$GU&D_>I65;0$7@,10<?ND G!CH-&6<D_QX509='@&@D(, M6;:#4X$QQ]-!5)RX4 \@TC'9$X4914<=<A0F7V*+;>4"D*[!B.*(=(@%5TH* M^F4'<L#%4<=9:WUXF%]NG+$4"&]D]I93=%24I8M?G:%=5?)]:1YHX*$ @SY M6;<F>H@)R$95ZXW4U'-'1<?E@EV5>28(*;P$0A(U*? E7V\\"9R%;6!81I$( M':DCCV$U"!R3<C@)99<@T#"A DZ@UM129(%@Y$*BD68::@B^<>>#=0;IX&/: M,2?'&77<9Z.B;=4!!QQE+#A&5Y,ZU988>Z)4AAEUL!'"AE.$D0=-9ZA:*:LU MRM9G:0&%(5H:9IA1+%[=Z<6F85&!(,*J#%%1Q!14B& H>;'*<9<< ?%)&T_B MSAF:"#6*P&Y&Q[J1)[/,C3%&:7,L-Y>X;P5$Q!-3N NCP4 RYJ";,,9Z)T^\ M ;QKKW@I%>RPQ2*&+*&CYA1;PGKVA!(=:8P1+4ILE%1'Q-"R1--(9'6(8!I^ M\93@@FU$B[.D 1DU!QR$10RP@S7.86@:+D1F6&Q,L0$'3V(471VS0#9%L1QI M!<1&5+R&<49DD^'K$U!"$75'5ZW>X08;;R"UG!D_$?7E$$\T 445\C+$1!!. M'%%%$$<4<9T"8D2;W-!B!"X'?(4-<1:Y"KJQEPLH-,%$$REH (D)&@ :&AH: M&AH:&AH:&AH:&AH:&AH:&AH:&AH:&AH:&AH:&AH:&AH:&AH:&AH:&AH:&AH: 4&AH:&AH:&AH:&AH:&AH:&AH:&AH: end -- Peter Fales UUCP: ...ihnp4!ihlpe!psfales work: (312) 979-7784 AT&T Information Systems, IW 1Z-243 1100 E. Warrenville Rd., IL 60566
hollen@mana.megatek.uucp (Dion Hollenbeck) (10/12/87)
>In article <700@hsi.UUCP> mark@hsi.UUCP (Mark Sicignano) writes: >I am trying to change an environment variable from within >a Turbo-C program. Turbo-C provides a function, putenv() >which will make changes to, add, or delete environment, >but any changes are made to the environment within the program, >and for child processes. > >I need for these changes to remain. Is it possible? If you have enough memory, how about not returning to the DOS command processor by leaving your program, but by creating a child process and running COMMAND.COM which would then be passed a copy of your expanded environment? Have not tried this since I don't need the capability, but it seems a reasonable way to solve it if it works for you. Dion Hollenbeck (619) 455-5590 x2814 Megatek Corporation, 9645 Scranton Road, San Diego, CA 92121 ames!scubed! {sdcsvax,hplabs}!hp-sdd!megatek!hollen sdcsvax!esosun!
acm@bu-cs.BU.EDU (ACM) (10/13/87)
In article <2168@ihlpe.ATT.COM> psfales@ihlpe.ATT.COM (Pete Fales) writes: >In article <114@fxgrp.UUCP>, ljz@fxgrp.UUCP (Lloyd Zusman) writes: >> In article <700@hsi.UUCP> mark@hsi.UUCP (Mark Sicignano) writes: >> >I am trying to change an environment variable from within >> >a Turbo-C program. Turbo-C provides a function, putenv() >> >which will make changes to, add, or delete environment, >> >but any changes are made to the environment within the program, >> >and for child processes. >> > >> >I need for these changes to remain. Is it possible? >> >> >> Sorry, but what you want to do isn't possible. DOS (be it MSDOS or PCDOS) > ^^^^^^^^^^^^^^ >> is written such that no running program can change the environment of its >> parent. In case you need more explanation, consider this: >> > >This is rather strong language for an operating system with no memory >protection. True. The way you do it is look for the pointer to the parent's PSP in your PSP. I forget the actual address of the pointer -- anyone out there know what it is? Anyway, after you find the parent's PSP you can get a pointer to the parent's environment and play with it as you like. it's not a bright idea to expand the environment because this is likely to cause massive memory problems. Expansion of the environment MUST NOT exceed the last paragraph in the environment (or the max size of the parent's environment -- in the case of COMMAND.COM you have some idea of what this will be). Normally you just setblock the environment pointer, but I don't think you can do this if you're playing with a parent process. Another point is that it's easy to backtrace through all the programs currently in memory with the pointer to the parent's PSP. I've seen some programs out there that do it -- nice to see what kind of stuff you've got stuck in memory. jim frost madd@bucsb.bu.edu
dave@westmark.UUCP (Dave Levenson) (10/14/87)
In article <700@hsi.UUCP>, mark@hsi.UUCP (Mark Sicignano) writes: > I am trying to change an environment variable from within > a Turbo-C program. Turbo-C provides a function, putenv() > which will make changes to, add, or delete environment, > but any changes are made to the environment within the program, > and for child processes. In MS-DOS, as in UNIX, you can change your environment, and then export it to your children, but you cannot change your parent's environment. You inherit a copy, and operate on it. Unlike UNIX, however, MS-DOS cannot protect itself from applications that disobey its rules. If you can find out where your parent keeps its environment, you can alter it. The segment address of your environment block appears at offset 2C in your PSP. Offset 16 of your PSP contains the segment address of your parent's PSP. Offset 16 of your parent's PSP points at your grandparent's PSP, and so on. (The first PSP, belonging to COMMAND.COM, points to itself!) Offset 2C of your parent's PSP holds the segment address of your parent's environment block. You probably won't be able to get there with putenv() but with enough chaining through enough far pointers, you can probably accomplish what you want to. -- Dave Levenson Westmark, Inc. A node for news. Warren, NJ USA {rutgers | clyde | mtune | ihnp4}!westmark!dave
paula@bcsaic.UUCP (Paul Allen) (10/15/87)
In article <700@hsi.UUCP>, mark@hsi.UUCP (Mark Sicignano) writes: >I am trying to change an environment variable from within >a Turbo-C program. Turbo-C provides a function, putenv() >which will make changes to, add, or delete environment, >but any changes are made to the environment within the program, >and for child processes. > >I need for these changes to remain. Is it possible? I've seen several responses to this, ranging from "It's impossible" to "here's a PD program that does it". So far, noone has mentioned undocumented interrupt 1EH. This interrupt takes as an argument a pointer to a string containing a command to be executed by command.com. The first byte of the string is a count of the remaining bytes. If you pass it "set foo=bar", it will set the variable foo in command.com's environment space. A little thought will turn up all sorts of nifty uses for this capability. In fact, one of my unfinished projects at home is a little program that understands commands like !!, history, and alias, and passes everything it doesn't understand off to command.com. Caveats: I have used this undocumented feature, and it works, but it is probably undocumented for a reason. I am working from memory, or I could tell you which register to put the string address in. If you really want it, e-mail me. Or check Ray Duncan's column in back issues of Dr. Dobb's or the Best of BIX column in back issues of BYTE. Paul Allen paula@boeing.com ...!uw-beaver!ssc-vax!bcsaic!paula
wew@naucse.UUCP (Bill Wilson) (10/16/87)
You cannot make changes to the environmemt without knowing where it is housed in memory. Good luck, I haven't found out where it is yet.
paula@bcsaic.UUCP (Paul Allen) (10/17/87)
This is an update to my recent posting (2400@bcsaic.UUCP) describing the back-door interface to command.com. As usual, posting from memory has gotten me into trouble! I was describing interrupt 2EH, *not* interrupt 1EH! From the current BYTE "Inside the IBM PCs" special issue, page 168, comes the following data: Undocumented interrupt 2EH causes command.com to execute a command pointed to by ds:si. The first byte of the command is the number of bytes in the command. The command must end with a carriage return, just as if it had been typed on the keyboard. The article is not clear on whether the cr is included in the byte count. So, to change something in command.com's environment, a small model program could simply construct the command, put its ds-relative offset in si, and do an int 2EH. One side-effect of this technique is that any output from the command will go to command.com's stdout (the screen). Another poster described a way to change command.com's environment by following the chain of parent PSP pointers until you find command.com's. Passing "set foo=bar" to int 2EH seems considerably easier to me. Int 2EH has been described in depth in Ray Duncan's column in Dr. Dobb's Journal. There may also have been information in BYTE's "Best of BIX" column. I have used it on MSDOS 2.1. I seem to remember that one of Ray Duncan's articles claimed it would work on everything since version 2.0, but you ought to check that out for yourself. Paul Allen paula@boeing.com ...!uw-beaver!ssc-vax!bcsaic!paula
darrylo@hpsrlc.HP.COM (Darryl Okahata) (10/17/87)
In comp.sys.ibm.pc, paula@bcsaic.UUCP (Paul Allen) writes: > In article <700@hsi.UUCP>, mark@hsi.UUCP (Mark Sicignano) writes: > >I am trying to change an environment variable from within > >a Turbo-C program. Turbo-C provides a function, putenv() > >which will make changes to, add, or delete environment, > >but any changes are made to the environment within the program, > >and for child processes. > > > >I need for these changes to remain. Is it possible? > > I've seen several responses to this, ranging from "It's impossible" to > "here's a PD program that does it". So far, noone has mentioned > undocumented interrupt 1EH. This interrupt takes as an argument a [ ... ] > Caveats: > > I have used this undocumented feature, and it works, but it is probably > undocumented for a reason. I am working from memory, or I could tell [ ... ] > > Paul Allen > paula@boeing.com > ...!uw-beaver!ssc-vax!bcsaic!paula > ---------- Int 2EH only seems to change the environment of the topmost invocation of command.com. For example, if you run another copy of command.com, and run a program which changes the environment via Int 2EH, you will find that the environment of the second copy of command.com has not changed. You will have to EXIT the second copy before the changes will become visible. Also, if I remember correctly, Int 2EH destroys ALL registers, including those of the STACK. Yuk! -- Darryl Okahata {hplabs!hpccc!, hpfcla!} hpsrla!darrylo CompuServe: 75206,3074 Disclaimer: the above is the author's personal opinion and is not the opinion or policy of his employer or of the little green men that have been following him all day.
ljz@fxgrp.UUCP (Lloyd Zusman) (10/22/87)
With regard to using int 2Eh to cause the top-level command interpreter to execute a command line ... Yes, this can be used to set an environment variable in the top-level command interpreter, but there are some caveats that may or may not be important: 1) This is an undocumented DOS call, meaning that it may go away or change. 2) Once you use it to set an environment variable in the top-level command interpreter, the varible DOES NOT propagate down to all the children of this top-level interpreter. In other words, assume I have booted up my PC and I'm sitting at the command prompt: C> I type SET and I get a list of environment variables containing the line FOO=BAR This means that there is a variable named FOO in my environment with the value BAR. Now, suppose I have written a C program that contains the following code fragment ... extern char *getenv(); char *ep = getenv("FOO"); printf("FOO=%s\n", ep ? ep : "<NOT SET>"); int1e("SET FOO=QUACK"); ep = getenv("FOO"); printf("FOO=%s\n", ep ? ep : "<NOT SET>"); Assume that the int1e() function passes its string argument to int 1Eh properly. The output of this program fragment will be FOO=BAR FOO=BAR It will NOT be FOO=BAR FOO=QUACK as you might hope. But after the program returns control to DOS, the next time you type SET, you will see the line FOO=QUACK in your environment. If you insert the following call after the int1e() call in the above program putenv("FOO=QUACK") then you will see the value of the variable FOO change during the course of running the program. To make it worse, suppose that from DOS I run a program that causes a subshell to run, and within this subshell, the above program is run (the version with the putenv()). What will happen is that the top level environment will be changed (via the int 1Eh), the environment in effect while the program is running will be changed (via the putenv() call), but the environments for all processes inbetween these will stay the same. If this sort of thing is what you want, then int 1Eh is useful. Otherwise, be careful. 3) I have had applications hang when making use of int 1Eh. I think it might have to do with the amount of space taken up by TSR ("Terminate and Stay Resident") programs, the version of DOS that's being run, etc. Be careful.
zu@ethz.UUCP (Urs Zurbuchen) (10/28/87)
In article <2434@bcsaic.UUCP> paula@bcsaic.UUCP (Paul Allen) writes: > ... Another poster >described a way to change command.com's environment by following the >chain of parent PSP pointers until you find command.com's. Passing "set >foo=bar" to int 2EH seems considerably easier to me. You forget one thing: Using Int 2Eh you can't set a variable to a string longer than about 120 characters. The exact amount depends on the length of the variablename. You only can execute commands of a total length of 128 (or 127) characters. ...urs UUCP: ...seismo!mcvax!cernvax!ethz!zu