• Fun trick

    From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Tue Jan 7 20:58:29 2025
    During some troubleshooting over at VSI forum hb told me that
    running a shareable image will execute LIB$INITIALIZE
    functions.

    That made me write this:

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

    [global]
    procedure check;

    var
    imgnam : varying [1024] of char;

    begin
    lib$getjpi(item_code := jpi$_imagname, resultant_string :=
    imgnam.body, resultant_length := imgnam.length);
    if index(imgnam, ']libshr.EXE') > 0 then begin
    writeln('This is a shareable image to link against not run');
    $exit(ss$_normal);
    end;
    end;

    [global]
    procedure say;

    begin
    writeln('Hi');
    end;

    end.
    $ type prg.pas
    program prg(input,output);

    [external]
    procedure say; external;

    begin
    say;
    end.
    $ type trick.mar
    .title trick
    .extrn lib$initialize
    .psect lib$initialize long,nopic,con,gbl,noshr,noexe,nowrt
    .address check
    .end
    $ macro trick
    $ pas lib
    $ link/share=libshr lib + trick + sys$input/opt
    SYMBOL_VECTOR=(say=PROCEDURE)
    $
    $ define/nolog libshr sys$disk:[]libshr
    $ pas prg
    $ link prg + sys$input/opt
    libshr/share
    $
    $ run prg
    Hi
    $ run libshr
    This is a shareable image to link against not run

    :-)

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Jan 8 02:33:07 2025
    On Tue, 7 Jan 2025 20:58:29 -0500, Arne Vajhøj wrote:

    During some troubleshooting over at VSI forum hb told me that running a shareable image will execute LIB$INITIALIZE functions.

    Wonder why shareable images had that .EXE file extension, eh ...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From John Reagan@21:1/5 to All on Wed Jan 8 12:37:44 2025
    On 1/7/2025 8:58 PM, Arne Vajhøj wrote:
    During some troubleshooting over at VSI forum hb told me that
    running a shareable image will execute LIB$INITIALIZE
    functions.

    That made me write this:

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

    [global]
    procedure check;

    var
       imgnam : varying [1024] of char;

    begin
       lib$getjpi(item_code := jpi$_imagname, resultant_string :=
    imgnam.body, resultant_length := imgnam.length);
       if index(imgnam, ']libshr.EXE') > 0 then begin
          writeln('This is a shareable image to link against not run');
          $exit(ss$_normal);
       end;
    end;

    [global]
    procedure say;

    begin
       writeln('Hi');
    end;

    end.
    $ type prg.pas
    program prg(input,output);

    [external]
    procedure say; external;

    begin
       say;
    end.
    $ type trick.mar
            .title  trick
            .extrn  lib$initialize
            .psect  lib$initialize long,nopic,con,gbl,noshr,noexe,nowrt
            .address check
            .end
    $ macro trick
    $ pas lib
    $ link/share=libshr lib + trick + sys$input/opt
    SYMBOL_VECTOR=(say=PROCEDURE)
    $
    $ define/nolog libshr sys$disk:[]libshr
    $ pas prg
    $ link prg + sys$input/opt
    libshr/share
    $
    $ run prg
    Hi
    $ run libshr
    This is a shareable image to link against not run

    :-)

    Arne

    Pascal has an [INITIALIZE] attribute that you can put on the PROCEDURE
    CHECK and the compiler should do the contribution to the LIB$INITIALIZE
    PSECT.

    And you should include LIB$INITIALIZE (the code module, not the data
    PSECT) from STARLET when linking. The x86 linker will do that for you,
    but the Alpha and Itanium linkers do not.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to John Reagan on Wed Jan 8 14:36:13 2025
    On 1/8/2025 12:37 PM, John Reagan wrote:
    On 1/7/2025 8:58 PM, Arne Vajhøj wrote:
    During some troubleshooting over at VSI forum hb told me that
    running a shareable image will execute LIB$INITIALIZE
    functions.

    That made me write this:
    ...
    Pascal has an [INITIALIZE] attribute that you can put on the PROCEDURE
    CHECK and the compiler should do the contribution to the LIB$INITIALIZE PSECT.

    And you should include LIB$INITIALIZE (the code module, not the data
    PSECT) from STARLET when linking.  The x86 linker will do that for you,
    but the Alpha and Itanium linkers do not.

    Zweite Sehr Verbesserte Ausgabe:

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

    [initialize]
    procedure check;

    var
    imgnam : varying [1024] of char;

    begin
    lib$getjpi(item_code := jpi$_imagname, resultant_string :=
    imgnam.body, resultant_length := imgnam.length);
    if index(imgnam, ']libshr.EXE') > 0 then begin
    writeln('This is a shareable image to link against not run');
    $exit(ss$_normal);
    end;
    end;

    [global]
    procedure say;

    begin
    writeln('Hi');
    end;

    end.
    $ type prg.pas
    program prg(input,output);

    [external]
    procedure say; external;

    begin
    say;
    end.
    $ pas lib
    $ link/share=libshr lib + sys$library:starlet/lib/incl=lib$initialize + sys$input/opt
    SYMBOL_VECTOR=(say=PROCEDURE)
    $
    $ define/nolog libshr sys$disk:[]libshr
    $ pas prg
    $ link prg + sys$input/opt
    libshr/share
    $
    $ run prg
    Hi
    $ run libshr
    This is a shareable image to link against not run

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From John Reagan@21:1/5 to All on Wed Jan 8 15:42:07 2025
    On 1/8/2025 2:36 PM, Arne Vajhøj wrote:
    On 1/8/2025 12:37 PM, John Reagan wrote:
    On 1/7/2025 8:58 PM, Arne Vajhøj wrote:
    During some troubleshooting over at VSI forum hb told me that
    running a shareable image will execute LIB$INITIALIZE
    functions.

    That made me write this:
    ...
    Pascal has an [INITIALIZE] attribute that you can put on the PROCEDURE
    CHECK and the compiler should do the contribution to the
    LIB$INITIALIZE PSECT.

    And you should include LIB$INITIALIZE (the code module, not the data
    PSECT) from STARLET when linking.  The x86 linker will do that for
    you, but the Alpha and Itanium linkers do not.

    Zweite Sehr Verbesserte Ausgabe:

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

    [initialize]
    procedure check;

    var
       imgnam : varying [1024] of char;

    begin
       lib$getjpi(item_code := jpi$_imagname, resultant_string :=
    imgnam.body, resultant_length := imgnam.length);
       if index(imgnam, ']libshr.EXE') > 0 then begin
          writeln('This is a shareable image to link against not run');
          $exit(ss$_normal);
       end;
    end;

    [global]
    procedure say;

    begin
       writeln('Hi');
    end;

    end.
    $ type prg.pas
    program prg(input,output);

    [external]
    procedure say; external;

    begin
       say;
    end.
    $ pas lib
    $ link/share=libshr lib + sys$library:starlet/lib/incl=lib$initialize + sys$input/opt
    SYMBOL_VECTOR=(say=PROCEDURE)
    $
    $ define/nolog libshr sys$disk:[]libshr
    $ pas prg
    $ link prg + sys$input/opt
    libshr/share
    $
    $ run prg
    Hi
    $ run libshr
    This is a shareable image to link against not run

    Arne

    And the compiler also supports the Extended Pascal TO BEGIN DO and TO
    END DO statements. TO BEGIN DO is just the same as [INITIALIZE] but
    allows any statement. TO END DO is an exit handler (registered with an initialization routine).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed Jan 8 16:37:21 2025
    On 1/8/2025 4:32 PM, Arne Vajhøj wrote:
    On 1/8/2025 3:42 PM, John Reagan wrote:
    And the compiler also supports the Extended Pascal TO BEGIN DO and TO
    END DO statements.  TO BEGIN DO is just the same as [INITIALIZE] but
    allows any statement.  TO END DO is an exit handler (registered with
    an initialization routine).

    $ type prg.pas
    program prg(input,output);

    [external]
    procedure say; external;

    begin
        writeln('2');
        say;
        writeln('4');
    end.
    $ type lib.pas
    module lib(input, output);

    [global]
    procedure say;

    begin
        writeln('3');
    end;

    to begin do writeln('1');
    to end do writeln('5');

    end.
    $ pas lib
    $ link/share=libshr lib + sys$library:starlet/lib/incl=lib$initialize + sys$input/opt
    SYMBOL_VECTOR=(say=PROCEDURE)
    $
    $ define/nolog libshr sys$disk:[]libshr
    $ pas prg
    $ link prg + sys$input/opt
    libshr/share
    $
    $ run prg
    1
    2
    3
    4
    5

    Or ditching the shareable image that are no longer relevant:

    $ type prg2.pas
    [inherit('lib2')]
    program prg2(input,output);

    begin
    writeln('2');
    say;
    writeln('4');
    end.
    $ type lib2.pas
    module lib2(input, output);

    procedure say;

    begin
    writeln('3');
    end;

    to begin do writeln('1');
    to end do writeln('5');

    end.
    $ pas/env lib2
    $ pas prg2
    $ link prg2 + lib2
    $ run prg2
    1
    2
    3
    4
    5

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to John Reagan on Wed Jan 8 16:32:41 2025
    On 1/8/2025 3:42 PM, John Reagan wrote:
    And the compiler also supports the Extended Pascal TO BEGIN DO and TO
    END DO statements.  TO BEGIN DO is just the same as [INITIALIZE] but
    allows any statement.  TO END DO is an exit handler (registered with an initialization routine).

    $ type prg.pas
    program prg(input,output);

    [external]
    procedure say; external;

    begin
    writeln('2');
    say;
    writeln('4');
    end.
    $ type lib.pas
    module lib(input, output);

    [global]
    procedure say;

    begin
    writeln('3');
    end;

    to begin do writeln('1');
    to end do writeln('5');

    end.
    $ pas lib
    $ link/share=libshr lib + sys$library:starlet/lib/incl=lib$initialize + sys$input/opt
    SYMBOL_VECTOR=(say=PROCEDURE)
    $
    $ define/nolog libshr sys$disk:[]libshr
    $ pas prg
    $ link prg + sys$input/opt
    libshr/share
    $
    $ run prg
    1
    2
    3
    4
    5

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From hb0815@21:1/5 to All on Wed Jan 8 23:11:46 2025
    On 1/8/25 02:58, Arne Vajhøj wrote:
    During some troubleshooting over at VSI forum hb told me that
    running a shareable image will execute LIB$INITIALIZE
    functions.

    That made me write this:

    Yeah, but ... You do not need init code for this.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to John Reagan on Wed Jan 8 16:38:51 2025
    On 1/8/2025 3:42 PM, John Reagan wrote:
    And the compiler also supports the Extended Pascal TO BEGIN DO and TO
    END DO statements.  TO BEGIN DO is just the same as [INITIALIZE] but
    allows any statement.  TO END DO is an exit handler (registered with an initialization routine).

    The compiler tell me that those two are only valid in modules
    not in programs.

    They are probably most useful for modules, but why not allow
    them for programs?

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From hb0815@21:1/5 to All on Wed Jan 8 23:31:03 2025
    On 1/8/25 23:20, Arne Vajhøj wrote:
    On 1/8/2025 5:11 PM, hb0815 wrote:
    On 1/8/25 02:58, Arne Vajhøj wrote:
    During some troubleshooting over at VSI forum hb told me that
    running a shareable image will execute LIB$INITIALIZE
    functions.

    That made me write this:

    Yeah, but ... You do not need init code for this.

    Oh.

    Can one get a transfer address into a shareable image?

    Arne

    $ sh sys/noproc/full
    OpenVMS V8.4-2L2 on node EISNER 8-JAN-2025 17:29:41.07 Uptime 3
    22:58:56
    AlphaServer ES40
    $
    $ ty s.c
    #include <stdio.h>
    static int firstFunctionInThisModuleBecomesTheEntryPoint () {
    printf ("It's the shareable, stupid!\n");
    return 1;
    }
    int foo () {
    printf ("This is %s\n", __func__);
    return 1;
    }
    $ cc s/stand=rel
    $ link/share s,tt:/opt ! symbol_v=(foo=proc)
    symbol_v=(foo=proc)
    Exit
    $ r s
    It's the shareable, stupid!
    $

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed Jan 8 17:20:50 2025
    On 1/8/2025 5:11 PM, hb0815 wrote:
    On 1/8/25 02:58, Arne Vajhøj wrote:
    During some troubleshooting over at VSI forum hb told me that
    running a shareable image will execute LIB$INITIALIZE
    functions.

    That made me write this:

    Yeah, but ... You do not need init code for this.

    Oh.

    Can one get a transfer address into a shareable image?

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed Jan 8 20:00:59 2025
    On 1/8/2025 5:31 PM, hb0815 wrote:
    On 1/8/25 23:20, Arne Vajhøj wrote:
    On 1/8/2025 5:11 PM, hb0815 wrote:
    On 1/8/25 02:58, Arne Vajhøj wrote:
    During some troubleshooting over at VSI forum hb told me that
    running a shareable image will execute LIB$INITIALIZE
    functions.

    That made me write this:

    Yeah, but ... You do not need init code for this.

    Oh.

    Can one get a transfer address into a shareable image?

    $ ty s.c
    #include <stdio.h>
    static int firstFunctionInThisModuleBecomesTheEntryPoint () {
      printf ("It's the shareable, stupid!\n");
      return 1;
    }
    int foo () {
      printf ("This is %s\n", __func__);
      return 1;
    }
    $ cc s/stand=rel
    $ link/share s,tt:/opt ! symbol_v=(foo=proc)
    symbol_v=(foo=proc)
     Exit
    $ r s
    It's the shareable, stupid!

    Hmmm.

    It works in C, but it does not seem to work in
    any other language (tested with Pascal and Fortran).

    $ type prg.c
    #include <stdio.h>

    extern void say();

    int main(int argc, char *argv[])
    {
    say();
    return 0;
    }

    $ type lib.c
    #include <stdio.h>

    int ooops()
    {
    printf("This is a shareable image to link against not run\n");
    return 1;
    }

    void say()
    {
    printf("Hi\n");
    }

    $ cc lib
    $ link/share=libshr lib + sys$input/opt
    symbol_vector=(say=procedure)
    $
    $ define/nolog libshr sys$disk:[]libshr
    $ cc prg
    $ link prg + sys$input/opt
    libshr/share
    $
    $ run prg
    Hi
    $ run libshr
    This is a shareable image to link against not run
    $ type prg.pas
    program prg(input,output);

    [external]
    procedure say; external;

    begin
    say;
    end.
    $ type lib.pas
    [inherit('sys$library:starlet')]
    module lib(input, output);

    [global]
    procedure ooops;

    begin
    writeln('This is a shareable image to link against not run');
    $exit(ss$_normal);
    end;

    [global]
    procedure say;

    begin
    writeln('Hi');
    end;

    end.
    $ pas lib
    $ link/share=libshr lib + sys$input/opt
    symbol_vector=(say=procedure)
    $
    $ define/nolog libshr sys$disk:[]libshr
    $ pas prg
    $ link prg + sys$input/opt
    libshr/share
    $
    $ run prg
    Hi
    $ run libshr
    %DCL-E-NOTFR, no transfer address
    $ type prg.for
    program prg
    call say
    end
    $ type lib.for
    subroutine ooops
    include '($ssdef)'
    write(*,*) 'This is a shareable image to link against not run'
    call sys$exit(ss$_normal)
    end
    c
    subroutine say
    write(*,*) 'Hi'
    end
    $ for lib
    $ link/share=libshr lib + sys$input/opt
    symbol_vector=(say=procedure)
    $
    $ define/nolog libshr sys$disk:[]libshr
    $ for prg
    $ link prg + sys$input/opt
    libshr/share
    $
    $ run prg
    Hi
    $ run libshr
    %DCL-E-NOTFR, no transfer address

    I assume the difference relates to user code main not being
    the real program entry.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From hb0815@21:1/5 to All on Thu Jan 9 14:01:51 2025
    On 1/9/25 02:00, Arne Vajhøj wrote:
    Hmmm.

    It works in C, but it does not seem to work in
    any other language (tested with Pascal and Fortran).
    ...
    I assume the difference relates to user code main not being
    the real program entry.

    So, make it a main entry.

    This is on Alpha. It should work on IA64 and x86. I don't have access to
    any of the latter systems. If this does not work on these systems, I
    know how to make it work, anyway.

    $ gdiff -ub lib.pas-orig lib.pas
    --- lib.pas-orig 2025-01-09 07:34:25 -0500
    +++ lib.pas 2025-01-09 07:37:14 -0500
    @@ -1,19 +1,11 @@
    -[inherit('sys$library:starlet')]
    -module lib(input, output);
    -
    -[global]
    -procedure ooops;
    -
    -begin
    - writeln('This is a shareable image to link against not run');
    - $exit(ss$_normal);
    -end;
    +program lib(input, output);

    [global]
    procedure say;
    -
    begin
    writeln('Hi');
    end;

    +begin
    + writeln('This is a shareable image to link against not run');
    end.
    $
    ...
    $ def/user libshr sys$disk:[]libshr.exe;
    $ r prg
    Hi
    $ r libshr
    This is a shareable image to link against not run
    $

    and

    $ gdiff -ub lib.for-orig lib.for
    --- lib.for-orig 2025-01-09 07:43:03 -0500
    +++ lib.for 2025-01-09 07:43:25 -0500
    @@ -1,7 +1,5 @@
    - subroutine ooops
    - include '($ssdef)'
    + program ooops
    write(*,*) 'This is a shareable image to link against not run'
    - call sys$exit(ss$_normal)
    end
    c
    subroutine say
    $
    ...
    $ de
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Mon Jan 13 13:40:46 2025
    On 1/9/2025 8:01 AM, hb0815 wrote:
    On 1/9/25 02:00, Arne Vajhøj wrote:
    Hmmm.

    It works in C, but it does not seem to work in
    any other language (tested with Pascal and Fortran).
    ...
    I assume the difference relates to user code main not being
    the real program entry.

    So, make it a main entry.

    This is on Alpha. It should work on IA64 and x86. I don't have access to
    any of the latter systems. If this does not work on these systems, I
    know how to make it work, anyway.

    $ gdiff -ub lib.pas-orig lib.pas

    $ gdiff -ub lib.for-orig lib.for

    For those that do not speak diffish:

    $ type prg.c
    #include <stdio.h>

    extern void say();

    int main(int argc, char *argv[])
    {
    say();
    return 0;
    }

    $ type lib.c
    #include <stdio.h>

    void say()
    {
    printf("Hi\n");
    }

    int main()
    {
    printf("This is a shareable image to link against not run\n");
    return 0;
    }

    $ cc lib
    $ link/share=libshr lib + sys$input/opt
    symbol_vector=(say=procedure)
    $
    $ define/nolog libshr sys$disk:[]libshr
    $ cc prg
    $ link prg + sys$input/opt
    libshr/share
    $
    $ run prg
    Hi
    $ run libshr
    This is a shareable image to link against not run
    $ type prg.pas
    program prg(input,output);

    [external]
    procedure say; external;

    begin
    say;
    end.
    $ type lib.pas
    program lib(input, output);

    [global]
    procedure say;

    begin
    writeln('Hi');
    end;

    begin
    writeln('This is a shareable image to link against not run');
    end.
    $ pas lib
    $ link/share=libshr lib + sys$input/opt
    symbol_vector=(say=procedure)
    $
    $ define/nolog libshr sys$disk:[]libshr
    $ pas prg
    $ link prg + sys$input/opt
    libshr/share
    $
    $ run prg
    Hi
    $ run libshr
    This is a shareable image to link against not run
    $ type prg.for
    program prg
    call say
    end
    $ type lib.for
    program lib
    write(*,*) 'This is a shareable image to link against not run'
    end
    c
    subroutine say
    write(*,*) 'Hi'
    end
    $ for lib
    $ link/share=libshr lib + sys$input/opt
    symbol_vector=(say=procedure)
    $
    $ define/nolog libshr sys$disk:[]libshr
    $ for prg
    $ link prg + sys$input/opt
    libshr/share
    $
    $ run prg
    Hi
    $ run libshr
    This is a shareable image to link against not run

    So I think the conclusion must be that one should
    not think the traditional grouping:
    * executable image
    * shareable image
    but instead:
    * image with transfer address
    * image with symbol vector
    * image with both transfer address and symbol vector

    :-)

    I believe that is rare for native code.

    But common for non-native code.

    $ type prg.py
    import lib

    if __name__ == '__main__':
    lib.say()

    $ type lib.py
    def say():
    print('Hi')

    if __name__ == '__main__':
    print('This is a library not a program')

    $ python prg.py
    Hi
    $ python lib.py
    This is a library not a program
    $ type Prg.java
    public class Prg {
    public static void main(String[] args) {
    Lib.say();
    }
    }
    $ type Lib.java
    public class Lib {
    public static void say() {
    System.out.println("Hi");
    }
    public static void main(String[] args) throws Exception {
    System.out.println("This is a library not a program");
    }
    }
    $ javac Prg.java Lib.java
    $ java Prg
    Hi
    $ java Lib
    This is a library not a program

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Mon Jan 13 13:45:50 2025
    On 1/9/2025 8:01 AM, hb0815 wrote:
    On 1/9/25 02:00, Arne Vajhøj wrote:
    Hmmm.

    It works in C, but it does not seem to work in
    any other language (tested with Pascal and Fortran).
    ...
    I assume the difference relates to user code main not being
    the real program entry.

    So, make it a main entry.

    This is on Alpha. It should work on IA64 and x86. I don't have access to
    any of the latter systems. If this does not work on these systems, I
    know how to make it work, anyway.

    $ gdiff -ub lib.pas-orig lib.pas

    $ gdiff -ub lib.for-orig lib.for

    Also, I should have mentioned ... Your shareable with printing a message
    from init code can not be used as a "normal" shareable image. The
    message will always be printed. That's probably not what you want.

    Init code of an image is always run. For a shareable image it is run at activation time, for a main image it is run at image startup time. For
    some reasons I distinguish these two phases although others prefer to
    say that "startup" is part of activation.

    My shareable image only prints its message if a user (accidently) runs
    it as main image.

    My Pascal code a few revisions back looked like:

    lib$getjpi(item_code := jpi$_imagname, resultant_string :=
    imgnam.body, resultant_length := imgnam.length);
    if index(imgnam, ']libshr.EXE') > 0 then begin
    writeln('This is a shareable image to link against not run');
    $exit(ss$_normal);
    end;

    Maybe not elegant, but it did check.

    All this works because VMS defines a weak transfer (or entry) address.
    The C compiler in absence of a "main" assigns this weak transfer to the
    first function seen in a source module. (I admit, I initially didn't
    test this with other compilers; obviously FORTRAN and PASCAL do not
    define this). The linker keeps track of the first weak transfer it
    encounters and uses it as image transfer, if there is no "strong"
    transfer, in C no "main". This makes the shareable image "runnable".

    There are probably a lot of shareable images written in C out
    there where the developer has no idea that they are runnable or
    what code will run.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Mon Jan 13 17:55:59 2025
    On 1/13/2025 5:18 PM, Lawrence D'Oliveiro wrote:
    On Mon, 13 Jan 2025 13:45:50 -0500, Arne Vajhøj wrote:
    There are probably a lot of shareable images written in C out there
    where the developer has no idea that they are runnable or what code will
    run.

    If it has no main(), then nothing will run.

    That is what the developer thinks.

    But it is not so.

    $ type lawrence.c
    #include <stdio.h>

    int foobar()
    {
    printf("Hi Lawrence\n");
    return 1;
    }
    $ cc lawrence
    $ link/share lawrence
    $ run lawrence
    Hi Lawrence

    No main() and it runs anyway.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Mon Jan 13 22:18:48 2025
    On Mon, 13 Jan 2025 13:45:50 -0500, Arne Vajhøj wrote:

    There are probably a lot of shareable images written in C out there
    where the developer has no idea that they are runnable or what code will
    run.

    If it has no main(), then nothing will run.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From John Reagan@21:1/5 to All on Mon Jan 13 21:08:11 2025
    On 1/8/2025 4:38 PM, Arne Vajhøj wrote:
    On 1/8/2025 3:42 PM, John Reagan wrote:
    And the compiler also supports the Extended Pascal TO BEGIN DO and TO
    END DO statements.  TO BEGIN DO is just the same as [INITIALIZE] but
    allows any statement.  TO END DO is an exit handler (registered with
    an initialization routine).

    The compiler tell me that those two are only valid in modules
    not in programs.

    They are probably most useful for modules, but why not allow
    them for programs?

    Arne

    Good question. Extended Pascal says only MODULEs so we just didn't
    think about allowing them in PROGRAMs even though we allow [INITIALIZE].

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From John Reagan@21:1/5 to All on Mon Jan 13 21:11:29 2025
    On 1/13/2025 5:55 PM, Arne Vajhøj wrote:
    On 1/13/2025 5:18 PM, Lawrence D'Oliveiro wrote:
    On Mon, 13 Jan 2025 13:45:50 -0500, Arne Vajhøj wrote:
    There are probably a lot of shareable images written in C out there
    where the developer has no idea that they are runnable or what code will >>> run.

    If it has no main(), then nothing will run.

    That is what the developer thinks.

    But it is not so.

    $ type lawrence.c
    #include <stdio.h>

    int foobar()
    {
        printf("Hi Lawrence\n");
        return 1;
    }
    $ cc lawrence
    $ link/share  lawrence
    $ run lawrence
    Hi Lawrence

    No main() and it runs anyway.

    Arne

    COBOL paragraphs behave like C. First routine/PARAGRAPH gets a WEAK
    transfer address. Linker finds the first one. Shuffle modules around
    and you'll get different transfer addresses. Pascal just creates a
    STRONG transfer address for a PROGRAM statement.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to John Reagan on Tue Jan 14 04:38:48 2025
    On Mon, 13 Jan 2025 21:08:11 -0500, John Reagan wrote:

    Extended Pascal says only MODULEs so we just didn't
    think about allowing them in PROGRAMs even though we allow [INITIALIZE].

    Not sure what the point would be in having them in PROGRAMs, anyway.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Tue Jan 14 04:39:19 2025
    On Mon, 13 Jan 2025 17:55:59 -0500, Arne Vajhøj wrote:

    On 1/13/2025 5:18 PM, Lawrence D'Oliveiro wrote:

    If it has no main(), then nothing will run.

    That is what the developer thinks.

    But it is not so.

    Try it on a proper POSIXish system.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to John Reagan on Tue Jan 14 11:06:23 2025
    On 1/13/2025 9:11 PM, John Reagan wrote:
    On 1/13/2025 5:55 PM, Arne Vajhøj wrote:
    On 1/13/2025 5:18 PM, Lawrence D'Oliveiro wrote:
    On Mon, 13 Jan 2025 13:45:50 -0500, Arne Vajhøj wrote:
    There are probably a lot of shareable images written in C out there
    where the developer has no idea that they are runnable or what code
    will
    run.

    If it has no main(), then nothing will run.

    That is what the developer thinks.

    But it is not so.

    $ type lawrence.c
    #include <stdio.h>

    int foobar()
    {
         printf("Hi Lawrence\n");
         return 1;
    }
    $ cc lawrence
    $ link/share  lawrence
    $ run lawrence
    Hi Lawrence

    No main() and it runs anyway.

    COBOL paragraphs behave like C.  First routine/PARAGRAPH gets a WEAK transfer address.  Linker finds the first one.

    I have many prejudices about COBOL developers.

    One of them is that they don't create shareable images.

    :-)

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Tue Jan 14 11:03:27 2025
    On 1/13/2025 11:38 PM, Lawrence D'Oliveiro wrote:
    On Mon, 13 Jan 2025 21:08:11 -0500, John Reagan wrote:
    ### They are probably most useful for modules, but why not allow
    ### them for programs?
    Extended Pascal says only MODULEs so we just didn't
    think about allowing them in PROGRAMs even though we allow [INITIALIZE].

    Not sure what the point would be in having them in PROGRAMs, anyway.

    Definitely most useful for modules. I was just wondering
    why not allow it in programs as well.

    It seems to have been explicit disallowed. The error message is:

    %PASCAL-E-TOPROGRAM, TO BEGIN/END DO not allowed in PROGRAM

    If one start to look for something useful then I would say that
    TO BEGIN is just code after PROGRAM BEGIN, but TO END is more
    than just code before PROGRAM END as it get triggered by other
    program exits as well.

    Demo:

    $ type m.pas
    module m(input,output);

    to begin do writeln('m to begin');
    to end do writeln('m to end');

    end.
    $ type p.pas
    [inherit('m', 'sys$library:starlet')]
    program p(input,output);

    [initialize]
    procedure init;

    begin
    writeln('init');
    end;

    procedure done;

    begin
    writeln('done');
    end;

    var
    ent : integer64;
    desblk : array [1..4] of integer;
    cond : integer;

    begin
    writeln('begin');
    desblk[1] := 0;
    desblk[2] := iaddress(done);
    desblk[3] := 0;
    desblk[4] := iaddress(cond);
    $dclexh(desblk);
    $get_entropy(ent, 8);
    if (ent mod 2) = 0 then $exit(SS$_NORMAL);
    $canexh(desblk);
    writeln('end');
    end.
    $ pas/env m
    $ pas p
    $ link p + m
    $ run p
    m to begin
    init
    begin
    end
    m to end
    $ run p
    m to begin
    init
    begin
    done
    m to end
    $ run p
    m to begin
    init
    begin
    end
    m to end
    $ run p
    m to begin
    init
    begin
    done
    m to end

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Tue Jan 14 11:41:21 2025
    On 1/14/2025 11:03 AM, Arne Vajhøj wrote:
       $get_entropy(ent, 8);

    That one is of course VMS x86-64 specific.

    More portable and less random:

    ent := 42;

    :-)

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From John Reagan@21:1/5 to All on Wed Jan 15 09:20:34 2025
    On 1/14/2025 11:03 AM, Arne Vajhøj wrote:
    On 1/13/2025 11:38 PM, Lawrence D'Oliveiro wrote:
    On Mon, 13 Jan 2025 21:08:11 -0500, John Reagan wrote:
    ### They are probably most useful for modules, but why not allow
    ### them for programs?
    Extended Pascal says only MODULEs so we just didn't
    think about allowing them in PROGRAMs even though we allow [INITIALIZE].

    Not sure what the point would be in having them in PROGRAMs, anyway.

    Definitely most useful for modules. I was just wondering
    why not allow it in programs as well.

    It seems to have been explicit disallowed. The error message is:

    %PASCAL-E-TOPROGRAM, TO BEGIN/END DO not allowed in PROGRAM

    If one start to look for something useful then I would say that
    TO BEGIN is just code after PROGRAM BEGIN, but TO END is more
    than just code before PROGRAM END as it get triggered by other
    program exits as well.

    Demo:

    $ type m.pas
    module m(input,output);

    to begin do writeln('m to begin');
    to end do writeln('m to end');

    end.
    $ type p.pas
    [inherit('m', 'sys$library:starlet')]
    program p(input,output);

    [initialize]
    procedure init;

    begin
       writeln('init');
    end;

    procedure done;

    begin
       writeln('done');
    end;

    var
       ent : integer64;
       desblk : array [1..4] of integer;
       cond : integer;

    begin
       writeln('begin');
       desblk[1] := 0;
       desblk[2] := iaddress(done);
       desblk[3] := 0;
       desblk[4] := iaddress(cond);
       $dclexh(desblk);
       $get_entropy(ent, 8);
       if (ent mod 2) = 0 then $exit(SS$_NORMAL);
       $canexh(desblk);
       writeln('end');
    end.
    $ pas/env m
    $ pas p
    $ link p + m
    $ run p
    m to begin
    init
    begin
    end
    m to end
    $ run p
    m to begin
    init
    begin
    done
    m to end
    $ run p
    m to begin
    init
    begin
    end
    m to end
    $ run p
    m to begin
    init
    begin
    done
    m to end

    Arne

    I just looked. The TO BEGIN/END DO was added back in 1987 by a former developer (not me). I suspect that since the Extended Pascal standard
    only allows them in MODULEs, not PROGRAMs, that he just followed the
    draft standard at that point without considering that TO END DO is a
    little better than "code at the end".

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Sun Feb 2 20:37:50 2025
    On 2/2/2025 8:30 PM, Arne Vajhøj wrote:
    On 1/14/2025 11:06 AM, Arne Vajhøj wrote:
    On 1/13/2025 9:11 PM, John Reagan wrote:
    COBOL paragraphs behave like C. First routine/PARAGRAPH gets a WEAK
    transfer address. Linker finds the first one.

    I have many prejudices about COBOL developers.

    One of them is that they don't create shareable images.

    :-)

    But let us say that someone wanted to create a shareable
    image in Cobol.

    A typical Cobol program just have all the paragraphs that
    get performed and they share state. Simple.

    To make them entry points with arguments in a shareable image,
    then I assume one need to make them programs with linkage section
    and procedure division using.

    Normal variables are just passed as arguments. Seems entirely
    unproblematic to me.

    But how does one share open files between modules?

    Fortran and Basic numeric identifiers work across modules.
    Pascal can share via inherit. C can use global variables
    or just pass as argument.

    But how does one do that in Cobol?

    Can one mark an fd as global or can one pass a fd as argument?

    Did some reading.

    IS GLOBAL in one module and IS EXTERNAL in the other modules?

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)