[comp.sys.amiga] EXECUTE

kkaempf@rmi.UUCP (Klaus Kaempf) (01/22/88)

Wanna call a CLI-command in your own application? Maybe you
don't have "RUN" in your "C:" directory? Or it's "PROMPT",
"STACK", "CD" or the like? So forget "Execute()"! But it's
one of these BCPL programs - darn!

Try this one!

This small program can be used to execute CLI-commands, even
the ones that rely on the correct BCPL setup.

Two restrictions:

"System0()" must be called from a CLI-PROCESS (or SHELL or
whatever). You cannot call it from WorkBench, a simple task
or interrupt (argh!).

"EXECUTE" (the CLI-command) will not loop through the
batchfile itself, but rather change the "cli_CurrentInput",
so the shell will execute the incoming lines until "EOF" is
encountered and then restore "cli_CurrentInput". So this is
not a restriction, if you return to the input-loop directly
after "System0()" has been called (normally true in shell
program). Batchfiles called this way may be nested, but do
not try to "EXECUTE" several batch-files ...

System0("Execute", seglist, "first");
System0("Execute", seglist, "second");
System0("Execute", seglist, "third");

... without returning to the input-loop first.

"System0()" WON'T handle loading and unloading of the code,
I/O-redirection or whatever, but this is fairly simple.

Commands should be checked in the following order:

built-in commands of the shell
resident commands ("NetHand")
current directory (WindowPtr = -1)
path list ("CommandDir", WindowPtr = -1)
"C:" (WindowPtr = 0)

As an option for shells: Try to execute it as a batchfile
(current directory or "S:"), if everything else fails (but
use "WindowPtr = -1" for "C:" then).

I/O-redirection should save the values of "pr_CIS" and
"pr_COS", put the new ones into these fields and restore
them after the command has finished. That's why "EXECUTE" is
not that much impressed if you supply it with ">" or "<".

"System0()" returns the return code (register D0 or
"Exit()"-parameter) of the program called (not the same as
"Execute()"!), or an internal error code:

-1: process not a CLI
-2: not enough memory for stack

It does not rely on some strange undocumented data
structures the way Aztec's "fexec#?()" does. You do not need
a special startup code to save the registers (Csh 2.04). I
still have to find the command, that cannot be called this
way, but you will certainly manage this. :-)

Two non-standard include files are used. "extern/exec.i"
contains the "_LVO" equates for "exec", you can use
"amiga.lib" instead. "extras/asm.i" provides ...

AbsExecBase equ 4

REG_SysBase equr a6

callsys macro
        jsr _LVO\1(REG_SysBase)
        endm

The uuencoded object file has been created using the
Metacomco Macro Assembler. A new release (11.1) of this one
has been announced for the ST, does anybody have further
information about an Amiga-version?

multam salutem omnibus

!ralph

P.S.: If someone would be as kind as to mail me a disk with
the latest version of Matt's shell for Lattice-C? Thanks!

################
*
* System0.asm - invoke system's command processor
*
* Copyright (C) by Ralph Babel, Guru Meditation Network,
* Falkenweg 3, D-6204 Taunusstein, West-Germany
*
* This piece of code may be used as part of any product as
* long as the source code for the complete program can be
* obtained free of charge (except for a small copying fee)
* and this copyright notice is left unchanged.
*
* Bug reports and improved versions appreciated.
*
* 20-Jul-1987 created original version
* 11-Jan-1988 now based on "official" information only
*

        nolist

        include "exec/types.i"
        include "libraries/dos.i"
        include "libraries/dosextens.i"
        include "extern/exec.i"
        include "extras/asm.i"

        list

*
* LONG System0(name, seglist, args)
* char *name;
* BPTR seglist;
* char *args;
*

        xdef    _System0
        xref    _DOSBase

* parameter offsets & stack

SAVED_REGS      reg     a2-a6/d2-d3

DELTA           equ     7*4

ARG_NAME        equ     4+DELTA
ARG_SEGLIST     equ     8+DELTA
ARG_ARGS        equ     12+DELTA

