If handle valid, close file in PSP table before the low-level close +

(perhaps) critical error.
Avoids closing the file twice (and hitting the critical error twice) on
abort/program termination.
Also, close can only return error 6 (DE_INVLDHNDL), not 5 (DE_ACCESS), see RBIL.


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1564 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2011-04-08 18:27:48 +00:00
parent 225237e915
commit 0760d51339

View File

@ -689,7 +689,7 @@ COUNT DosCloseSft(int sft_idx, BOOL commitonly)
*/ */
struct dhdr FAR *dev = sftp->sft_dev; struct dhdr FAR *dev = sftp->sft_dev;
if (BinaryCharIO(&dev, 0, MK_FP(0x0000, 0x0000), C_CLOSE) != SUCCESS) if (BinaryCharIO(&dev, 0, MK_FP(0x0000, 0x0000), C_CLOSE) != SUCCESS)
return DE_ACCESS; return DE_INVLDHNDL;
} }
/* now just drop the count if a device */ /* now just drop the count if a device */
if (!commitonly) if (!commitonly)
@ -717,13 +717,18 @@ COUNT DosCloseSft(int sft_idx, BOOL commitonly)
COUNT DosClose(COUNT hndl) COUNT DosClose(COUNT hndl)
{ {
psp FAR *p = MK_FP(cu_psp, 0); psp FAR *p = MK_FP(cu_psp, 0);
COUNT ret; int sft_idx = get_sft_idx(hndl);
if (FP_OFF(idx_to_sft(sft_idx)) == (size_t) - 1)
return DE_INVLDHNDL;
/* We must close the (valid) file handle before any critical error */
/* may occur, else e.g. ABORT will try to close the file twice, */
/* the second time after stdout is already closed */
p->ps_filetab[hndl] = 0xff;
/* Get the SFT block that contains the SFT */ /* Get the SFT block that contains the SFT */
ret = DosCloseSft(get_sft_idx(hndl), FALSE); return DosCloseSft(sft_idx, FALSE);
if (ret != DE_INVLDHNDL && ret != DE_ACCESS)
p->ps_filetab[hndl] = 0xff;
return ret;
} }
UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc) UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc)