system() or exec() for Lattice C - (nf)
goldberg at uiucdcs.UUCP
goldberg at uiucdcs.UUCP
Sun Jun 24 08:06:00 AEST 1984
#R:pyramid:-16600:uiucdcs:12600018:000:6001
uiucdcs!goldberg Jun 23 17:06:00 1984
Here is one I scarfed a while back... I haven't even had a chance to play
with it yet, however.
Phil Goldberg
University of Illinois @ Urbana-Champaign
...!{convex,ihnp4,pur-ee}!uiucdcs!goldberg
goldberg.uiuc at csnet.arpa
<--------------------------------------------------------------------------->
/**** uiuccsc:net.sources / ihlpf!dap1 / 4:16 am Nov 16, 1983 ****/
This routine implements the UN*X system call (in spite of the fact that I
called it exec, the name in the DOS manual) under Lattice C although it
should be easy to adopt it to other languages. One caution, it uses the
undocumented 037h DOS call to retrieve the switch character. This is
clearly marked in the code and I will change it after DOS 2.0 so I'd rather
the DOS purists don't jump down my throat about this. If you don't like it
the way it is, change it.
Darrell Plank
BTL-IH
-----------------
PAGE 55,132
;
; This function is modified from the macro by Brad Davis (b-davis at utah-cs)
; The prolog and epilog are modified from Jim Holtman's macros for Pascal.
;
; exec( cmd)
; char *cmd;
;
; This function accepts a string with the pathname of a command to be
; executed and executes it. The returned value is one of the following:
; 0: Successful
; -1: Insufficient Memory
; -2: Access Denied
; -3: No such command
; -4: Invalid command format
;
PROLOG MACRO
PUSH BP
MOV BP,SP
ENDM
EPILOG MACRO NUM
POP BP
RET
ENDM
EXECVAL EQU 0
OVLVAL EQU 3
FNCINT EQU 21H
SETBLK EQU 4AH
EXECF EQU 4BH
CR EQU 0DH
PSP STRUC
INTVECT DW ?
TOM DW ?
RES1 DB ?
DOSLONG DB 5 DUP (?)
TERMINA DD ?
CTRLBRK DD ?
CRITERR DD ?
DOS1 DB 22 DUP (?)
ENVIRO DW ?
DOS2 DB 46 DUP (?)
FPA1 DB 16 DUP (?)
FPA2 DB 20 DUP (?)
UPA DB 128 DUP (?)
PSP ENDS
EXECDEF STRUC
NENVIRO DW
COMMND DW 2 DUP (0)
FCB5CH DW 2 DUP (0)
FCB6CH DW 2 DUP (0)
EXECDEF ENDS
PGROUP GROUP PROG
PROG SEGMENT BYTE PUBLIC 'prog'
ASSUME CS:PGROUP
PUBLIC EXEC
EXEC PROC NEAR
PROLOG
PUSH DS
PUSH ES
;
; free up as much memory as we can
;
MOV AX,CS
PUSH ES ; Save ES for later
MOV ES,AX
MOV BX,SS
SUB BX,AX
ADD BX,1000H ; 64K for stack segment
MOV AH,SETBLK
INT FNCINT
JNC NEAR PTR LBL1
MOV AX,-1 ; Insufficient memory
JMP NEAR PTR FINE
LBL1: POP ES ; Get ES's original value
;
; Save SS and SP registers
;
MOV CS:SPSAVE,SP
MOV CS:SSSAVE,SS
;
; set up the parameter block
;
MOV CS:EXECBLK.NENVIRO,0 ; Inherit envir. from parent
MOV AX,3700H ; Undocumented call for SWITCHAR
;
; W A R N I N G: The following function call is undocumented and is
; liable to disappear or change in future versions of DOS.
;
INT FNCINT
MOV CS:COMMAND[1],DL ; Switchar
MOV DX,4[BP] ; Address of the command
MOV SI,DX
MOV DI,DX
CLD
XOR AL,AL
MOV CX,100H ; Longest string can be 100h
REPNE SCASB ; Find Null termination
SUB DX,DI
NEG DX
MOV CX,DX
DEC CX
ADD DX,2
MOV CS:COMMAND[0],DL ; Save command length
LEA DI,CS:COMMAND[4]
MOV AX,CS
MOV ES,AX
REP MOVSB ; Copy command into our buffer
ASSUME DS:PGROUP
MOV AX,CS
MOV DS,AX ; DS points at code segment
MOV BYTE PTR [DI],CR ; Put in Carriage Return
LEA DX,COMMAND
MOV EXECBLK.COMMND[0],DX
MOV EXECBLK.COMMND[2],DS
MOV BX,OFFSET EXECBLK
XOR SI,SI
MOV DS,[SI].ENVIRO ; Get environment address
ASSUME DS:NOTHING
LEA SI,CS:COMSPEC ; Point SI at env. variable name
PUSH DS ; Swap
PUSH ES ; ES
POP DS ; and
POP ES ; DS
CALL GETENV
PUSH DS ; Swap
PUSH ES ; them
POP DS ; back
POP ES ; again
MOV AH,EXECF
MOV AL,EXECVAL ; OVLVAL here for overlay
INT FNCINT
JC NEAR PTR LBL2
MOV AX,0 ; Successful exec
JMP NEAR PTR FINE
LBL2: MOV SI,AX
MOV AL,CS:ERRORS[SI] ; Get error code
MOV AH,0FFH ; Sign extension - Assume Negative
FINE: MOV SS,CS:SSSAVE
MOV SP,CS:SPSAVE
POP ES
POP DS
EPILOG 1
EXECBLK EXECDEF <>
;
; first byte of command is length excluding the length byte and the
; trailing \r. Second byte is switchar.
;
COMMAND DB 2 DUP(?),"C ",254 DUP(?)
COMSPEC DB "COMSPEC",0
SPSAVE DW
SSSAVE DW
ERRORS DB ?
DB ?
DB -3 ; No such command
DB ?
DB ?
DB -2 ; Access denied
DB ?
DB ?
DB -1 ; Insufficient memory
DB ?
DB ?
DB -4 ; Invalid command format
EXEC ENDP
;
; Getenv expects ES to have the environment paragraph and DS:SI to point
; to an ASCIIZ string with the desired environment variable in it.
; It returns the address of the proper string in ds:dx.
;
PUBLIC GETENV
GETENV PROC NEAR
PROLOG
PUSH AX
PUSH CX
PUSH SI
PUSH DI
MOV CS:VARNAME,SI ; Save offset of env. name
XOR DI,DI
;
; At this point ds:si points to dummy variable environment name and
; es:di points to environment.
;
CLD ;Forward string operations
TOP:
LODSB ;Get a char. of env. name
CMP AL,0 ;If we're at the end
JNE NEAR PTR LBL3
CMP BYTE PTR ES:[DI],'=' ;Check for match
JNE NEAR PTR LBL4
;
; We matched
;
INC DI ;Move beyond '='
MOV DX,DI
POP DI
POP SI
POP CX
POP AX
EPILOG 2
LBL4:
;
; At this point we found the end of the Env. variable name but it didn't
; match because the env. string was too long
;
MOV CX,-1
REPNE SCASB ;Find the end of the env. string
CMP BYTE PTR ES:[DI],0
JNE LBL3
MOV AX,-1 ;End of environment area
POP DI
POP SI
POP CX
POP AX
EPILOG 2
LBL3:
;
; Check if the next character matches
;
AND AX,11011111b ;Capitalize the character in ax
SCASB
JE TOP
;
; If we get here we don't have a match so move on
;
MOV SI,CS:VARNAME ;Go back to start of env. string
XOR AX,AX
MOV CX,-1
REPNE SCASB ;Go to next env. variable
CMP BYTE PTR ES:[DI],0
JNE TOP
MOV AX,-1 ;End of environment area
POP DI
POP SI
POP CX
POP AX
EPILOG 2
VARNAME DW ?
GETENV ENDP
PROG ENDS
END
/* ---------- */
More information about the Comp.sources.unix
mailing list