Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to index page
Thread view  Board view
alexfru(R)

USA,
11.09.2014, 21:26
 

C's system() & COMMAND.COM (Developers)

I've started a thread on comp.os.msdos.programmer, but posting it here to widen the audience.

I'm implementing system() in the DOS version of my compiler's (Smaller C) standard C library and having a bit of a dilemma.

It appears that if I build system("command") around "%COMSPEC% /C command", neither the "execute" function 0x4b00 nor the "get exit code" function 0x4d does return the exit code from "command" if "command" resolves to a .COM/.EXE executable. Looks like I'm getting success exit code of 0 from COMMAND.COM itself.

This is unfortunate since I can't easily detect errors in child processes based on their exit code.

I can think of a few pretty nasty workarounds.

1. Do COMMAND.COM's job and find the full path of the .COM/.EXE and execute it directly without involving "COMMAND.COM /C". The problem here is that even though I can traverse %PATH% and find the executable, if it's there, I need to know that the command is not one of COMMAND.COM's internal commands and the set of command processor's commands varies between DOS versions and vendors and DOS emulators (e.g. DosBox). I don't want to incorporate substantial knowledge about different DOS versions into the library. I don't feel it's the right way to do things.

2. Hook int 0x20 and int 0x21's function 0x4c that are used to terminate executables and note terminations and stash away the exit codes (from function 0x4c only as int 0x20 doesn't take any exit code). If I ignore the last one (from COMMAND.COM), then the next one is from my executable. But again, what if the command resolves to a batch file, which in turn invokes a .COM/.EXE? In that case occasionally I'm going to get the exit code that has nothing to do with batch file execution. Further, I may run into trouble hooking DOS interrupts. Either DOS may not appreciate it or some ancient anti-virus may block such suspicious activity.

I could probably devise a more intrusive workaround, but it might result in incompatibilities with various DOSes and be even more fragile.

Any suggestions, ideas?

Thanks,
Alex

nidud(R)

E-mail

Norway,
11.09.2014, 23:22

@ alexfru
 

C's system() & COMMAND.COM

Borland

int system(const char *command) - issues an MS-DOS command

system invokes the MS-DOS command processor to
execute a command given in the string command, as if the command
had been typed at the DOS prompt.

The COMSPEC environment variable is used to find the
command processor file, so the file does not need to be in
the current directory.

If command is a NULL pointer then system() returns nonzero if
a command processor is available.  If command is not a NULL pointer,
system() returns zero if the command processor was successfully
started.  If an error occurred, a -1 is returned and errno is set to
ENOENT, ENOMEM, E2BIG, or ENOEXEC.

ENOENT  - command processor not found
ENOMEM  - not enough memory
E2BIG   - argument list too long
ENOEXEC - the command processor is not a valid executable

Microsoft

int system(command) - send the command line to a shell

Executes a shell and passes the command line to it.
If command is NULL, determine if a command processor exists.

char *command - command to pass to the shell
(if NULL, just determine if command processor exists)

if command != NULL  returns status of the shell
if command == NULL  returns non-zero if CP exists, zero if CP doesn't exist

alexfru(R)

USA,
12.09.2014, 02:55

@ nidud
 

C's system() & COMMAND.COM

> Borland
>
...
>

> Microsoft
>
...
>


I'm sorry for being unable to read your mind. What did you want to say with this?

nidud(R)

E-mail

Norway,
12.09.2014, 12:44

@ alexfru
 

C's system() & COMMAND.COM

> I'm sorry for being unable to read your mind. What did you want to say with
> this?

That all return codes from system() comes from %COMSPEC% and not from the .COM/.EXE/.BAT files executed.

alexfru(R)

USA,
13.09.2014, 00:54

@ nidud
 

C's system() & COMMAND.COM

> > I'm sorry for being unable to read your mind. What did you want to say
> with
> > this?
>
> That all return codes from system() comes from %COMSPEC% and not from the
> .COM/.EXE/.BAT files executed.

That is exactly the problem I came with and posted about.

Alex

nidud(R)

E-mail

Norway,
13.09.2014, 14:54

