mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-12-22 14:30:29 +00:00
710 lines
11 KiB
NASM
710 lines
11 KiB
NASM
***********************************************************************
|
|
*
|
|
* The GNO Shell Project
|
|
*
|
|
* Developed by:
|
|
* Jawaid Bazyar
|
|
* Tim Meekins
|
|
*
|
|
**************************************************************************
|
|
*
|
|
* INVOKE.ASM
|
|
* By Tim Meekins
|
|
*
|
|
* Command invocation routines.
|
|
*
|
|
**************************************************************************
|
|
|
|
mcopy m/invoke.mac
|
|
keep o/invoke.mac
|
|
|
|
SIGINT gequ 2
|
|
SIGKILL gequ 9
|
|
SIGTERM gequ 15
|
|
SIGSTOP gequ 17
|
|
SIGTSTP gequ 18
|
|
SIGCONT gequ 19
|
|
SIGCHLD gequ 20
|
|
SIGTTIN gequ 21
|
|
SIGTTOU gequ 22
|
|
|
|
**************************************************************************
|
|
*
|
|
* Redirect
|
|
*
|
|
**************************************************************************
|
|
|
|
redirect START
|
|
|
|
space equ 1
|
|
pipeout2 equ space+3
|
|
pipein2 equ pipeout2+2
|
|
pipeout equ pipein2+2
|
|
pipein equ pipeout+2
|
|
eapp equ pipein+2
|
|
app equ eapp+2
|
|
efile equ app+2
|
|
dfile equ efile+4
|
|
sfile equ dfile+4
|
|
end equ sfile+4
|
|
|
|
; subroutine (4:sfile,4:dfile,4:efile,2:app,2:eapp,2:pipein,2:pipeout,2:pipein2,2:pipeout2),space
|
|
|
|
tsc
|
|
phd
|
|
tcd
|
|
;
|
|
; standard input
|
|
;
|
|
ora2 sfile,sfile+2,@a
|
|
beq execa
|
|
pei (sfile+2) ;for c2pstr
|
|
pei (sfile)
|
|
pei (sfile+2)
|
|
pei (sfile)
|
|
jsr cstrlen
|
|
inc a
|
|
pea 0
|
|
pha
|
|
jsl ~NEW
|
|
sta RedirectFile
|
|
stx RedirectFile+2
|
|
phx
|
|
pha
|
|
jsr c2pstr
|
|
stz RedirectDev
|
|
stz RedirectApp
|
|
Redirect RedirectParm
|
|
php
|
|
ph4 RedirectFile
|
|
jsl nullfree
|
|
plp
|
|
bcc execa
|
|
ldx #^err1
|
|
lda #err1
|
|
jmp badbye
|
|
;
|
|
; standard output
|
|
;
|
|
execa ora2 dfile,dfile+2,@a
|
|
beq execb
|
|
pei (dfile+2) ;for c2pstr
|
|
pei (dfile)
|
|
pei (dfile+2)
|
|
pei (dfile)
|
|
jsr cstrlen
|
|
inc a
|
|
pea 0
|
|
pha
|
|
jsl ~NEW
|
|
sta RedirectFile
|
|
stx RedirectFile+2
|
|
phx
|
|
pha
|
|
jsr c2pstr
|
|
ld2 1,RedirectDev
|
|
mv2 app,RedirectApp
|
|
Redirect RedirectParm
|
|
php
|
|
ph4 RedirectFile
|
|
jsl nullfree
|
|
plp
|
|
bcc execb
|
|
ldx #^err2
|
|
lda #err2
|
|
jmp badbye
|
|
;
|
|
; standard error
|
|
;
|
|
execb ora2 efile,efile+2,@a
|
|
beq execc
|
|
pei (efile+2) ;for c2pstr
|
|
pei (efile)
|
|
pei (efile+2)
|
|
pei (efile)
|
|
jsr cstrlen
|
|
inc a
|
|
pea 0
|
|
pha
|
|
jsl ~NEW
|
|
sta RedirectFile
|
|
stx RedirectFile+2
|
|
phx
|
|
pha
|
|
jsr c2pstr
|
|
ld2 2,RedirectDev
|
|
mv2 eapp,RedirectApp
|
|
Redirect RedirectParm
|
|
php
|
|
ph4 RedirectFile
|
|
jsl nullfree
|
|
plp
|
|
bcc execc
|
|
ldx #^err3
|
|
lda #err3
|
|
jmp badbye
|
|
;
|
|
; is input piped in?
|
|
;
|
|
execc lda pipein
|
|
beq execd
|
|
dup2 (pipein,#1)
|
|
mv2 pipein2,CloseRef
|
|
Close CloseParm
|
|
ldx #0
|
|
lda pipein
|
|
SetInputDevice (#3,@xa)
|
|
;
|
|
; is output piped?
|
|
;
|
|
execd lda pipeout
|
|
beq exece
|
|
dup2 (pipeout,#2)
|
|
mv2 pipeout2,CloseRef
|
|
Close CloseParm
|
|
ldx #0
|
|
lda pipeout
|
|
SetOutputDevice (#3,@xa)
|
|
|
|
exece anop
|
|
|
|
goodbye ldy #0
|
|
bra exit
|
|
badbye jsr errputs
|
|
cop $7F ; get out of the way
|
|
ldy #1
|
|
exit lda space
|
|
sta end-3
|
|
lda space+1
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-4
|
|
tcs
|
|
|
|
cpy #1
|
|
|
|
rtl
|
|
|
|
RedirectParm anop
|
|
RedirectDev ds 2
|
|
RedirectApp ds 2
|
|
RedirectFile ds 4
|
|
CloseParm dc i'1'
|
|
CloseRef dc i'0'
|
|
|
|
err1 dc c'gsh: Error redirecting standard input.',h'0d00'
|
|
err2 dc c'gsh: Error redirecting standard output.',h'0d00'
|
|
err3 dc c'gsh: Error redirecting standard error.',h'0d00'
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* Invoke a command (PHASE 0)
|
|
*
|
|
**************************************************************************
|
|
|
|
invoke START
|
|
|
|
using hashdata
|
|
using vardata
|
|
using global
|
|
using pdata
|
|
|
|
p equ 0
|
|
biflag equ p+4
|
|
ptr equ biflag+2
|
|
val equ ptr+4
|
|
dir equ val+2
|
|
space equ dir+4
|
|
|
|
subroutine (2:argc,4:argv,4:sfile,4:dfile,4:efile,2:app,2:eapp,2:bg,4:cmd,2:jobflag,2:pipein,2:pipeout,2:pipein2,2:pipeout2,4:pipesem),space
|
|
|
|
ld2 -1,val
|
|
stz biflag ;not a built-in
|
|
|
|
lda argc
|
|
bne chknull
|
|
|
|
lda sfile
|
|
ora sfile+2
|
|
ora dfile
|
|
ora dfile+2
|
|
ora efile
|
|
ora efile+2
|
|
beq nulldone
|
|
|
|
ldx #^hehstr
|
|
lda #hehstr
|
|
jsr errputs
|
|
|
|
nulldone jmp done
|
|
;
|
|
; Check for null command
|
|
;
|
|
chknull ldy #2
|
|
lda [argv]
|
|
sta dir
|
|
lda [argv],y
|
|
sta dir+2
|
|
ora dir
|
|
beq gonull
|
|
lda [dir]
|
|
and #$FF
|
|
bne checkfile
|
|
gonull jmp done
|
|
;
|
|
; check for file
|
|
;
|
|
checkfile anop
|
|
|
|
pei (dir+2)
|
|
pei (dir)
|
|
jsl IsBuiltin ;check builtin first
|
|
cmp #-1
|
|
jne trybuiltin
|
|
|
|
pei (dir+2)
|
|
pei (dir)
|
|
ph4 hash_table
|
|
ph4 #hash_paths
|
|
jsl search
|
|
cmp #0
|
|
bne changeit
|
|
cpx #0
|
|
beq skip
|
|
|
|
changeit sta dir
|
|
stx dir+2
|
|
|
|
skip lock mutex2
|
|
pei (dir+2)
|
|
pei (dir)
|
|
jsr c2gsstr
|
|
sta GRecPath
|
|
sta ptr
|
|
stx GRecPath+2
|
|
stx ptr+2
|
|
|
|
GetFileInfo GRec
|
|
unlock mutex2
|
|
jcs notfound
|
|
|
|
if2 GRecFileType,eq,#$B5,doExec
|
|
if2 @a,eq,#$B3,doExec
|
|
ldx vardirexec
|
|
bne ft02
|
|
cmp #$0F
|
|
jeq doDir
|
|
ft02 if2 @a,ne,#$B0,badfile
|
|
if2 GRecAuxType,ne,#6,badfile
|
|
if2 GRecAuxType+2,ne,#0,badfile
|
|
jmp doShell
|
|
badfile ldx dir+2
|
|
lda dir
|
|
jsr errputs
|
|
ldx #^err1
|
|
lda #err1
|
|
jsr errputs
|
|
free pei (ptr+2)
|
|
pei (ptr)
|
|
jsl nullfree
|
|
jmp done
|
|
;
|
|
; launch an executable
|
|
;
|
|
doExec pei (ptr+2)
|
|
pei (ptr)
|
|
jsl nullfree
|
|
jsr prefork
|
|
fork #invoke0
|
|
jsr postfork
|
|
jmp done
|
|
|
|
invoke0 phk
|
|
plb
|
|
;
|
|
; make a a copy of cmd
|
|
;
|
|
pha
|
|
pha
|
|
tsc
|
|
phd
|
|
tcd
|
|
ldx #0
|
|
tsc
|
|
FindHandle @xa,1
|
|
ldy #6
|
|
lda [1],y ;This is the UserID!
|
|
and #$F0FF
|
|
pha
|
|
ph4 _cmd
|
|
jsr cstrlen
|
|
inc a
|
|
ply
|
|
pha
|
|
ldx #0
|
|
NewHandle (@xa,@y,#$4018,#0),1
|
|
ply
|
|
ldx #0
|
|
PtrToHand (_cmd,1,@xy)
|
|
ldy #2
|
|
lda [1],y
|
|
tax
|
|
lda [1]
|
|
pld
|
|
ply
|
|
ply
|
|
phx ;_cmd
|
|
pha
|
|
;
|
|
; make a a copy of dir
|
|
;
|
|
pha
|
|
pha
|
|
tsc
|
|
phd
|
|
tcd
|
|
ldx #0
|
|
tsc
|
|
FindHandle @xa,1
|
|
ldy #6
|
|
lda [1],y ;This is the UserID!
|
|
and #$F0FF
|
|
pha
|
|
ph4 _dir
|
|
jsr cstrlen
|
|
inc a
|
|
ply
|
|
pha
|
|
ldx #0
|
|
NewHandle (@xa,@y,#$4018,#0),1
|
|
ply
|
|
ldx #0
|
|
PtrToHand (_dir,1,@xy)
|
|
ldy #2
|
|
lda [1],y
|
|
tax
|
|
lda [1]
|
|
pld
|
|
ply
|
|
ply
|
|
phx ;_dir
|
|
pha
|
|
|
|
jsl infork
|
|
bcs invoke1
|
|
case on
|
|
jsl execve
|
|
case off
|
|
rtl
|
|
invoke1 pla
|
|
pla
|
|
pla
|
|
pla
|
|
rtl
|
|
;
|
|
; do path (it was a directory entry so change to that directory)
|
|
;
|
|
doDir lock cdmutex
|
|
mv4 GRecPath,PRecPath
|
|
SetPrefix PRec
|
|
unlock cdmutex
|
|
stz val
|
|
jmp free
|
|
;
|
|
; fork a shell script
|
|
;
|
|
doShell inc biflag ;don't free argv...
|
|
jsr prefork
|
|
|
|
* int fork2(void *subr, int stack, int prio, char *name, word argc, ...)
|
|
pea 0
|
|
ldy #2
|
|
lda [argv],y
|
|
pha
|
|
lda [argv]
|
|
pha
|
|
pea 0
|
|
pea 1024
|
|
ph4 #exec0
|
|
case on
|
|
jsl fork2
|
|
case off
|
|
|
|
* fork #exec0
|
|
jsr postfork
|
|
jmp free
|
|
|
|
exec0 ph2 _argc ;for argfree
|
|
ph4 _argv
|
|
|
|
ph4 _dir ;for shellexec
|
|
ph2 _argc
|
|
ph4 _argv
|
|
jsl infork
|
|
bcs exec0c
|
|
signal (#SIGCHLD,#0)
|
|
PushVariables 0
|
|
pea 1
|
|
jsl ShellExec
|
|
jsl argfree
|
|
PopVariables 0
|
|
rtl
|
|
exec0c pla
|
|
pla
|
|
pla
|
|
pla
|
|
pla
|
|
pla
|
|
pla
|
|
pla
|
|
rtl
|
|
;
|
|
; file not found, so try a builtin.
|
|
;
|
|
trybuiltin inc biflag ;it's a built-in
|
|
cmp #1
|
|
beq noforkbuiltin
|
|
jsr prefork
|
|
fork #forkbuiltin
|
|
jsr postfork
|
|
jmp done
|
|
|
|
forkbuiltin cop $7F ;give palloc a chance
|
|
ph2 _argc
|
|
ph4 _argv
|
|
jsl infork
|
|
bcs fork0c
|
|
jsl builtin
|
|
rtl
|
|
fork0c pla
|
|
pla
|
|
pla
|
|
rtl
|
|
|
|
noforkbuiltin anop
|
|
pei (argc)
|
|
pei (argv+2)
|
|
pei (argv)
|
|
jsl builtin
|
|
stz val
|
|
bra done
|
|
|
|
notfound pei (ptr+2)
|
|
pei (ptr)
|
|
jsl nullfree
|
|
ldy #2
|
|
lda [argv],y
|
|
tax
|
|
lda [argv]
|
|
jsr errputs
|
|
ldx #^err2
|
|
lda #err2
|
|
jsr errputs
|
|
lda pipein
|
|
beq notfound0
|
|
ssignal _semaphore
|
|
sdelete _semaphore
|
|
mv4 pjoblist,p
|
|
ldy #16 ;p_jobid
|
|
lda [p],y
|
|
getpgrp @a
|
|
eor #$FFFF
|
|
inc a
|
|
kill (@a,#9)
|
|
sigpause #0
|
|
notfound0 anop
|
|
|
|
done cop $7F
|
|
lda biflag
|
|
bne skipfrarg
|
|
|
|
pei (argc)
|
|
pei (argv+2)
|
|
pei (argv)
|
|
jsl argfree
|
|
|
|
skipfrarg pei (cmd+2)
|
|
pei (cmd)
|
|
jsl nullfree
|
|
|
|
return 2:val
|
|
;
|
|
;
|
|
; stuff to do just before forking
|
|
;
|
|
prefork lock mutex
|
|
SetInGlobals (#$FF,#00)
|
|
mv4 sfile,_sfile
|
|
mv4 dfile,_dfile
|
|
mv4 efile,_efile
|
|
mv2 app,_app
|
|
mv2 eapp,_eapp
|
|
mv4 cmd,_cmd
|
|
mv4 dir,_dir
|
|
mv2 argc,_argc
|
|
mv4 argv,_argv
|
|
mv2 pipein,_pipein
|
|
mv2 pipeout,_pipeout
|
|
mv2 pipein2,_pipein2
|
|
mv2 pipeout2,_pipeout2
|
|
mv2 bg,_bg
|
|
mv2 jobflag,_jobflag
|
|
lda [pipesem]
|
|
sta _semaphore
|
|
lda pipesem
|
|
sta putsem+1
|
|
lda pipesem+1
|
|
sta putsem+2
|
|
rts
|
|
;
|
|
; stuff to do right after forking
|
|
;
|
|
postfork sta val
|
|
lda pipein
|
|
beq postfork2
|
|
sta CloseRef
|
|
Close CloseParm
|
|
postfork2 lda pipeout
|
|
beq postfork3
|
|
sta CloseRef
|
|
Close CloseParm
|
|
postfork3 lda val
|
|
cmp #-1
|
|
bne postfork4
|
|
ldx #^deadstr
|
|
lda #deadstr
|
|
jsr errputs
|
|
unlock mutex
|
|
jmp done
|
|
postfork4 ldx jobflag
|
|
dex
|
|
beq postfork5
|
|
pha
|
|
pei (bg)
|
|
pei (cmd+2)
|
|
pei (cmd)
|
|
lda pipein
|
|
bne postfork4a
|
|
jsl palloc
|
|
bra postfork5
|
|
postfork4a jsl pallocpipe
|
|
postfork5 lda >mutex ;DANGER!!!!! Assumes knowledge of
|
|
beq postfork6 ;lock/unlock structure!!!!!!!!
|
|
cop $7F
|
|
bra postfork5
|
|
postfork6 rts
|
|
;
|
|
; stuff to do in fork
|
|
;
|
|
infork phk
|
|
plb
|
|
|
|
lda _jobflag
|
|
bne invoke0b
|
|
|
|
Open ttyopen
|
|
jcs doneinfork
|
|
|
|
lda _pipein
|
|
bne invoke0a
|
|
tcnewpgrp ttyref
|
|
invoke0a settpgrp ttyref
|
|
lda _bg ;if in background then reset tty to
|
|
and #$FF
|
|
beq invoke0b ;to the shell process group
|
|
tctpgrp (gshtty,gshpid)
|
|
|
|
invoke0b ph4 _sfile
|
|
ph4 _dfile
|
|
ph4 _efile
|
|
ph2 _app
|
|
ph2 _eapp
|
|
ph2 _pipein
|
|
ph2 _pipeout
|
|
ph2 _pipein2
|
|
ph2 _pipeout2
|
|
jsl redirect
|
|
jcs doneinfork
|
|
|
|
unlock mutex
|
|
|
|
lda _pipein
|
|
bne invoke0c
|
|
lda _pipeout
|
|
beq invoke0d
|
|
screate #0
|
|
putsem sta >$FFFFFF
|
|
swait @a
|
|
bra invoke0d
|
|
invoke0c lda _pipeout
|
|
bne invoke0d
|
|
waitsemy lda _semaphore
|
|
bne goodsemy
|
|
cop $7F
|
|
bra waitsemy
|
|
goodsemy ssignal _semaphore
|
|
sdelete _semaphore
|
|
|
|
invoke0d anop
|
|
|
|
clc
|
|
bra indone
|
|
|
|
doneinfork unlock mutex
|
|
sec
|
|
indone rtl
|
|
|
|
mutex key
|
|
mutex2 key
|
|
cdmutex key
|
|
|
|
_argc dc i2'0'
|
|
_argv dc i4'0'
|
|
_sfile dc i4'0'
|
|
_dfile dc i4'0'
|
|
_efile dc i4'0'
|
|
_app dc i2'0'
|
|
_eapp dc i2'0'
|
|
_cmd dc i4'0'
|
|
_dir dc i4'0'
|
|
_pipein dc i2'0'
|
|
_pipeout dc i2'0'
|
|
_pipein2 dc i2'0'
|
|
_pipeout2 dc i2'0'
|
|
_bg dc i2'0'
|
|
_jobflag dc i2'0'
|
|
_semaphore dc i2'0'
|
|
|
|
str dc c'[0]',h'0d00'
|
|
err1 dc c': Not executable.',h'0d00'
|
|
err2 dc c': Command not found.',h'0d00'
|
|
hehstr dc c'heh heh, next time you''ll need to specify a command '
|
|
dc c'before redirecting.',h'0d00'
|
|
deadstr dc c'Cannot fork (too many processes?)',h'0d00' ;try a spoon
|
|
|
|
GRec dc i'4'
|
|
GRecPath ds 4
|
|
ds 2
|
|
GRecFileType ds 2
|
|
GRecAuxType ds 4
|
|
|
|
PRec dc i'2'
|
|
PRecNum dc i'0'
|
|
PRecPath ds 4
|
|
|
|
CloseParm dc i2'1'
|
|
CloseRef dc i2'0'
|
|
|
|
Err dc i2'0'
|
|
|
|
ttyopen dc i2'2'
|
|
ttyref dc i2'0'
|
|
dc i4'ttyname'
|
|
ttyname gsstr '.tty'
|
|
|
|
END
|