* additional return codes

NO_CLI  equ     -1
NO_MEM  equ     -2

* local constants

MAXBSTR equ     255
LF      equ     10

* register usage

REG_Result      equr    d3
REG_Process     equr    a2      ;may not be A4, see below!
REG_CLI         equr    a3
REG_CIS         equr    a4      ;may not be A3, see below!
REG_PrevStack   equr    a5

* local stack frame

 STRUCTURE      StackFrame,0
        STRUCT  sf_CommandName,MAXBSTR+1        ;BSTR, length byte!
        STRUCT  sf_CommandArgs,MAXBSTR+1        ;not a BSTR, LF-terminated!

        APTR    sf_PrevStack

        APTR    sf_SaveReturnAddr
        BPTR    sf_SaveModule
        BPTR    sf_SaveCommandName

        APTR    sf_StackBase
        LONG    sf_StackSize
        LONG    sf_PushSize

        APTR    sf_Process
        APTR    sf_CLI
        APTR    sf_CIS

        BPTR    sf_SCB_Buf
        LONG    sf_SCB_Pos
        LONG    sf_SCB_End

        LABEL   sf_SIZEOF

* entry point

_System0:
        movem.l SAVED_REGS,-(sp)

        moveq   #NO_CLI,REG_Result      ;ERROR - not a CLI task

        movea.l AbsExecBase,REG_SysBase
        suba.l  a1,a1
        callsys FindTask        ;find own task
        movea.l d0,REG_Process
        move.l  pr_CLI(REG_Process),d0
        beq     quit0

* build local stack frame & save some values

        lsl.l   #2,d0   ;BPTR to machine pointer
        movea.l d0,REG_CLI

        movea.l sp,REG_PrevStack        ;save old stack pointer
        move.l  sp,d0
        andi.b  #$fc,d0 ;make SP longword-aligned for BPTRs
        movea.l d0,sp
        suba.w  #sf_SIZEOF,sp

        move.l  REG_PrevStack,sf_PrevStack(sp)
        move.l  REG_Process,sf_Process(sp)
        move.l  REG_CLI,sf_CLI(sp)

        move.l  pr_ReturnAddr(REG_Process),sf_SaveReturnAddr(sp)

* allocate space for stack

        moveq   #NO_MEM,REG_Result      ;ERROR - no memory for STACK

        move.l  cli_DefaultStack(REG_CLI),d0    ;in longwords for "VEC"
        lsl.l   #2,d0
        move.l  d0,sf_PushSize(sp)
        addq.l  #4,d0   ;one additional longword
        move.l  d0,sf_StackSize(sp)
        moveq   #0,d1   ;intentionally NOT "MEMF_PUBLIC"!
        callsys AllocMem
        tst.l   d0
        beq     quit1

        move.l  d0,sf_StackBase(sp)     ;save result

* save old command pointer, build new BCPL command name

        move.l  cli_CommandName(REG_CLI),sf_SaveCommandName(sp)

        movea.l ARG_NAME(REG_PrevStack),a0      ;first parameter to "System0()"
        lea     sf_CommandName+1(sp),a1 ;first char location for BSTR
        move.l  a1,d0
        lsr.l   #2,d0   ;will ignore (+1), BPTR as result
        move.l  d0,cli_CommandName(REG_CLI)

        move.w  #MAXBSTR,d0
        bra.s   2$

1$      move.b  d1,(a1)+
2$      move.b  (a0)+,d1
        dbeq    d0,1$

        suba.l  ARG_NAME(REG_PrevStack),a0      ;subtract original source
        move.l  a0,d0
        subq.l  #1,d0   ;terminating null-byte
        move.b  d0,sf_CommandName(sp)   ;to first location in BSTR