@ alexfru
 

C's system() & COMMAND.COM

> >
> > That all return codes from system() comes from %COMSPEC% and not from
> the
> > .COM/.EXE/.BAT files executed.
>
> That is exactly the problem I came with and posted about.
>
> Alex

My point was that those using the system function may expect COMSPEC to be executed in this case, and you mention a few of the (good) reasons why in point one in your first post. Other functions are normally used to call .EXE/.COM files directly.

I assume one way to get the return code using COMSPEC from .EXE/.COM files is to use a batch file.

COMMAND.COM will return an ?errorlevel? in INT 0x21/0x4D from a batch file, but not from an .EXE/.COM file.

COMMAND /C return9.exe -- returns 0

exec.bat:
return9.exe

COMMAND /C exec.bat -- returns 9

System(command):
        create(%TEMP%\exec.bat)
        write(file,?%s\n?, command)
        close(file)
        execute(file)
        getresult()
        delete(file)
        return result

tom(R)

Homepage

Germany,
12.09.2014, 13:10

@ alexfru
 

C's system() & COMMAND.COM

> I'm sorry for being unable to read your mind. What did you want to say with
> this?

if you want to be compatible to Borland or Microsoft, system("command") is equivalent to %COMSPEC%/c command, and there is no errorlevel returned from the executed command available.

that's the way it is (and saves you a lot of work ;)

marcov(R)

12.09.2014, 20:00

@ tom
 

C's system() & COMMAND.COM

> if you want to be compatible to Borland or Microsoft, system("command") is
> equivalent to %COMSPEC%/c command, and there is no errorlevel returned
> from the executed command available.

FWIW:

I looked up the system() function in my copy of K&R 2nd edition, and it says

"In the UNIX system, the status return is the value returned by exit"

Further it says "the return value is implementation-dependent".

alexfru(R)

USA,
13.09.2014, 01:05

@ marcov
 

C's system() & COMMAND.COM

> FWIW:
>
> I looked up the system() function in my copy of K&R 2nd edition, and it
> says
>
> "In the UNIX system, the status return is the value returned by exit"
>
> Further it says "the return value is implementation-dependent".

Check out some more modern stuff.

http://pubs.opengroup.org/onlinepubs/009695399/functions/system.html:

"
If command is not a null pointer, system() shall return the termination status of the command language interpreter in the format specified by waitpid(). The termination status shall be as defined for the sh utility; ...
"

http://pubs.opengroup.org/onlinepubs/009695399/functions/waitpid.html:

"
The value stored at the location pointed to by stat_loc shall be 0 if and only if the status returned is from a terminated child process that terminated by one of the following means:

The process returned 0 from main().

The process called _exit() or exit() with a status argument of 0.

The process was terminated because the last thread in the process terminated.
"

http://pubs.opengroup.org/onlinepubs/009695399/utilities/sh.html:

"
The following exit values shall be returned:

0
The script to be executed consisted solely of zero or more blank lines or comments, or both.
1-125
A non-interactive shell detected a syntax, redirection, or variable assignment error.
127
A specified command_file could not be found by a non-interactive shell.

Otherwise, the shell shall return the exit status of the last command it invoked or attempted to invoke...
"

I can reasonably expect to get 0 from system() on POSIX systems if the command has succeeded (main() returned with 0) and non-zero otherwise.

Alex

marcov(R)

13.09.2014, 14:02

@ alexfru
 

C's system() & COMMAND.COM

> > "In the UNIX system, the status return is the value returned by exit"
> >
> > Further it says "the return value is implementation-dependent".
>
> Check out some more modern stuff.
>
> http://pubs.opengroup.org/onlinepubs/009695399/functions/system.html:

That's Unix(POSIX), not C. What are you doing, implementing a C compiler or an Unix-on-Dos emulation (as a cygwin for dos)?

The page says it is aligned with C, but the popup says that paragraph is an extension to C, so it would still be interesting what a newer C standard (C99) says about it. I may have that at work, which I can't access now.

That was the whole point of my post, to make the separation between POSIX and C.

alexfru(R)

