home *** CD-ROM | disk | FTP | other *** search
- NAME spawnpth
- TITLE Path search for disk-swapping spawn() by Ralf Brown
- PAGE 60,132
- ;-----------------------------------
- ; (c) Copyright 1990, 1991, 1992 Ralf Brown All Rights Reserved
- ; This code may be redistributed as a part of the complete SPAWNO package,
- ; under its distribution conditions.
- ;-----------------------------------
- ; SPAWNO v4.10
- ;
- ; assembler defines:
- ; __TINY__, __SMALL__, __COMPACT__, __MEDIUM__, __LARGE__, __HUGE__
- ; exactly one of the above must be defined to specify the memory
- ; model in use
- ;-----------------------------------
-
- __BSS__ equ 1 ; yes, we are using uninitialized storage
- INCLUDE RULES.ASI
-
- Header@ ; set up segment and group definitions
-
- ; bit flags for the extensions which were found
- COM_EXT equ 1
- EXE_EXT equ 2
- USER_EXT equ 4
-
- ;-----------------------------------------------------------
- ; initialized data
-
- DSeg@
- IFNDEF __TP ; defined in BSeg@ if __TP
- ExtSym@ _psp,WORD,__CDECL__
- ENDIF
-
- PATH_EQUALS db 'PATH='
- PATH_EQUALS_LEN equ $-PATH_EQUALS
- DSegEnd@
-
- ;-----------------------------------------------------------
- ; uninitialized data
-
- BSeg@
- IFDEF __TP
- ExtSym@ _psp, WORD, __CDECL__
- ENDIF
-
- env dd ?
-
- extrn ___SPAWN_PNAME:byte
- executable_path equ ___SPAWN_PNAME
- executable_pad equ ___SPAWN_PNAME + 80
-
- BSegEnd@
-
- CSeg@
- ASSUME DS:DGROUP
-
- extrn __SPAWN_ERRNO:near
- extrn __SPAWN_DDSEP:near
- extrn __SPAWN_CHECK_DIR:near
-
- ;----------------------------------------------------------------
- ; char * pascal __spawn_search(const char *name) ;
- ; given a program name, search the PATH for it, returning the full pathname
- ; or NULL if not found
- ;----------------------------------------------------------------
- PubProc@ __SPAWN_SEARCH,__PASCAL__
- ; parameters
- @name = DPTR_ [bp+2+cPtrSize]
- ; start of subroutine
- ASSUME DS:DGROUP,ES:NOTHING
- push bp
- mov bp,sp
- IFDEF __HUGE__
- push ds ; save caller's DS
- mov ax,DGROUP ; and establish addressing to our
- mov ds,ax ; data segment
- ENDIF ;__HUGE__
- push es
- push di
- push si
- ; set up pointer to environment
- IFDEF __TINY__
- mov es,ds:[002Ch]
- ELSE
- mov es,_psp@
- mov es,es:[002Ch]
- ENDIF ;__TINY__
- xor di,di
- jmp short find_path
- find_path_loop:
- mov al,0
- cmp byte ptr es:[di],al
- je found_path
- cld
- find_path_loop2:
- scasb ; find terminating zero
- jne find_path_loop2
- find_path:
- mov cx,PATH_EQUALS_LEN
- mov si,offset DGROUP:PATH_EQUALS
- repe cmpsb
- jne find_path_loop
- found_path:
- mov word ptr env+2,es
- mov word ptr env,di
- mov byte ptr ___SPAWN_PNAME,0 ; start with null path
- search_loop:
- IF LDATA
- push word ptr @name+2
- ENDIF
- push word ptr @name
- call __SPAWN_CHECK_DIR
- jnz search_successful
- or al,al ; was there a pathspec in the name?
- jne search_failed ; don't look at PATH unless simple filename
- les bx,env
- ASSUME ES:NOTHING
- cmp byte ptr es:[bx],0
- je search_failed
- mov di,offset DGROUP:executable_path
- dir_copy_loop:
- mov al,es:[bx]
- or al,al
- je dir_copy_done
- inc bx
- cmp al,';' ; separator for path entries
- je dir_copy_done
- mov [di],al
- inc di
- cmp di,offset DGROUP:executable_pad ; make sure we don't overrun buf
- jb dir_copy_loop
- dir_copy_done:
- mov al,[di-1]
- call __spawn_ddsep ; was last char a slash/backslash/colon?
- je dir_has_slash
- mov byte ptr [di],'\'
- inc di
- dir_has_slash:
- mov byte ptr [di],0
- mov word ptr env,bx
- jmp search_loop
-
- search_successful:
- mov ax,bx
- IF LDATA
- mov dx,ds
- ENDIF
- jmp short search_done
- search_failed:
- mov ax,2 ; file not found
- call __SPAWN_ERRNO
- xor ax,ax
- IF LDATA
- xor dx,dx
- ENDIF
- search_done:
- pop si
- pop di
- pop es
- IFDEF __HUGE__
- pop ds
- ENDIF ;__HUGE__
- pop bp
- ret dPtrSize
- EndProc@ __SPAWN_SEARCH,__PASCAL__
-
- CSegEnd@
- END
-