* save contents of Current Input Stream

        move.l  pr_CIS(REG_Process),d0
        lsl.l   #2,d0
        movea.l d0,REG_CIS      ;contains APTR to CIS
        move.l  REG_CIS,sf_CIS(sp)

        move.l  fh_Buf(REG_CIS),sf_SCB_Buf(sp)
        move.l  fh_Pos(REG_CIS),sf_SCB_Pos(sp)
        move.l  fh_End(REG_CIS),sf_SCB_End(sp)

* convert argument to LF-terminated string

        movea.l ARG_ARGS(REG_PrevStack),a0      ;third argument to "System0()"
        lea     sf_CommandArgs(sp),a1   ;first buffer location
        move.l  a1,d0
        lsr.l   #2,d0   ;make buffer pointer a BPTR
        move.l  d0,fh_Buf(REG_CIS)

        move.w  #MAXBSTR,d0     ;leave some room for terminating LF
        bra.s   4$

3$      move.b  d1,(a1)+
4$      move.b  (a0)+,d1
        dbeq    d0,3$

        move.b  #LF,(a1)
        suba.l  ARG_ARGS(REG_PrevStack),a0      ;subtract first position
        move.l  a0,d0   ;do NOT subtract, LF need this byte

* setup start/end indices in Stream Control Block

        clr.l   fh_Pos(REG_CIS)
        move.l  d0,fh_End(REG_CIS)

* misc setup

        clr.l   pr_Result2(REG_Process) ;clear secondary result

        moveq   #0,d0
        move.l  #SIGBREAKF_CTRL_C,d1
        callsys SetSignal       ;clear CTRL-C flag

* handle seglist and start address

        move.l  cli_Module(REG_CLI),sf_SaveModule(sp)

        move.l  ARG_SEGLIST(REG_PrevStack),d0   ;second argument to "System0()"
        move.l  d0,cli_Module(REG_CLI)
        lsl.l   #2,d0
        movea.l d0,a3   ;make it a machine pointer in A3

* setup processor registers & C-interface

        lea     sf_CommandArgs(sp),a0
        move.l  fh_End(REG_CIS),d0

* setup processor registers, BCPL-interface, stack & return address for "Exit()"

        movea.l sf_StackBase(sp),a1     ;BCPL stack, low end
        move.l  sf_PushSize(sp),d2
        lea     4(a1,d2.l),a4   ;must not destroy REG_Process!
        move.l  sp,-(a4)        ;previous stack frame
        move.l  d2,-(a4)        ;stack size in bytes
        move.l  a4,pr_ReturnAddr(REG_Process)
        movea.l a4,sp

        movea.l _DOSBase,a4     ;large data memory model!
        movem.l dl_A2(a4),a2/a5/a6

* now call the command at its entry point

        jsr     4(a3)   ;code starts one longword behind segment pointer

        move.l  d0,REG_Result   ;save return code

* get old stackframe & reload old register contents

        movea.l 4(sp),sp        ;old stack frame

        movea.l sf_Process(sp),a0
        move.l  sf_SaveReturnAddr(sp),pr_ReturnAddr(a0)

        movea.l sf_CLI(sp),a0
        move.l  sf_SaveCommandName(sp),cli_CommandName(a0)
        move.l  sf_SaveModule(sp),cli_Module(a0)

* restore original contents of Current Input Stream

        movea.l sf_CIS(sp),a0
        lea     sf_CommandArgs(sp),a1
        move.l  a1,d0
        lsr.l   #2,d0
        cmp.l   fh_Buf(a0),d0   ;still the same?
        bne.s   5$      ;no: don't restore
        move.l  sf_SCB_Buf(sp),fh_Buf(a0)
5$      move.l  sf_SCB_Pos(sp),fh_Pos(a0)
        tst.l   fh_End(a0)      ;end index set?
        beq.s   6$      ;no: don't restore
        move.l  sf_SCB_End(sp),fh_End(a0)

* free temporary stack

6$      movea.l AbsExecBase,REG_SysBase
        movea.l sf_StackBase(sp),a1
        move.l  sf_StackSize(sp),d0
        callsys FreeMem