USA,
13.09.2014, 14:21

@ marcov
 

C's system() & COMMAND.COM

> > > "In the UNIX system, the status return is the value returned by exit"
> > >
> > > Further it says "the return value is implementation-dependent".
> >
> > Check out some more modern stuff.
> >
> > http://pubs.opengroup.org/onlinepubs/009695399/functions/system.html:
>
> That's Unix(POSIX), not C. What are you doing, implementing a C
> compiler or an Unix-on-Dos emulation (as a cygwin for dos)?

Not really.

I want POSIX-ish behavior of system(). Some DOS compilers provide it and I am depending on it and implementing it in my C library for DOS.

I also throw in a few things like open(), lseek(), unlink() as the lowest level functions sitting between DOS system calls and fopen(), fseek() and remove(), but I may either remove them entirely or make them available only when they're actually used. I haven't decided yet. But there's no intention to provide much outside of standard C.

> The page says it is aligned with C, but the popup says that paragraph is an
> extension to C, so it would still be interesting what a newer C standard
> (C99) says about it. I may have that at work, which I can't access now.

There's nothing of interest in C99. The return value of system(non-NULL pointer) is implementation-defined according to it.

> That was the whole point of my post, to make the separation between POSIX
> and C.

I do know the difference.

marcov(R)

13.09.2014, 16:50

@ alexfru
 

C's system() & COMMAND.COM

> > That's Unix(POSIX), not C. What are you doing, implementing a C
> > compiler or an Unix-on-Dos emulation (as a cygwin for dos)?
>
> Not really.
>
> I want POSIX-ish behavior of system(). Some DOS compilers provide it and I
> am depending on it and implementing it in my C library for DOS.

As you wish. If you don't want to do it the proper way (with a POSIX compatible shell, since that is the part that returns the errorlevel to system), then parsing/interpreting the commandline is the only way I guess.

But of course that is fragile. If sb uses 4/ndos it might already break, since that has more built-ins.

Maybe looking at source of opensourced dos compilers (like watcom) can give you a clue. I don't have much experience of attempting to do POSIX outside *nix from an implementation viewpoint, since our runtime opts more for native.

> > The page says it is aligned with C, but the popup says that paragraph is
> an
> > extension to C, so it would still be interesting what a newer C
> standard
> > (C99) says about it. I may have that at work, which I can't access now.
>
> There's nothing of interest in C99. The return value of system(non-NULL
> pointer) is implementation-defined according to it.

Thanks, that saves me the time of looking it up.

alexfru(R)

USA,
13.09.2014, 17:06

@ marcov
 

C's system() & COMMAND.COM

> > > That's Unix(POSIX), not C. What are you doing, implementing a C
> > > compiler or an Unix-on-Dos emulation (as a cygwin for dos)?
> >
> > Not really.
> >
> > I want POSIX-ish behavior of system(). Some DOS compilers provide it and
> I
> > am depending on it and implementing it in my C library for DOS.
>
> As you wish. If you don't want to do it the proper way (with a POSIX
> compatible shell, since that is the part that returns the errorlevel to
> system), then parsing/interpreting the commandline is the only way I
> guess.
>
> But of course that is fragile. If sb uses 4/ndos it might already break,
> since that has more built-ins.
>
> Maybe looking at source of opensourced dos compilers (like watcom) can give
> you a clue. I don't have much experience of attempting to do POSIX outside
> *nix from an implementation viewpoint, since our runtime opts more for
> native.

DJGPP looks at the extension and executes .COM/.EXE directly if the extension is present.

OW seems to do that and also consult a list of what it thinks are COMMAND.COM's commands.

For me checking the extension and possibly traversing PATH is good enough.

marcov(R)

13.09.2014, 20:24

@ alexfru
 

C's system() & COMMAND.COM

>
> DJGPP looks at the extension and executes .COM/.EXE directly if the
> extension is present.
>
> OW seems to do that and also consult a list of what it thinks are
> COMMAND.COM's commands.
>
> For me checking the extension and possibly traversing PATH is good enough.

Don't forget to expand %environmentvariables% too.

alexfru(R)

