home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
crt
/
src
/
close.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-17
|
7KB
|
246 lines
/***
*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 <cruntime.h>
#include <oscalls.h>
#include <io.h>
#include <mtdll.h>
#include <errno.h>
#include <stdlib.h>
#include <msdos.h>
#include <internal.h>
/***
*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 <cruntime.h>
#include <msdos.h>
#include <memory.h>
#include <errno.h>
#include <stdlib.h>
#include <internal.h>
#include <macos\files.h>
#include <macos\errors.h>
/***
*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 */