/*** *dup.c - OS/2 duplicate file handles * * Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved. * *Purpose: * defines _dup() - duplicate file handles * *Revision History: * 06-09-89 PHG Module created, based on asm version * 03-12-90 GJF Made calling type _CALLTYPE2 (for now), added #include * and fixed the copyright. Also, cleaned up * the formatting a bit. * 04-03-90 GJF Now _CALLTYPE1. * 07-24-90 SBM Removed '32' from API names * 08-14-90 SBM Compiles cleanly with -W3 * 09-28-90 GJF New-style function declarator. * 12-04-90 GJF Appended Win32 version onto the source with #ifdef-s. * It is enough different that there is little point in * trying to more closely merge the two versions. * 12-04-90 SRW Changed to include instead of * 12-06-90 SRW Changed to use _osfile and _osfhnd instead of _osfinfo * 01-16-91 GJF ANSI naming. * 02-07-91 SRW Changed to call _get_osfhandle [_WIN32_] * 02-18-91 SRW Changed to call _free_osfhnd [_WIN32_] * 02-25-91 SRW Renamed _get_free_osfhnd to be _alloc_osfhnd [_WIN32_] * 02-13-92 GJF Replaced _nfile by _nhandle for Win32. * 09-03-92 GJF Added explicit check for unopened handles [_WIN32_]. * *******************************************************************************/ #include #include #include #include #include #include #include #include /*** *int _dup(fh) - duplicate a file handle * *Purpose: * Assigns another file handle to the file associated with the * handle fh. The next available file handle is assigned. * * Multi-thread: Be sure not to hold two file handle locks * at the same time! * *Entry: * int fh - file handle to duplicate * *Exit: * returns new file handle if successful * returns -1 (and sets errno) if fails * *Exceptions: * *******************************************************************************/ int _CALLTYPE1 _dup ( int fh ) { ULONG dosretval; /* OS/2 return value */ int newfh; /* variable for new file handle */ char fileinfo; /* _osfile info for file */ /* validate file handle */ #ifdef _WIN32_ if ( ((unsigned)fh >= (unsigned)_nhandle) || !(_osfile[fh] & FOPEN) ) { #else if ((unsigned)fh >= (unsigned)_nfile) { #endif errno = EBADF; _doserrno = 0; /* no OS/2 error */ return -1; } _lock_fh(fh); /* lock file handle */ fileinfo = _osfile[fh]; /* get file info for file */ /* create duplicate handle */ #ifdef _CRUISER_ newfh = -1; /* ask for new handle */ dosretval = DOSDUPHANDLE(fh, &newfh); /* validate range of new handle */ if (dosretval == 0 && (unsigned)newfh >= (unsigned)_nfile) { /* file handle is not in range -- close it and return error */ _doserrno = DOSCLOSE(newfh); errno = EMFILE; _unlock_fh(fh); return -1; } #else /* ndef _CRUISER_ */ #ifdef _WIN32_ { long new_osfhandle; if ( (newfh = _alloc_osfhnd()) == -1 ) { errno = EMFILE; /* too many files error */ _doserrno = 0L; /* not an OS error */ _unlock_fh(fh); return -1; /* return error to caller */ } /* * duplicate the file handle */ if ( !(DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fh), GetCurrentProcess(), (PHANDLE)&new_osfhandle, 0L, TRUE, DUPLICATE_SAME_ACCESS)) ) { dosretval = GetLastError(); } else { _set_osfhnd(newfh, new_osfhandle); dosretval = 0; } } _unlock_fh(newfh); #else /* ndef _WIN32_ */ #error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! #endif /* _WIN32_ */ #endif /* _CRUISER_ */ _unlock_fh(fh); /* unlock file handle */ if (dosretval) { /* OS/2 error -- map and return */ _dosmaperr(dosretval); return -1; } /* copy _osfile info */ _osfile[newfh] = fileinfo; return newfh; }