Discussion:
Missing argv[0]?
(too old to reply)
Nick
2023-12-20 15:10:49 UTC
Permalink
I've been playing around with Aztec-C 1.06D on the RunCPM emulator and
I've been unable to get the programs to print argv[0] (the name of the
calling program). I eventually found in the Aztec-C manual an
explanation that says this is a null pointer in CP/M.

Is this the same for all CP/M versions, was it enhanced in any of the
other CCPs?
David Schultz
2023-12-20 16:52:54 UTC
Permalink
Post by Nick
I've been playing around with Aztec-C 1.06D on the RunCPM emulator and
I've been unable to get the programs to print argv[0] (the name of the
calling program). I eventually found in the Aztec-C manual an
explanation that says this is a null pointer in CP/M.
Is this the same for all CP/M versions, was it enhanced in any of the
other CCPs?
CP/M-68K gives you a pointer to "C Runtime". That might be true but I
can't recall ever checking.

The problem stems from the BDOS copying the command tail to the default
DMA buffer as part of its setup before starting the program. That does
not include the program name so it isn't available to the C runtime code
that sets up the argv array.
--
http://davesrocketworks.com
David Schultz
Douglas Miller
2023-12-20 18:16:06 UTC
Permalink
Technically, it is the CCP in CP/M-80 that copies the command tail to the default dma buffer. You didn't specify which CP/M you're talking about. CP/M Plus (3) (CCP) does provide the command name, but I'm not aware of any C compilers/runtimes that took advantage of that. So, in the 8-bit CP/M world you likely won't have argv[0].
Nick
2023-12-21 11:08:31 UTC
Permalink
Post by David Schultz
Post by Nick
I've been playing around with Aztec-C 1.06D on the RunCPM emulator and
I've been unable to get the programs to print argv[0] (the name of the
calling program). I eventually found in the Aztec-C manual an
explanation that says this is a null pointer in CP/M.
Is this the same for all CP/M versions, was it enhanced in any of the
other CCPs?
CP/M-68K gives you a pointer to "C Runtime". That might be true but I
can't recall ever checking.
The problem stems from the BDOS copying the command tail to the default
DMA buffer as part of its setup before starting the program. That does
not include the program name so it isn't available to the C runtime code
that sets up the argv array.
OK I've had the chance to test a bit further on CP/M 2.2 and CP/M-86
with the same results so I'll find a workaround. I was playing with some
old code for Motorola 6800 series assemblers and found it works with DOS
but not under various CP/M versions. Plus it's been an interesting
learning exercise as I've never been much of a C programmer.
Mark Ogden
2023-12-22 09:56:59 UTC
Permalink
Post by Nick
Post by David Schultz
Post by Nick
I've been playing around with Aztec-C 1.06D on the RunCPM emulator and
I've been unable to get the programs to print argv[0] (the name of the
calling program). I eventually found in the Aztec-C manual an
explanation that says this is a null pointer in CP/M.
Is this the same for all CP/M versions, was it enhanced in any of the
other CCPs?
CP/M-68K gives you a pointer to "C Runtime". That might be true but I
can't recall ever checking.
The problem stems from the BDOS copying the command tail to the default
DMA buffer as part of its setup before starting the program. That does
not include the program name so it isn't available to the C runtime code
that sets up the argv array.
OK I've had the chance to test a bit further on CP/M 2.2 and CP/M-86
with the same results so I'll find a workaround. I was playing with some
old code for Motorola 6800 series assemblers and found it works with DOS
but not under various CP/M versions. Plus it's been an interesting
learning exercise as I've never been much of a C programmer.
The historic technique to provide argv[0] or equivalent, was to code it in the source code.
Whitesmiths compilers for example used _pname to store the program name, and the usage function would show this
Hi-Tech uses the prompt name passed into _getargs. By default it defines nularg i.e. "". It could easily be changed to use a user defined string similar to Whitesmiths approach
Mark
Nick
2024-01-20 15:46:19 UTC
Permalink
Post by Mark Ogden
Post by Nick
Post by David Schultz
Post by Nick
I've been playing around with Aztec-C 1.06D on the RunCPM emulator and
I've been unable to get the programs to print argv[0] (the name of the
calling program). I eventually found in the Aztec-C manual an
explanation that says this is a null pointer in CP/M.
Is this the same for all CP/M versions, was it enhanced in any of the
other CCPs?
CP/M-68K gives you a pointer to "C Runtime". That might be true but I
can't recall ever checking.
The problem stems from the BDOS copying the command tail to the default
DMA buffer as part of its setup before starting the program. That does
not include the program name so it isn't available to the C runtime code
that sets up the argv array.
OK I've had the chance to test a bit further on CP/M 2.2 and CP/M-86
with the same results so I'll find a workaround. I was playing with some
old code for Motorola 6800 series assemblers and found it works with DOS
but not under various CP/M versions. Plus it's been an interesting
learning exercise as I've never been much of a C programmer.
The historic technique to provide argv[0] or equivalent, was to code it in the source code.
Whitesmiths compilers for example used _pname to store the program name, and the usage function would show this
Hi-Tech uses the prompt name passed into _getargs. By default it defines nularg i.e. "". It could easily be changed to use a user defined string similar to Whitesmiths approach
Mark
Thanks.
I've now had a chance to test a later MS-DOS version 4.10D of Aztec C I
found on Bitsavers in the pdf/manx directory. Interestingly, it doesn't
print argv[0] on that OS so maybe it's a Manx thing as well as CP/M.
Mark Ogden
2024-01-20 17:23:55 UTC
Permalink
Post by Nick
Post by Mark Ogden
Post by Nick
Post by David Schultz
Post by Nick
I've been playing around with Aztec-C 1.06D on the RunCPM emulator and
I've been unable to get the programs to print argv[0] (the name of the
calling program). I eventually found in the Aztec-C manual an
explanation that says this is a null pointer in CP/M.
Is this the same for all CP/M versions, was it enhanced in any of the
other CCPs?
CP/M-68K gives you a pointer to "C Runtime". That might be true but I
can't recall ever checking.
The problem stems from the BDOS copying the command tail to the default
DMA buffer as part of its setup before starting the program. That does
not include the program name so it isn't available to the C runtime code
that sets up the argv array.
OK I've had the chance to test a bit further on CP/M 2.2 and CP/M-86
with the same results so I'll find a workaround. I was playing with some
old code for Motorola 6800 series assemblers and found it works with DOS
but not under various CP/M versions. Plus it's been an interesting
learning exercise as I've never been much of a C programmer.
The historic technique to provide argv[0] or equivalent, was to code it in the source code.
Whitesmiths compilers for example used _pname to store the program name, and the usage function would show this
Hi-Tech uses the prompt name passed into _getargs. By default it defines nularg i.e. "". It could easily be changed to use a user defined string similar to Whitesmiths approach
Mark
Thanks.
I've now had a chance to test a later MS-DOS version 4.10D of Aztec C I
found on Bitsavers in the pdf/manx directory. Interestingly, it doesn't
print argv[0] on that OS so maybe it's a Manx thing as well as CP/M.
NIck
CP/M puts it command line arguments in a buffer starting at 80h, prefilling fcbs at 5ch and 6ch with parsed file names for the first 2 arguments. Unfortunately, it doesn't save the invoking command in this argument list.
A C implementation would usually covert this command line into standard argc,argv format. Any argv[0] would have to be set to a fixed value during this conversion and is usually the null string. By modifying the conversion routines to put your own string would at least give a more reasonable value, however renaming your application would not change this fixed name.

By way of an example, the hitech C compiler startup code contains a data label nularg which is a null string. This is what initialises argv[0], replacing this, possibly by moving to your own code, would allow argv[0] to be set.
Alternatively, to make your code portable to non CP/M systems testing for a null or null string argv[0] would allow you to replace argv[0] with your own string.

In principle you could probe the ccp in memory before it is overwritten, for the invoking name. However, this is likely to require CP/M version specific code. For example CP/M 2.2 uses a buffer at ccpbase + 8 for processing, so the name may be there.
Be aware some applications like a debugger, overwrite the ccp when they load.

Mark
dxf
2024-01-21 04:45:08 UTC
Permalink
...
I've now had a chance to test a later MS-DOS version 4.10D of Aztec C I found on Bitsavers in the pdf/manx directory. Interestingly, it doesn't print argv[0] on that OS so maybe it's a Manx thing as well as CP/M.
Suggesting it's relatively unimportant? Mostly it's only the command tail that's
wanted. Similarly CP/M's pre-parsing to fcb's is neat but as most compilers would
include a [better?] fcb parser, it's kind of redundant.

Loading...