USA,
16.09.2014, 23:27

@ marcov
 

C's system() & COMMAND.COM

> >
> > DJGPP looks at the extension and executes .COM/.EXE directly if the
> > extension is present.
> >
> > OW seems to do that and also consult a list of what it thinks are
> > COMMAND.COM's commands.
> >
> > For me checking the extension and possibly traversing PATH is good
> enough.
>
> Don't forget to expand %environmentvariables% too.

What is %environmentvariables%? Or do you want to say that I should not forget about things like %foo%.exe?

marcov(R)

17.09.2014, 13:03

@ alexfru
 

C's system() & COMMAND.COM

> What is %environmentvariables%? Or do you want to say that I should not
> forget about things like %foo%.exe?

Yes, if you execute directly, you must resolve those yourself.

alexfru(R)

USA,
17.09.2014, 13:07

@ marcov
 

C's system() & COMMAND.COM

> > What is %environmentvariables%? Or do you want to say that I should not
> > forget about things like %foo%.exe?
>
> Yes, if you execute directly, you must resolve those yourself.

I've decided to bail out on commands containing % and a number of reserved characters, including those used for redirection.

bretjohn(R)

Homepage E-mail

Rio Rancho, NM,
15.09.2014, 19:24

@ alexfru
 

C's system() & COMMAND.COM

> DJGPP looks at the extension and executes .COM/.EXE directly if the
> extension is present.
>
> OW seems to do that and also consult a list of what it thinks are
> COMMAND.COM's commands.
>
> For me checking the extension and possibly traversing PATH is good enough.

