Discussion:
PATH
(too old to reply)
muta...@gmail.com
2021-04-23 16:19:39 UTC
Permalink
In MSDOS (and is it universal?), who is responsible
for scanning through the PATH environment variable
when you do a system()?

And what is the logic behind this decision?

Options I see are:

1. The C library can scan the PATH, since the
environment variable is available to it.

2. The C library can invoke a new copy of "command.com"
(or whatever "SHELL" is set to (will it always be set?))
and pass "/c" and the command, and it will scan the PATH.

3. MSDOS can receive the program name and scan the
PATH to find the executable, since it also has access
to the environment variable (after all, it passed that to
the executable in the first place).

Or maybe all of them can do it.

I'm interested in the philosophy before coding one or
more of those things.

Thanks. Paul.
Alexei A. Frounze
2021-04-23 20:08:20 UTC
Permalink
Post by ***@gmail.com
In MSDOS (and is it universal?), who is responsible
for scanning through the PATH environment variable
when you do a system()?
And what is the logic behind this decision?
1. The C library can scan the PATH, since the
environment variable is available to it.
2. The C library can invoke a new copy of "command.com"
(or whatever "SHELL" is set to (will it always be set?))
and pass "/c" and the command, and it will scan the PATH.
3. MSDOS can receive the program name and scan the
PATH to find the executable, since it also has access
to the environment variable (after all, it passed that to
the executable in the first place).
Or maybe all of them can do it.
I'm interested in the philosophy before coding one or
more of those things.
Thanks. Paul.
I should remind that in DOS when you execute a command
through command.com (%COMSPEC% /c <command>),
command.com does not report errors occurring within
back to the caller. command.com typically (always?)
returns 0. For this reason in Smaller C's system()
I put some logic to see if the caller is trying to execute
another program (with name ending in .EXE or .COM) and
in that case do so directly, w/o involving command.com,
so the program's exit code can be obtained.
And if you're making a program that executes other programs
(e.g. a compiler that's made up of separate programs),
you really want to know the exit code, so you can automate
things and provide decent user experience in case when
there is an error.

So, system() may indeed traverse %PATH% even though
command.com does it itself as well.
It's just you don't always want to run command.com.

Windows's cmd.exe doesn't swallow the exit code and so
it needs no such workaround.

HTH,
Alex
muta...@gmail.com
2021-04-23 23:16:24 UTC
Permalink
Post by Alexei A. Frounze
I should remind that in DOS when you execute a command
through command.com (%COMSPEC% /c <command>),
Thanks. I see that that variable is defined in PDOS too.
Post by Alexei A. Frounze
command.com does not report errors occurring within
back to the caller. command.com typically (always?)
returns 0.
Ok, thanks. Maybe I should change that in PDOS/86.
I don't see a reason to be bound to Microsoft's decisions.
I changed the behavior of C90 on the mainframe too,
compared to IBM C.
Post by Alexei A. Frounze
For this reason in Smaller C's system()
I put some logic to see if the caller is trying to execute
another program (with name ending in .EXE or .COM) and
in that case do so directly, w/o involving command.com,
so the program's exit code can be obtained.
Ok. I forgot about the need to execute .bat files too,
so that is a strong imperative to use command.com.
Post by Alexei A. Frounze
And if you're making a program that executes other programs
(e.g. a compiler that's made up of separate programs),
you really want to know the exit code, so you can automate
things and provide decent user experience in case when
there is an error.
Ok.
Post by Alexei A. Frounze
So, system() may indeed traverse %PATH% even though
command.com does it itself as well.
It's just you don't always want to run command.com.
Ok.
Post by Alexei A. Frounze
Windows's cmd.exe doesn't swallow the exit code and so
it needs no such workaround.
Ok, cool. I think I will be consistent then.

Hopefully I'll do that today.

BFN. Paul.
muta...@gmail.com
2021-04-24 04:32:00 UTC
Permalink
Post by ***@gmail.com
Post by Alexei A. Frounze
I should remind that in DOS when you execute a command
through command.com (%COMSPEC% /c <command>),
Thanks. I see that that variable is defined in PDOS too.
I'm thinking that if COMSPEC is set to an empty string,
or something like that, then the COMSPEC plus "/c"
should be omitted to give the user some flexibility of
bypassing the MSDOS-style shell.

Or maybe another environment variable, COMPREF which
if not set defaults to "/c". E.g. a command processor may
require "-c" instead of "/c", or something else entirely, or
nothing.

Any suggestions?

BFN. Paul.
Alexei A. Frounze
2021-04-24 04:48:47 UTC
Permalink
Post by ***@gmail.com
Post by ***@gmail.com
Post by Alexei A. Frounze
I should remind that in DOS when you execute a command
through command.com (%COMSPEC% /c <command>),
Thanks. I see that that variable is defined in PDOS too.
I'm thinking that if COMSPEC is set to an empty string,
or something like that, then the COMSPEC plus "/c"
should be omitted to give the user some flexibility of
bypassing the MSDOS-style shell.
Or maybe another environment variable, COMPREF which
if not set defaults to "/c". E.g. a command processor may
require "-c" instead of "/c", or something else entirely, or
nothing.
Any suggestions?
Not sure what problem you're trying to solve.

Continuing the previous subject...
system() should invoke the "command processor".
If you understand that as command.com (or your supposedly
compatible implementation of it), then you need to invoke it
or make it look like you do whereas you actually don't.
In DOS it's easy to fake it because there aren't that many
ways to meaningfully and usefully distinguish direct
execution of another program via function 4B00h vs
indirect, via command.com.
OTOH, the C standard does not define what "command
processor" is and how it works. So, you can legally do
something rather unconventional.

Also, IIRC, DOS C compilers allowed both simple execution
of command.com until the user exits it and execution of
other programs/commands via command.com.
In the latter case "/C " would enter the scene.
The distinction between the two is made by the content
of the string passed to system(). That is, empty vs non-empty.
Not to confuse with a NULL pointer passed to system()
which has a special meaning per the C standard.

Alex
muta...@gmail.com
2021-04-24 21:03:31 UTC
Permalink
Post by Alexei A. Frounze
Post by ***@gmail.com
Post by ***@gmail.com
Post by Alexei A. Frounze
I should remind that in DOS when you execute a command
through command.com (%COMSPEC% /c <command>),
Thanks. I see that that variable is defined in PDOS too.
I'm thinking that if COMSPEC is set to an empty string,
or something like that, then the COMSPEC plus "/c"
should be omitted to give the user some flexibility of
bypassing the MSDOS-style shell.
Or maybe another environment variable, COMPREF which
if not set defaults to "/c". E.g. a command processor may
require "-c" instead of "/c", or something else entirely, or
nothing.
Any suggestions?
Not sure what problem you're trying to solve.
Let's say my command processor is from an entirely
alien system that knows nothing about MSDOS. And
is called bash.exe.

And to execute a single command you go:
bash --single-command ls -l

And I have a "ls -l" in a makefile, so that is being read
and executed.

How do you suggest that work without a COMPREF
or similar?

BFN. Paul.

Continue reading on narkive:
Loading...