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/moredos.asm.old Sun Feb 23 08:48:16 1992 --- msdos/moredos.asm Thu Nov 14 08:56:36 1991 *************** *** 0 **** --- 1,235 ---- + ; Various stuff that has to be in assembly langauge because the + ; C library under DOS won't do what we need. + + + ; Copyright (c) 1990 Leonard Reed. + ; Author: ...!gatech!holos0!lbr + + ; 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 + .data + + extrn __psp:word ; our PSP, set by C library startup code + extrn _errno:word ; C library Unix-like error code + extrn __osversion:word ; MS-DOS version, set by C library startup + + SFT_block Struc ; header for s system file table block + d_next dd ? ; pointer to next block, or ????:ffffh for end + d_count dw ? ; num of system file table entries in this block + SFT_block Ends + + .code + + ; struct sft far * dos_sys_file(int handle); + + ; Return a pointer to the system file table entry for a given file handle. + ; This routine returns zero for success and NULL (with errno set) for failure. + ; We resolve the file handle to a system file table entry and + ; change the value there. This requires knowledge of DOS's internals + ; that is widely know but not "documented" by Microsoft. + ; Refer to _The Waite Group's MS-DOS Developer's Guide_, 2nd edition, + ; Howard Sams & Co., pp. 210-217. + + Public _dos_sys_file + _dos_sys_file Proc + push bp + mov bp,sp + push di + + mov es,__psp ; our program segment prefix + mov ax,es:[32h] ; size of our job file table (max num of handles) + + mov bx,[bp+ARG] ; get the file handle passed to this routine + + cmp bx,ax + jae bad_handle ; bad handle, possibly 0ffffh from failed open() + + les di,es:[34h] ; address of the job file table (typically just es:18h) + mov bl,es:[bx+di] ; get system file table entry for this handle + cmp bl,0ffh ; is the entry used? + je bad_handle + + mov dl,bl ; save the system file table entry momentarily in DX + sub dh,dh + + mov ah,52h ; "undocumented" call to get ptr to list of lists + int 21h ; pointer returned in ES:BX + + les di,es:[bx+4] ; get pointer to first SFT_block + mov ax,dx ; index of entry sought + + ; Now have ES:DI ==> first SFT_BLOCK + ; AL == AX == system file table number for the given handle + + sub bx,bx + + new_block: + add bx,es:[di].d_count ; set BX to first sys file number in next block + cmp ax,bx ; is the sought number in this block? + jl found_it + + cmp di,0ffffh ; at end of chain ? + je bad_handle ; didn't find it: really is worse than EBADF! + les di,es:[di].d_next ; pointer to next block + jmp new_block + + found_it: + sub bx,es:[di].d_count ; sys file number of 1st SFN this block + sub ax,bx ; offset of sought sys file number's entry + mov bx,__osversion ; test DOS version + cmp bl,4 + mov bl,3bh ; assume 4.x/5.x structure size + jae its_dos_4 + mov bl,35h ; before 4.0, structures were smaller + + its_dos_4: + mul bl ; set AX to offset (almost) into block + add ax,size SFT_block ; add the header size + add ax,di ; add the offset of the block + mov dx,es ; now DX:AX points to the sought entry + jmp short get_out + + bad_handle: + mov _errno,9 ; EBADF + sub ax,ax + mov dx,ax + + get_out: + pop di + pop bp + ret + _dos_sys_file Endp + + ; Routine to return maximum number of files, similar to Unix NOFILE. + ; Ususally under dos this is 20, but it can be changed. + + ; int dos_get_nofiles(void); + + Public _dos_get_nofiles + _dos_get_nofiles Proc + mov es,__psp ; our program segment prefix + mov ax,es:[32h] ; size of our job file table (max num of handles) + ret + _dos_get_nofiles Endp + + ; Routine to return pointer to the file table that maps handles + ; to system files. Usually in PSP at offset 18h, but can be remapped. + + ; unsigned char far * dos_get_sft_map(void); + + Public _dos_get_sft_map + _dos_get_sft_map Proc + mov es,__psp ; our program segment prefix + les ax,es:[34h] ; address of the job file table (typically just es:18h) + mov dx,es ; return pointer in DX:AX + ret + _dos_get_sft_map Endp + + ; Duplicate a handle bypassing the C library + ; Used by spawn logic to control inheritance without confusing the + ; C library about O_BINARY/O_TEXT, I/O modes, etc. + + ; int dos_dup(int); + + Public _dos_dup + _dos_dup Proc + push bp + mov bp,sp + + mov bx,[bp+ARG] + mov ah,45h + int 21h + jc dup_failure + + pop bp + ret + + dup_failure: ; also jumped to from _dos_dup2 + cmp ax,6h ; Is DOS trying to say EBADF (bad handle?) + je dup_bad_handle + mov ax,24 ; assume EMFILE, out of files or handles + jmp short dup_error_exit + + dup_bad_handle: + mov ax,9 ; EBADF, bad file handle + + dup_error_exit: + mov _errno,ax + mov ax,-1 + pop bp + ret + _dos_dup Endp + + ; Duplicate a handle to a specific new handle, bypassing the C library. + ; Used by spawn logic to control inheritance without confusing the + ; C library about O_BINARY/O_TEXT, I/O modes, etc. + + ; int dos_dup2(int current, int duplicate); + + Public _dos_dup2 + _dos_dup2 Proc + push bp + mov bp,sp + + mov bx,[bp+ARG] + mov cx,[bp+ARG+2] + mov ah,46h + int 21h + jc dup_failure ; see _dos_dup code + + pop bp + ret + _dos_dup2 Endp + + ; Close a handle without telling the C runtime library. + ; Used by spawn logic to control inheritance without confusing the + ; C library about O_BINARY/O_TEXT, I/O modes, etc. + + ; int dos_close(int handle); + + Public _dos_close + _dos_close Proc + push bp + mov bp,sp + + mov bx,[bp+ARG] + mov ah,3eh + int 21h + mov ax,0 ; no error (note this doesn't affect CF) + jnc closed_it + mov _errno,9 ; EBADF (this is a guess, we could inspect AX) + mov ax,-1 + + closed_it: + pop bp + ret + _dos_close Endp + + End