All very dangerous roads to go down, especially with things like 4DOS around (aliases, BTM files, etc.). Even MS-DOS has an extensibility function (INT 2F.AE00/AE01) that allows you to effectively add your own "internal" commands (via TSR's) to the ones built into the shell. Basically, you can never be certain what all of the "internal" commands (which get processed before any executable file even if they have the same name) really are.

Internal commands are ALWAYS processed first, so even if you find a valid COM/EXE/BAT/BTM with the appropriate name, it may not be what actually gets processed.

alexfru(R)

USA,
16.09.2014, 23:24

@ bretjohn
 

C's system() & COMMAND.COM

> > DJGPP looks at the extension and executes .COM/.EXE directly if the
> > extension is present.
> >
> > OW seems to do that and also consult a list of what it thinks are
> > COMMAND.COM's commands.
> >
> > For me checking the extension and possibly traversing PATH is good
> enough.
>
> All very dangerous roads to go down, especially with things like 4DOS
> around (aliases, BTM files, etc.). Even MS-DOS has an extensibility
> function (INT 2F.AE00/AE01) that allows you to effectively add your own
> "internal" commands (via TSR's) to the ones built into the shell.
> Basically, you can never be certain what all of the "internal" commands
> (which get processed before any executable file even if they have the same
> name) really are.
>
> Internal commands are ALWAYS processed first, so even if you find a valid
> COM/EXE/BAT/BTM with the appropriate name, it may not be what actually gets
> processed.

If I execute a .COM/.EXE directly (int 21h function 4b00h) and not via "%COMSPEC% /C", it should just work, no matter what internal commands are.

marcov(R)

17.09.2014, 13:04

@ alexfru
 

C's system() & COMMAND.COM

> > Internal commands are ALWAYS processed first, so even if you find a
> valid
> > COM/EXE/BAT/BTM with the appropriate name, it may not be what actually
> gets
> > processed.
>
> If I execute a .COM/.EXE directly (int 21h function 4b00h) and not via
> "%COMSPEC% /C", it should just work, no matter what internal commands are.

The point is that the person calling the shell might have wanted the internal command. You are basically changing priorities there.

alexfru(R)

USA,
17.09.2014, 13:08

@ marcov
 

C's system() & COMMAND.COM

> > > Internal commands are ALWAYS processed first, so even if you find a
> > valid
> > > COM/EXE/BAT/BTM with the appropriate name, it may not be what actually
> > gets
> > > processed.
> >
> > If I execute a .COM/.EXE directly (int 21h function 4b00h) and not via
> > "%COMSPEC% /C", it should just work, no matter what internal commands
> are.
>
> The point is that the person calling the shell might have wanted the
> internal command. You are basically changing priorities there.

IFF an internal command ends in .COM/.EXE, which is sick.

bretjohn(R)

Homepage E-mail

Rio Rancho, NM,
17.09.2014, 20:42

@ alexfru
 

C's system() & COMMAND.COM

> IFF an internal command ends in .COM/.EXE, which is sick.

The fact that you think it's "sick" is irrelevant. You could have some or all of the following with the same name: a COM, EXE, BAT, and BTM file, a 4DOS alias, a DOSKEY macro, an INT 2F.AE internal extension, and an internal command (and the may even be other possibilities you could add to the list). If the user simply types the name at a command line, what happens?

The answer actually depends on what brand and version of DOS is being used, teh environment, and what TSR's and device drivers are loaded as well. What various versions of MS-DOS does is described here:

http://support.microsoft.com/kb/35284

What your program should do is the same thing that would happen if the user simply typed the same thing at the command-line. The problem is there's no way you can know what that is. The only sane thing you can do is a "%COMSPEC% /C ..." and figure out some other way to return the ErrorLevel if that's critical to you.

alexfru(R)

USA,
17.09.2014, 22:53

@ bretjohn
 

C's system() & COMMAND.COM

> > IFF an internal command ends in .COM/.EXE, which is sick.
>
> The fact that you think it's "sick" is irrelevant. You could have some or
...
> The problem is there's no
> way you can know what that is. The only sane thing you can do is a
> "%COMSPEC% /C ..." and figure out some other way to return the ErrorLevel
> if that's critical to you.

That's the very problem I came with. I don't need it to be restated to me. Can you be more specific? Otherwise, those are empty and meaningless words.

marcov(R)

18.09.2014, 12:18

@ alexfru
 

C's system() & COMMAND.COM

> > The problem is there's no
> > way you can know what that is. The only sane thing you can do is a
> > "%COMSPEC% /C ..." and figure out some other way to return the
> ErrorLevel
> > if that's critical to you.
>
> That's the very problem I came with. I don't need it to be restated to me.
> Can you be more specific? Otherwise, those are empty and meaningless words.

If you are so focussed on the exitcode, I think simplest is having both. One focusses on errorlevel, and one that really always runs the shell.

Depending on the codebases that you run, you select the variant that gets the system() identifier. Or make it an alias even depending on a define in the header. (like #ifdef unicode in windows headers)

And document it very, very thoroughly.

alexfru(R)

USA,
18.09.2014, 13:33

@ marcov
 

C's system() & COMMAND.COM

> > > The problem is there's no
> > > way you can know what that is. The only sane thing you can do is a
> > > "%COMSPEC% /C ..." and figure out some other way to return the
> > ErrorLevel
> > > if that's critical to you.
> >
> > That's the very problem I came with. I don't need it to be restated to
> me.
> > Can you be more specific? Otherwise, those are empty and meaningless
> words.
>
> If you are so focussed on the exitcode, I think simplest is having both.
> One focusses on errorlevel, and one that really always runs the shell.
>
> Depending on the codebases that you run, you select the variant that gets
> the system() identifier. Or make it an alias even depending on a define in
> the header. (like #ifdef unicode in windows headers)
>
> And document it very, very thoroughly.

I may (I probably should) document my implementation of system(), but other than that I don't think I care enough about the specific combination of these:
- an ancient 16-bit OS (all kinds of DOS and its clones)
- ancient non-standard extensions to the ancient OS (TSRs, shells replacing COMMAND.COM and the like, especially those additionally crippled license-wise (e.g. 4DOS and its ties to FreeDOS)) that I don't know, don't have, am not willing to acquire, test and support
- a compiler that is a little more than just a toy, but more not by a lot

Plain DOS, no weird stuff, that's the environment I can and am willing to handle.

I see no point making things more complex than truly necessary, given the expected frequency of use and usage scenarios themselves and that the whole exercise is meant to be for fun in the first place.

You may lament about certain limitations and incompatibilities and so may I, but realistically there aren't that many options:
- contributions by other people (so far there have been nearly zero contributions in almost 2 years of Smaller C's existence online)
- people pay me enough to make it my job and I pay attention to the paying hand instead of weighing the pros and the cons of doing this or that unpaid work in spare time and not doing something else or earning more money instead
- ???
Isn't it how it works with many hobby projects?

Rugxulo(R)

Homepage

Usono,
18.09.2014, 15:20

@ alexfru
 

C's system() & COMMAND.COM

> I may (I probably should) document my implementation of system(), but other
> than that I don't think I care enough about the specific combination of
> these:
> - ancient non-standard extensions to the ancient OS (TSRs, shells replacing
> COMMAND.COM and the like, especially those additionally crippled
> license-wise (e.g. 4DOS and its ties to FreeDOS)) that I don't know, don't
> have, am not willing to acquire, test and support

4DOS is freeware with sources (but needs old MSVC 1.52 to rebuild). It is definitely not tied to FreeDOS only. Rex Conn confirmed as much (see the Talk page on Wikipedia). That shouldn't be a problem at all. If you want to use and redistribute 4DOS, go ahead. I have it installed on my main desktop, but honestly I just always prefer FreeCOM out of simplicity.

I admit that FreeCOM isn't perfect, nor totally easy to rebuild (TC++ 1.01 only; Bart's OW port was incomplete and unstable), but at least (in theory) you could tweak and redistribute it to your heart's content. I would honestly probably suggest you improve that if you can't live with unmodified DOS shells.

> I see no point making things more complex than truly necessary, given the
> expected frequency of use and usage scenarios themselves and that the whole
> exercise is meant to be for fun in the first place.

Then it's simple: "Do nothing."

> You may lament about certain limitations and incompatibilities and so may
> I, but realistically there aren't that many options:

I think you misunderstood MarcoV. He isn't interested, just offering some (very) light advice.

alexfru(R)

USA,
18.09.2014, 15:41

@ Rugxulo
 

C's system() & COMMAND.COM

> > I may (I probably should) document my implementation of system(), but
> other
> > than that I don't think I care enough about the specific combination of
> > these:
> > - ancient non-standard extensions to the ancient OS (TSRs, shells
> replacing
> > COMMAND.COM and the like, especially those additionally crippled
> > license-wise (e.g. 4DOS and its ties to FreeDOS)) that I don't know,
> don't
> > have, am not willing to acquire, test and support
>
> 4DOS is freeware with sources (but needs old MSVC 1.52 to rebuild). It is
> definitely not tied to FreeDOS only. Rex Conn confirmed as much (see the
> Talk page on Wikipedia).
> That shouldn't be a problem at all. If you want to use and redistribute
> 4DOS, go ahead. I have it installed on my main desktop, but honestly I just
> always prefer FreeCOM out of simplicity.

http://www.4dos.info/sources.htm says at the bottom below that same text:

"These contradictions should be cleared, because they prevent e.g. making 4DOS a Sourceforge project."

If I were a lawyer or sought to extract profit from 4DOS, it would be a big red flag for me. IMO, if anyone cares, the license should be changed to remove said contradictions.

> I admit that FreeCOM isn't perfect, nor totally easy to rebuild (TC++ 1.01
> only; Bart's OW port was incomplete and unstable), but at least (in theory)
> you could tweak and redistribute it to your heart's content. I would
> honestly probably suggest you improve that if you can't live with
> unmodified DOS shells.

Sorry, improves who, improves what?

> > I see no point making things more complex than truly necessary, given
> the
> > expected frequency of use and usage scenarios themselves and that the
> whole
> > exercise is meant to be for fun in the first place.
>
> Then it's simple: "Do nothing."

I do just a little bit more than nothing, but that's the idea. :)

> > You may lament about certain limitations and incompatibilities and so
> may
> > I, but realistically there aren't that many options:
>
> I think you misunderstood MarcoV. He isn't interested, just offering some
> (very) light advice.

The range of possible problems has been duly registered in my mind. :)

Rugxulo(R)

Homepage

Usono,
01.11.2014, 23:48

@ alexfru
 

C's system() & COMMAND.COM

> http://www.4dos.info/sources.htm says at the bottom below that same text:
>
> "These contradictions should be cleared, because they prevent e.g. making
> 4DOS a Sourceforge project."
>
> If I were a lawyer or sought to extract profit from 4DOS, it would be a big
> red flag for me. IMO, if anyone cares, the license should be changed to
> remove said contradictions.

I'm very pessimistic about re-licensing things, but it does happen sometimes (see Moria).

The only one who can change the license is the current copyright holder, which AFAIK is Rex Conn (or maybe someone similar with legal authority from JP Software). I don't know his current email address offhand, so you may just have to directly contact them at http://jpsoft.com/company/contact-jp-software.html .

4DOS7501.ZIP's README.TXT is a completely different to 4DOS800.ZIP's LICENSE.TXT . The latter doesn't mention FreeDOS nor Rex Conn directly at all anymore. AFAIK, only the copyright holder can complain or clarify such a license (unless you consult a lawyer).

P.S. Keep in mind that you still need "non-free tools" just to build it. And if free/libre Linux users refuse to use even OpenWatcom (OSI), they're probably not going to touch old MSVC 1.52 with a ten foot pole. I doubt it's easy to port. I do think improving FreeCOM (far from perfect) is a better goal, at least in theory. No, I don't actually expect you to do anything here, just weakly trying to clarify in what little way I can (though I'm no lawyer).

Rugxulo(R)

Homepage

Usono,
02.11.2014, 00:29

@ Rugxulo
 

C's system() & COMMAND.COM

> > http://www.4dos.info/sources.htm says at the bottom below that same
> text:
> >
> > "These contradictions should be cleared, because they prevent e.g.
> making
> > 4DOS a Sourceforge project."
> >
> > If I were a lawyer or sought to extract profit from 4DOS, it would be a
> big
> > red flag for me. IMO, if anyone cares, the license should be changed to
> > remove said contradictions.

I forgot to mention. Don't quote me, I'm not any authority on the matter, but I think the original intention was to keep 4DOS strictly to DOS (and not Windows, e.g. NT, where 4NT was/is still commercially sold). I even vaguely remember hearing that "4DOS might be open sourced once it diverges enough from 4OS2" or such. So I think the intent was to not directly compete against existing products, not so much the intent to arbitrarily prevent use on various DOS flavors. But you'll have to ask the copyright holder for further clarity.

marcov(R)

18.09.2014, 16:10

@ Rugxulo
 

C's system() & COMMAND.COM

> I think you misunderstood MarcoV. He isn't interested, just offering some
> (very) light advice.

Correct. I care about neither C (big, medium or small) nor POSIX (on Dos).

I'm merely interested from a general crafting runtime libraries philosophy, and having dealt with posix emulation being forced on non-posix systems (and the arguments pro and con) before.

marcov(R)

18.09.2014, 16:07

@ alexfru
 

C's system() & COMMAND.COM

(big laments snipped)

> Isn't it how it works with many hobby projects?

Sure, but on the other hand you go the extra mile by adding posix compatibility to some C function.

Anyway, I hate "smart" systems that I can't bypass in case of trouble.

Rugxulo(R)

Homepage

Usono,
18.09.2014, 07:27

@ bretjohn
 

C's system() & COMMAND.COM

> What your program should do is the same thing that would happen if the user
> simply typed the same thing at the command-line.

"INT 2E - DOS 2+ - PASS COMMAND TO COMMAND INTERPRETER FOR EXECUTION"

http://www.delorie.com/djgpp/doc/rbinter/id/64/42.html

"COMMAND.COM processes the string as if typed from the keyboard"

bretjohn(R)

Homepage E-mail

Rio Rancho, NM,
18.09.2014, 18:14

@ Rugxulo
 

C's system() & COMMAND.COM

Unfortunately, INT 2Eh has this problem (quoting from the link provided): "results are unpredictable if invoked by a program run from a batch file because this call is not reentrant and COMMAND.COM uses the same internal variables when processing a batch file".

I really don't think there's a way to do what you're trying to do and have it return consistent results. E.g., I'm not sure if/how ErrorLevels are even returned by internal commands (or even if internal commands terminate with an INT 20h or INT 21.4C). I'm not sure exactly how batch files terminate, either, but what your system() call should return is the ErrorLevel of the batch file itself (which doesn't really exist AFAIK), and not just the ErrorLevel of the last command the batch file issued. And, if you do things in two different ways (invoking %COMSPEC% only if it doesn't have an explicit COM or EXE extension), then you will be able to return a valid ErrorLevel in some cases (COM or EXE) and not in others (every other case). As the link I provided earlier indicates, even if an explicit COM or EXE extension is provided, but you are using an early DOS version (earlier than v4), you have to ignore the extension if you want your program to do the same thing DOS would do.

The idea of two different calls (one that invokes %COMSPEC% and can't return valid ErrorLevels, and one that doesn't invoke %COMSPEC% but can return valid ErrorLevels) may be a valid approach that you can actually implement successfully and consistently. The "generic" system() call as defined in the C standard would seem to be the one that DOES invoke %COMSPEC%.

Rugxulo(R)

Homepage

Usono,
01.11.2014, 23:32

@ bretjohn
 

C's system() & COMMAND.COM

> Unfortunately, INT 2Eh has this problem (quoting from the link provided):
> "results are unpredictable if invoked by a program run from a batch file
> because this call is not reentrant and COMMAND.COM uses the same internal
> variables when processing a batch file".

Yes, I know, but I still thought it was worth mentioning, at least for completeness. Besides, obviously there are many DOSes (not just from MS) and many shells, so they can't all have the same limitations (e.g. see PATH Not Limited to 128 Characters).

> I really don't think there's a way to do what you're trying to do and have
> it return consistent results. E.g., I'm not sure if/how ErrorLevels are
> even returned by internal commands (or even if internal commands terminate
> with an INT 20h or INT 21.4C).

To quote the current Regina Rexx website (even though he doesn't support the DOS port anymore):

"Regina and Win95/98/Me

Due to a bug in the Windows 9x and Me command processor; COMMAND.COM, all calls to operating system commands from within Regina will ALWAYS return a zero return code. This is because COMMAND.COM always returns a zero return code. If you really need to be able to detect non-zero return codes from operating system commands, I recommend you get JP Software's 4DOS or 4NT."

> I'm not sure exactly how batch files
> terminate, either, but what your system() call should return is the
> ErrorLevel of the batch file itself (which doesn't really exist AFAIK), and
> not just the ErrorLevel of the last command the batch file issued.

Some shells (e.g. DR-DOS 7.03) let you "EXIT" from a .BAT with an errorlevel. And while I don't think FreeDOS' FreeCOM supports that, it does have an unusual feature where errorlevel can be treated like an environment variable (instead of forcing a long descending cascade of "if errorlevel" statements).

Obviously the problem here is that no shell properly runs on all these variants. So you'd have to port and improve one (e.g. FreeCOM, which is GPL) yourself if it's important enough to you.

alexfru(R)

USA,
13.09.2014, 01:00

@ tom
 

C's system() & COMMAND.COM

> if you want to be compatible to Borland or Microsoft, system("command") is
> equivalent to %COMSPEC%/c command, and there is no errorlevel returned
> from the executed command available.

Some compilers' DOS-specific implementation system() goes a bit further and tries to make sense of the command by checking the extension (.COM, .EXE, etc), if any, and checking the command against a [naturally never complete and accurate] list of internal commands of COMMAND.COM. Basically, if it's a .COM/.EXE, "COMMAND.COM /C" is avoided and the program is executed directly, which lets one get its exit code instead of 0 from COMMAND.COM. That's what I'm doing now as well.

> that's the way it is (and saves you a lot of work ;)

It doesn't save my anything if I care about the outcome of the function call.

Alex

Back to index page
Thread view  Board view
15115 Postings in 1359 Threads, 249 registered users, 17 users online (0 registered, 17 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum