MS-DOS patches to perl.
Apply this patch to the standard perl source, version 4, patch level 19,
using "patch -p."  Do this in the root directory of the perl source
distribution.

You can cat all these patches together and pipe the output to patch -p.

Len Reed
Holos Software, Inc.
..!gatech!holos0!lbr
holos0!lbr@gatech.edu
--------------------------------------
*** msdos/argv.asm.old	Sun Feb 23 08:48:16 1992
--- msdos/argv.asm	Thu Nov 14 08:56:28 1991
***************
*** 0 ****
--- 1,347 ----
+ ; Invoke MKS argument handler.  If succcesful, return.
+ ; If unsuccessful, call MS-DOS __argv to process the command line.
+ 
+ ; Called by MS-DOS C startup code (crt0.obj in the C library).
+ 
+ ; This code used detailed knowledge of how the Microsoft C 6.0 startup
+ ; code works.  That source is distributed with the compiler, in
+ ; lib/startup and lib/startup/dos, so we're not talking about a terrible
+ ; guessing game here.
+ 
+ ; This code contains no MKS or Microsoft copyrighted code.
+ 
+ ; This program is free software; you can redistribute it and/or
+ ; modify it under the terms of the GNU General Public License
+ ; (version 1), as published by the Free Software Foundation, and
+ ; found in the file 'LICENSE' included with this distribution.
+ 
+ ; This program is distributed in the hope that it will be useful,
+ ; but WITHOUT ANY WARRANTY; without even the implied warrant of
+ ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ ; GNU General Public License for more details.
+ 
+ ; You must assemble this file with masm flag
+ ;    -dmmodel where model is one of {small, compact, medium, large}
+ ;
+ ifdef msmall
+         .model	small
+   ARG	equ	4
+ endif
+ ifdef mcompact
+ 	.model  compact
+   ARG	equ	4
+ endif
+ ifdef mmedium
+ 	.model	medium
+   ARG	equ	6
+ endif
+ ifdef mlarge
+ 	.model	large
+   ARG	equ	6
+ endif
+ 
+ ;-------------------------
+ 
+ ; The Microsoft startup code calls __setenvp and then __setargv.  Each of
+ ; these can return a changed stack pointer.  The routines set ___argv,
+ ; ___argc, and environ.
+ 
+ 
+ .DATA
+ 
+ If @codesize
+ return_adr dd ?
+ Else
+ return_adr dw ?
+ Endif
+ 
+ extrn __psp:word	; our PSP segment, set by startup before __setenvp
+ extrn ___argc:word	; pointer to argv[], used by startup in calling main
+ extrn _environ:word	; ptr to environment ptrs, used by startup calling main
+ extrn STKHQQ:word	; top of stack, defined by Microsoft C startup
+ extrn __osversion:word	; MS-DOS version
+ 
+ gseg	dw	?	; segment of buffer passed to MKS glob
+ 
+     Public _com_slashc
+ _com_slashc db	'/c', 0	; default switch for command.com
+ 
+ .CODE
+ extrn ___setargv:proc	; Microsoft globber, in C library
+ extrn __amsg_exit:proc	; Microsoft stack overflow death, in C library
+ 
+ extrn _mks_init:proc	; C code to do MKS argument analysis
+ extrn _mks_globber:proc	; C code to run MKS glob.exe
+ 
+ DONT_USE equ 400h	; stack space that must be left over after
+ 			; processing arguments
+ 
+ ; Define MIN_DOS_VER to be minimum version of DOS to support times 100,
+ ; using the -D assembler option.  If undefined, assume 2.0.
+ 
+ Ifndef MIN_DOS_VER
+  MIN_DOS_VER Equ 200	; have to at least have handle I/O, in ver 2.00
+ Endif
+ 
+ If MIN_DOS_VER lt 300
+ exec_ss	dw	?	; needed to support DOS 2.xx exec system call
+ exec_sp	dw	?
+ Endif
+ 
+     Public __setenvp
+ 
+ __setenvp Proc
+     pop ax
+     mov word ptr return_adr,ax
+ If @codesize
+     pop ax
+     mov word ptr return_adr + 2,ax
+ Endif
+ 
+     mov ax,3000h	; get MS-DOS version.
+     int 21h
+     mov __osversion,ax	; Microsoft code we're replacing does this, too.
+     mov dx,ax
+     xchg dl,dh		; version from DOS is in wrong byte order!
+     cmp dx,MIN_DOS_VER	; Approprite DOS version
+     jae ver_okay
+     mov bx,4		; error message number
+     jmp version_death
+ 
+ ver_okay:
+     cmp al,4		; if version 4 or beyond ignore switch char
+     jae ver_4
+     mov ax,3700h	; get switch char, usually / or -
+     int 21h
+     mov _com_slashc,dl	; set the switch character
+ 
+ ver_4:
+     mov ax,STKHQQ	; min SP: below this is stack overflow
+     add ax,DONT_USE	; retain some space, AX will be mks_init's SP
+     cmp sp,ax		; make sure that DONT_USE doesn't exhaust the stack
+     jb too_little	; sorry--expand the stack
+     mov dx,sp
+     sub dx,ax		; DX has amount of space mks_init can play with
+     mov sp,ax		; allocate that space for mks_init
+     push dx		; tell C program how much space he gets
+ 
+     call _mks_init	; parse envp and args, return stack space used
+     			; return -1 for insufficient stack space
+     pop dx		; total that was available
+ 
+     cmp ax,0FFFFh	; was there enough space?
+     je not_enough
+ 
+     sub dx,ax		; subtract off amount actually used
+     add sp,dx		; reduce stack by amount not used
+ 
+     cmp ___argc,0	; did we find the MKS arguments?
+     jnz done_with_args
+ 
+     sub sp,dx		; reallocate the remaining space
+     push dx		; tell mks_globber how big it is
+     call _mks_globber	; try running MKS glob program
+     pop dx		; total that was available
+ 
+     cmp ax,0FFFFh	; was there enough space?
+     je not_enough
+ 
+     sub dx,ax		; subtract off amount actually used
+     add sp,dx		; reduce stack by amount not used
+ 
+     mov ax,gseg
+     or ax,ax
+     jz gspace_freed
+     mov es,ax
+     mov ah,49h		; free the memory block used by glob
+     int 21h
+ 
+ gspace_freed:
+     cmp ___argc,0	; did MKS glob program succeed?
+     jnz done_with_args
+ 
+ ; Last chance, and it's a poor third choice, is to let Microsoft's globber run
+ ; It won't handle single quotes and thinks *.* matches abc and that * doesn't
+ ; match "abc.c".  It will also change the file names to upper case.  If
+ ; someone doesn't like that he can write a globber.
+ 
+     call ___setargv
+ 
+ done_with_args:
+     jmp return_adr
+ 
+ not_enough:
+     add sp,dx		; recover all the space that was allocated
+ 
+ too_little:
+     xor ax,ax		; message zero
+     jmp	__amsg_exit	; stack overflow message and die
+ __setenvp  Endp
+ 
+ ; Resolve Microsoft C's need for the following routine
+ 
+     Public __setargv
+ 
+ __setargv  Proc
+   ret			; all was done by _setenvp
+ __setargv Endp
+ 
+ .DATA
+ 
+ fcb_one	db	0, 12 dup(' ')
+ fcb_two	db	0, 12 dup(' ')
+ 
+ gtt	db	1, ' ', '\r', '\n'	; glob's tail is null
+ 
+ genv	dw	?	; segment of glob's environment
+ gtail	dd	gtt	; pointer to glob's command tail
+ gfcb1	dd	fcb_one	; first FCB
+ gfcb2	dd	fcb_two	; second FCB
+ 
+ .CODE
+ 
+ ; Subroutine to get space for running MKS glob program.
+ ; Can't be using malloc() this early, so we call DOS directly.
+ ; Return a far pointer to the allocated 8K space, 0 for failure.
+ 
+     Public _get_glob_space
+ _get_glob_space Proc
+     mov ah,48h		; MS-DOS allocate memory call
+     mov bx,201h		; 8 Kilobytes worth of paragraphs plus one paragraph
+     			; the extra paragraph is used for glob's environment
+     int 21h
+     jnc got_it
+     sub ax,ax		; not enough memory
+     mov dx,ax
+     ret
+ 
+ got_it:
+     mov gseg,ax		; save segment address
+     mov dx,ax		; return segment address
+     sub ax,ax		; offset is always zero
+     ret
+ _get_glob_space Endp
+ 
+ ; Run the MKS glob program.
+ ; Arguments are standard pointer to the glob program name and far
+ ; pointer to the glob buffer.
+ 
+     Public _spawn_mks_glob
+ 
+ one_dig Proc Near	; convert to ascii and store 1 hex digit
+     mov ax,dx
+     and ax,0fh
+     add ax,30h
+     cmp ax,39h
+     jbe one_dec
+     add ax,7		; change 3A to 41 ('A'), 3B to 'B' etc.
+ 
+ one_dec:
+     mov es:[bx],al
+     dec bx
+     shr dx,cl
+     ret
+ one_dig Endp
+ 
+ _spawn_mks_glob Proc
+     push bp
+     mov bp,sp
+     push si
+     push di
+ 
+     mov ax,gseg		; segment of glob buffer
+     mov dx,ax		; save for making ascii string
+     add ax,200h		; segment of where we'll put the environment
+     mov genv,ax
+ 
+     mov es,ax
+     mov cx,4
+     mov bx,3
+     call one_dig
+     call one_dig
+     call one_dig
+     call one_dig
+     mov es:word ptr [4],3030h	; we know glob buffer starts at para address
+     mov es:word ptr [6],3030h
+     mov es:byte ptr [8],0	; terminate the string
+ 
+     mov ax,@data		; set ES:BX pointing to spawn parameter block
+     mov es,ax
+     lea bx,genv
+ 
+ If @datasize
+     mov ds,[bp+ARG+2]		; segment of program name
+ Endif
+     mov dx,[bp+ARG]		; offset of program name
+ 
+ If MIN_DOS_VER lt 300
+ 	; DOS 2.x is brain-damaged and will clobber all but CS:IP
+     push ds
+     mov exec_ss,ss
+     mov exec_sp,sp
+ Endif
+     mov ax,4b00h		; spawn the glob program
+     int 21h			; we're assuming DOS 3.0+; 2.x trashes regs
+ If MIN_DOS_VER lt 300
+     mov ss,exec_ss		; will delay interrupts til after next instr
+     mov sp,exec_sp		; movs and pops don't change CF
+     pop ds
+ Endif
+     mov ah,0ffh			; assume failure: note doesn't affect carry
+     jc spawn_done		; problem: return MS-DOS error code
+ 
+     mov ah,4dh			; get return code of glob
+     int 21h
+ 
+ spawn_done:	; return code in AX, if spawn failed, AH == 0FFh
+     mov cx,ss
+     mov ds,cx
+ 
+     pop di
+     pop si
+     pop bp
+     ret
+ _spawn_mks_glob Endp
+ 
+ ; Catastophe calling glob.exe.  Print message and die
+ 
+ .DATA
+ 
+ gmsg0	db 'glob: not found', 13, 10
+ gmsg1	db 'glob: insufficient space', 13, 10
+ gmsg2	db 'glob: unknown problem', 13, 10
+ gmsg3	db 'glob: arg list too long', 13, 10
+ gmsg4	db 'DOS '
+ 	db (MIN_DOS_VER shr 8) or 30h	; ascii major
+ 	db '.'
+ 	db ((MIN_DOS_VER and 0f0h) shr 4) or 30h ; ascii minor (tens)
+ 	db (MIN_DOS_VER and 0fh) or 30h		 ; ascii minor (units)
+ 	db ' or better required', 13, 10
+ 
+ gmsg	dw gmsg0, gmsg1, gmsg2, gmsg3, gmsg4
+ 	dw gmsg
+ 
+ .CODE
+ 
+     Public _glob_problem
+ _glob_problem Proc
+     push bp
+     mov bp,sp
+     mov bx,[bp+ARG]	; get message index
+ 
+ version_death:
+     shl bx,1		; convert to word index
+     mov dx,[bx].gmsg	; get offset of the message
+     mov cx,[bx+2].gmsg	; get offset of next message
+     sub cx,dx		; bytes in between
+     mov bx,2		; write to stderr
+     mov ah,40h
+     int 21h
+ 
+     mov ax,4c01h	; terminte with return code 1
+     int 21h
+     ; no return
+ _glob_problem Endp
+ 
+ 
+ End
