/*** *close.c - close file handle for Windows NT * * Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved. * *Purpose: * defines _close() - close a file handle * *******************************************************************************/ #ifndef _MAC #include #include #include #include #include #include #include #include /*** *int _close(fh) - close a file handle * *Purpose: * Closes the file associated with the file handle fh. * *Entry: * int fh - file handle to close * *Exit: * returns 0 if successful, -1 (and sets errno) if fails * *Exceptions: * *******************************************************************************/ #ifdef _MT /* define normal version that locks/unlocks, validates fh */ int __cdecl _close ( int fh ) { int r; /* return value */ /* validate file handle */ if ( ((unsigned)fh >= (unsigned)_nhandle) || !(_osfile(fh) & FOPEN) ) { /* bad file handle, set errno and abort */ errno = EBADF; _doserrno = 0; return -1; } _lock_fh(fh); /* lock file */ r = _close_lk(fh); _unlock_fh(fh); /* unlock the file */ return r; } /* now define version that doesn't lock/unlock, validate fh */ int __cdecl _close_lk ( int fh ) { DWORD dosretval; #else /* _MT */ /* now define normal version */ int __cdecl _close ( int fh ) { DWORD dosretval; /* validate file handle */ if ( ((unsigned)fh >= (unsigned)_nhandle) || !(_osfile(fh) & FOPEN) ) { /* bad file handle, set errno and abort */ errno = EBADF; _doserrno = 0; /* no o.s. error */ return -1; } #endif /* _MT */ /* * Close the underlying OS file handle. Special cases: * 1. If _get_osfhandle(fh) is INVALID_HANDLE_VALUE, don't try * to actually close it. Just reset the lowio info so the * handle can be reused. The standard handles are setup like * this in Windows app, or a background app. * 2. If fh is STDOUT or STDERR, and if STDOUT and STDERR are * mapped to the same OS file handle, skip the CloseHandle * is skipped (without error). STDOUT and STDERR are the only * handles for which this support is provided. Other handles * are mapped to the same OS file handle only at the * programmer's risk. */ if ( (_get_osfhandle(fh) == (long)INVALID_HANDLE_VALUE) || ( ((fh == 1) || (fh == 2)) && (_get_osfhandle(1) == _get_osfhandle(2)) ) || CloseHandle( (HANDLE)_get_osfhandle(fh) ) ) { dosretval = 0L; } else dosretval = GetLastError(); _free_osfhnd(fh); _osfile(fh) = 0; /* clear file flags */ if (dosretval) { /* OS error */ _dosmaperr(dosretval); return -1; } return 0; /* good return */ } #else /* _MAC */ #include #include #include #include #include #include #include #include /*** *int _close(fh) - close a file handle * *Purpose: * Closes the file associated with the file handle fh. * *Entry: * int fh - file handle to close * *Exit: * returns 0 if successful, -1 (and sets errno) if fails * *Exceptions: * *******************************************************************************/ /* now define normal version */ int __cdecl _close ( int fh ) { ParamBlockRec parm; OSErr osErr = 0; FCBPBRec fcbparm; HParamBlockRec hparm; OSErr osErrFCB = 0; unsigned char strFilename[32]; /* validate file handle */ if ((unsigned)fh >= (unsigned)_nfile || !(_osfile[fh] & FOPEN)) { /* bad file handle, set errno and abort */ errno = EBADF; _macerrno = 0; return -1; } if (!(_osfile[fh] & FDEV)) /* no need to close console */ { if (_osfhnd[fh] == -1 ) { /* an open file with a -1 handle indicates a pseudo open for stdin, stdout, or stderr -- close with no error */ _osfhnd[fh] = 0; /* only allowed to close once */ } else { /* if file is temporary, use the file FCB to get the volume, filename, and parent directory for deletion */ if (_osfileflags[fh] & FTEMP) { fcbparm.ioFCBIndx = 0; fcbparm.ioVRefNum = _osVRefNum[fh]; fcbparm.ioRefNum = _osfhnd[fh]; fcbparm.ioNamePtr = (StringPtr)strFilename; osErrFCB = PBGetFCBInfoSync(&fcbparm); } parm.ioParam.ioRefNum = _osfhnd[fh]; parm.ioParam.ioNamePtr = NULL; osErr = PBCloseSync(&parm); if (osErr) { _dosmaperr(osErr); return -1; } /* file is closed, so if temporary, delete */ if ((_osfileflags[fh] & FTEMP) && !osErrFCB) { memset(&hparm, 0, sizeof(HParamBlockRec)); hparm.fileParam.ioVRefNum = fcbparm.ioFCBVRefNum; hparm.fileParam.ioDirID = fcbparm.ioFCBParID; hparm.fileParam.ioNamePtr = fcbparm.ioNamePtr; PBHDeleteSync(&hparm); } /* flush volume to commit changes */ memset(&parm, 0, sizeof(ParamBlockRec)); parm.ioParam.ioVRefNum = _osVRefNum[fh]; osErr = PBFlushVolSync(&parm); } } _osfile[fh] = 0; /* clear file flags */ _osfileflags[fh] = 0; if (osErr) { _dosmaperr(osErr); return -1; } return 0; /* good return */ } #endif /* _MAC */