[Info-vax] Local Versus Global Command Options

Arne Vajhøj arne at vajhoej.dk
Sat Feb 15 20:21:12 EST 2025


On 2/15/2025 4:32 PM, Lawrence D'Oliveiro wrote:
> On Sat, 15 Feb 2025 12:22:59 -0700, Mark Berryman wrote:
>> So, IMHO, DCL is superior in this regard.
> 
> Unfortunately, no. The fundamental problem with DEC OSes (and this
> includes Windows) is that the command line is passed to the program as a
> single string buffer. On *nix systems, it is passed as an array of
> strings.
> 
> You should be familiar with the well-known problem of one program invoking
> another with a command that might include characters with special meanings
> to a shell. On a *nix system, there is a simple way to avoid those special
> meanings: the first program invokes the second program directly, without
> going through a shell.
> 
> Nowadays, there is even a simple library call to do this
> <https://manpages.debian.org/posix_spawn(3)>.
> 
> This is not so easy to do with a DEC-style command line.

How do you get those "characters with special meanings
to a shell" interpreted instead of passed on VMS?

All my trivial attempts failed:

$ type self.pas
[inherit('sys$library:pascal$lib_routines', 'sys$library:starlet')]
program self(input,output);

[external]
function decc$system(%immed cmd : c_str_t) : integer; external;

type
    pstr = varying [255] of char;

var
    cmdlin : pstr;

begin
    lib$get_foreign(cmdlin.body, , cmdlin.length);
    if cmdlin <> '' then begin
       writeln(cmdlin);
    end else begin
       decc$system(malloc_c_str('mcr sys$disk:[]self ''a'' ''b'' ''c'''));
       lib$spawn('mcr sys$disk:[]self ''a'' ''b'' ''c''');
       lib$do_command('mcr sys$disk:[]self ''a'' ''b'' ''c''');
    end;
end.
$ pas self
$ link self
$ a = 1
$ b = 2
$ c = 3
$ mcr sys$disk:[]self 'a' 'b' 'c'
1 2 3
$ r self
'a' 'b' 'c'
'a' 'b' 'c'
'a' 'b' 'c'

$ type self2.c
#include <stdio.h>
#include <stdlib.h>

#include <descrip.h>
#include <lib$routines.h>

int main(int argc, char *argv[])
{
     $DESCRIPTOR(cmddesc, "mcr sys$disk:[]self2 'a' 'b' 'c'");
     if(argc > 1)
     {
         for(int i = 1; i < argc; i++) printf(" %s", argv[i]);
         printf("\n");
     }
     else
     {
         system("mcr sys$disk:[]self2 'a' 'b' 'c'");
         lib$spawn(&cmddesc);
         lib$do_command(&cmddesc);
     }
     return 0;
}

$ cc self2
$ link self2
$ a = 1
$ b = 2
$ c = 3
$ mcr sys$disk:[]self 'a' 'b' 'c'
  1 2 3
$ r self2
  'a' 'b' 'c'
  'a' 'b' 'c'
  'a' 'b' 'c'

Arne




More information about the Info-vax mailing list