PDA

View Full Version : system("set var=num") not working



MortalMonkey
02-29-2004, 08:33 AM
I've been fascinated by the simplicity of batch files for quite some time, but now I'm trying to expand their capabilities.

The first thing I've tried is a simple randomizer. It works quite well if I just return the random integer, then use 'if errorlevel' in the batch file, but to make things easier, I wanted to allow the randomizer to directly set a variable in the console.
To do this, I tried

if (argv[3] != '\0')
{
snprintf(setcmd, sizeof(setcmd), "set %s=%d", argv[3], r);
system(setcmd);
}
which did not work, even though printing setcmd showed it held the right console command.
The weird thing is, other commands such as "echo Foo" and "cls" work, it's just "set var=num" that doesn't.

Any explanation as to why it is so and/or how to go around it would be much appreciated.

alex
03-02-2004, 11:04 AM
Sorry, that won't work.

The system function starts a new version of command.com. Command.com sets the environment variable in it's own copy of the environment, and than exits. This is exactly what you have programmed, but not what you intended.

alex

MortalMonkey
03-02-2004, 12:12 PM
I suspected that too, but then why would echo's show up in the same console?
Thanks anyway.

alex
03-02-2004, 03:34 PM
Hi!

The command.com that is executed (spawned) by the system function inherits the console, so stdout and stderr write to the same console. And stdin reads from the same console, so PAUSE will also work ;). There is a way to change environment variable of the calling program. See Ralf Brown's Interrup list (http://www-2.cs.cmu.edu/~ralf/files.html) and search for "Program Segment Prefix" (PSP). Since DOS 2 or so, it contains a pointer to the PSP of the "parent process", and a pointer to the list of environment variables.

So your program would need to find it's own PSP (CS:0, if it is a .COM-file), find its parent PSP, read the pointer to the environment of that proces, and then change that environment by hand. Have fun...

alex

p.s. Did you know the freedos (http://www.freedos.org) project?

VirtualAce
03-02-2004, 04:37 PM
....and invoking interrupts from a console app is not only not allowed, its not supported either. You would have to invoke an interrupt from assembly - alas there is a much better way to do what you want.

alex
03-03-2004, 05:39 AM
Err...

Well, I was assuming that MortalMonkey was using an old-fashioned "16-bit" legacy compiler to create his utility. Moreover, I mentioned Ralf Brown's interrup(t) list, not because he should use an interrupt service, but to look at the documentation of the structure of the psp. I agree that this is all legacy dos stuff (and that's why I mentioned the freedos project). The approach I mentioned is most probably incorrect for 32-bit windows console applications.

You say that there is a better way to do this? I am curious...

alex

p.s. I seem to remember that the old Turbo C compiler provided a pointer to the psp; iirc it was _psp.

MortalMonkey
03-03-2004, 09:57 AM
Thanks, but actually I'm one of those win98 freaks that pop up once in a moon (wrong board then maybe?).
I'd convert to Linux, but my ISP refers me to a 404 for instructions on how to connect with it.

Anyway, I came across that freedos site when searching for dos games on one of the school's computers (they're the only ones that work :p) but I must have forgotten about it. I'll give it a spin tho.

VirtualAce
03-03-2004, 04:36 PM
Well I have the DOS 6.20 tech ref and there are multiple functions that will allow you to set/change environment variables. In fact, Microsoft does not want you poking around the PSP area w/o first telling DOS you are doing it. Kind of like installing an interrupt directly into the chain w/o calling DOS to do it - it works, but sooner or later DOS is gonna puke it up.