summaryrefslogtreecommitdiffstats
path: root/private/crt32/lowio/dup.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/crt32/lowio/dup.c')
-rw-r--r--private/crt32/lowio/dup.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/private/crt32/lowio/dup.c b/private/crt32/lowio/dup.c
new file mode 100644
index 000000000..1eaa12597
--- /dev/null
+++ b/private/crt32/lowio/dup.c
@@ -0,0 +1,156 @@
+/***
+*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
+* <cruntime.h> 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 <oscalls.h> instead of <doscalls.h>
+* 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 <cruntime.h>
+#include <oscalls.h>
+#include <errno.h>
+#include <os2dll.h>
+#include <io.h>
+#include <msdos.h>
+#include <internal.h>
+#include <stdlib.h>
+
+/***
+*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;
+}