quit1   movea.l sf_PrevStack(sp),sp     ;UNLINK local variables

quit0   move.l  REG_Result,d0

        movem.l (sp)+,SAVED_REGS
        rts

        end
################
begin 777 System0.obj
M```#YP````````/I````94CG,#YV_RQX``23R4ZN_MHD0"`J`*QG``%TY8@FN
M0"I/(`\"``#\+D">_`(T+TT"`"]*`APO2P(@+VH`L`($=OX@*P`TY8@O0`(8-
M6(`O0`(4<@!.KO\Z2H!G``$N+T`"$"]K`!`"#"!M`"!#[P`!(`GDB"=``!`PY
M/`#_8`(2P1(85\C_^I'M`"`@"%.`'T```"`J`)SEB"A`+TP")"]L``P"*"]LR
M`!`"+"]L`!0","!M`"A#[P$`(`GDB"E```PP/`#_8`(2P1(85\C_^A*\``J1<
M[0`H(`A"K``0*4``%$*J`)1P`"(\```0`$ZN_LXO:P`\`@@@+0`D)T``/.6(_
M)D!![P$`("P`%")O`A`D+P(82?$H!"D/*0(E3`"P+DPH>0````!,[&0``"I.@
MJP`$)@`N;P`$(&\"'"%O`@0`L"!O`B`A;P(,`!`A;P((`#P@;P(D0^\!`"`)O
MY(BPJ``,9@8A;P(H``PA;P(L`!!*J``49P8A;P(P`!0L>``$(F\"$"`O`A1.7
MKO\N+F\"`"`#3-]\#$YU```#[P$```)?4WES=&5M,`````"!```"7T1/4T)A'
2<V4````!```!(`````````/RO
``
end
################

       Ralph Babel | sys64824
       Falkenweg 3 | (!#X3F0001)()
D-6204 Taunusstein | (**((void (**)(void))0xfc0004))();

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (08/27/90)

In <1990Aug28.092026.322@darwin.ntu.edu.au>, caldwell_t@darwin.ntu.edu.au writes:
>I am looking for a program that does everything that EXECUTE does except WRTIE 
>TO THE DISK.
>
>Let me explain.  I have a non-autobooting hard disk.  So I have a 
>startup-sequence that does a few things and then EXECUTE dh0:s/ss
>
>To do this EXECUTE writes a copy of ss to t: .  If this is on the boot floppy 
>then there is a large delay while the copy is written to its T directory.
>If I assign t: to RAM: then i have to load in the ram-handler.  If I assign t: 
>to hd0: there is a major problem If there is a validation happening.  (It 
>happens every now and again).

Well, there are a couple of things you can do.  The first is to assign T:  to
RAM:, which will not (better not) have any sort of validation problems. You can
assign it elsewhere later if you must.

The second is to not use Execute at all, but to use something like:

  NewCLI CON:0/0/640/100 FROM dh0:s/ss

This will give you a window about half the height of the screen (so you can
still see what's going on in the first window), and will execute dh0:s/ss using
the new window for IO, but without writing a temp file to T:

>I think that this is what caused all validations from then on to hang.

If validation on bootup is causing a problem for your s-s script(s), press
CTRL-D on boot to break the script, then wait for the validation to finish,
then reboot normally.

>BTW: could anyone help me with the problem with the endless validation?

We'd need more details. Validation can be caused by incomplete writes to disk
(reset or power off or crash while writing), or by a bug in the
trackdisk.device in version 1.2 of the OS. The bug shows up when a floppy is
exactly full. Get rid of the writes to the temp file, delete any in the T:
directory, and see if your problem still occurs.

-larry

--
It is not possible to both understand and appreciate Intel CPUs.
    -D.Wolfskill
+-----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                 |
| \X/    lphillips@lpami.wimsey.bc.ca -or- uunet!van-bc!lpami!lphillips |
|        COMPUSERVE: 76703,4322  -or-  76703.4322@compuserve.com        |
+-----------------------------------------------------------------------+

caldwell_t@darwin.ntu.edu.au (08/28/90)

I am looking for a program that does everything that EXECUTE does except WRTIE 
TO THE DISK.

Let me explain.  I have a non-autobooting hard disk.  So I have a 
startup-sequence that does a few things and then EXECUTE dh0:s/ss

To do this EXECUTE writes a copy of ss to t: .  If this is on the boot floppy 
then there is a large delay while the copy is written to its T directory.
If I assign t: to RAM: then i have to load in the ram-handler.  If I assign t: 
to hd0: there is a major problem If there is a validation happening.  (It 
happens every now and again).

I think that this is what caused all validations from then on to hang.

There is no reason for the extra copy in T: as there is no need for 
substitutions in the script.

BTW: could anyone help me with the problem with the endless validation?

Any ideas,
	Malcolm Caldwell

jmeissen@ogicse.ogi.edu (John Meissen) (08/28/90)

In article <1990Aug28.092026.322@darwin.ntu.edu.au> caldwell_t@darwin.ntu.edu.au writes:
>
>There is no reason for the extra copy in T: as there is no need for 
>substitutions in the script.
>
Execute will also create a new copy if there are IF statements in the script


-- 
John Meissen .............................. Oregon Advanced Computing Institute
jmeissen@oacis.org        (Internet) | "That's the remarkable thing about life;
..!sequent!oacis!jmeissen (UUCP)     |  things are never so bad that they can't
jmeissen                  (BIX)      |  get worse." - Calvin & Hobbes

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (08/29/90)

In <20523.26dbd2db@psuecl.bitnet>, d6b@psuecl.bitnet writes:
>In article <1901@lpami.wimsey.bc.ca>, lphillips@lpami.wimsey.bc.ca (Larry Phillips) writes:
>>
>> We'd need more details. Validation can be caused by incomplete writes to disk
>> (reset or power off or crash while writing), or by a bug in the
>> trackdisk.device in version 1.2 of the OS. The bug shows up when a floppy is
>> exactly full. Get rid of the writes to the temp file, delete any in the T:
>> directory, and see if your problem still occurs.
>>
>
>Do you really mean trackdisk, or are you referring to some file system?
>If the latter, which file system has this bug? Thanks!

Hmmm... really not sure. Since I only ever saw the bug on floppies, perhaps it
was the OFS.

-larry


--
It is not possible to both understand and appreciate Intel CPUs.
    -D.Wolfskill
+-----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                 |
| \X/    lphillips@lpami.wimsey.bc.ca -or- uunet!van-bc!lpami!lphillips |
|        COMPUSERVE: 76703,4322  -or-  76703.4322@compuserve.com        |
+-----------------------------------------------------------------------+

Joseph P. Hillenburg (joseph@valnet.UUCP) (08/29/90)

Gee...you mean people at MicroSoft actually USE Amigas? Can you tell us 
if MS has any Amiga stuff planned?

 -Joseph Hillenburg (Sultan of Asm)
INET: joseph@valnet.uucp            |MAIL: 1709 West Gray
UUCP: ...!iuvax!valnet!joseph       |MAIL: Bloomington, IN 47401
AT&T: 1-812-336-2969                |MAIL: United States
CompSci BBS: 3/12/24 1-812-876-4407 9:30 pm-7:30 am |Mail replies requested
              Those aren't bugs! Just undesirable features!

d6b@psuecl.bitnet (08/30/90)

In article <1901@lpami.wimsey.bc.ca>, lphillips@lpami.wimsey.bc.ca (Larry Phillips) writes:
>
> We'd need more details. Validation can be caused by incomplete writes to disk
> (reset or power off or crash while writing), or by a bug in the
> trackdisk.device in version 1.2 of the OS. The bug shows up when a floppy is
> exactly full. Get rid of the writes to the temp file, delete any in the T:
> directory, and see if your problem still occurs.
>

Do you really mean trackdisk, or are you referring to some file system?
If the latter, which file system has this bug? Thanks!

-- Dan Babcock