summaryrefslogtreecommitdiffstats
path: root/private/crt32/lowio
diff options
context:
space:
mode:
Diffstat (limited to 'private/crt32/lowio')
-rw-r--r--private/crt32/lowio/cgets.c129
-rw-r--r--private/crt32/lowio/chsize.c231
-rw-r--r--private/crt32/lowio/close.c135
-rw-r--r--private/crt32/lowio/commit.c115
-rw-r--r--private/crt32/lowio/cputs.c100
-rw-r--r--private/crt32/lowio/creat.c52
-rw-r--r--private/crt32/lowio/dup.c156
-rw-r--r--private/crt32/lowio/dup2.c200
-rw-r--r--private/crt32/lowio/eof.c90
-rw-r--r--private/crt32/lowio/flength.c84
-rw-r--r--private/crt32/lowio/fstat.c352
-rw-r--r--private/crt32/lowio/getch.c672
-rw-r--r--private/crt32/lowio/i386/_initcon.asm17
-rw-r--r--private/crt32/lowio/i386/cinitcon.asm99
-rw-r--r--private/crt32/lowio/initcon.c113
-rw-r--r--private/crt32/lowio/ioinit.c242
-rw-r--r--private/crt32/lowio/isatty.c62
-rw-r--r--private/crt32/lowio/locking.c187
-rw-r--r--private/crt32/lowio/lseek.c187
-rw-r--r--private/crt32/lowio/makefile6
-rw-r--r--private/crt32/lowio/mktemp.c115
-rw-r--r--private/crt32/lowio/open.c590
-rw-r--r--private/crt32/lowio/osfinfo.c319
-rw-r--r--private/crt32/lowio/pipe.c180
-rw-r--r--private/crt32/lowio/ppc/cinitcon.s53
-rw-r--r--private/crt32/lowio/putch.c129
-rw-r--r--private/crt32/lowio/read.c349
-rw-r--r--private/crt32/lowio/setmode.c155
-rw-r--r--private/crt32/lowio/sources62
-rw-r--r--private/crt32/lowio/tell.c46
-rw-r--r--private/crt32/lowio/txtmode.c19
-rw-r--r--private/crt32/lowio/write.c324
32 files changed, 5570 insertions, 0 deletions
diff --git a/private/crt32/lowio/cgets.c b/private/crt32/lowio/cgets.c
new file mode 100644
index 000000000..ad2a7f1c0
--- /dev/null
+++ b/private/crt32/lowio/cgets.c
@@ -0,0 +1,129 @@
+/***
+*cgets.c - buffered keyboard input
+*
+* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _cgets() - read a string directly from console
+*
+*Revision History:
+* 06-09-89 PHG Module created, based on asm version
+* 03-12-90 GJF Made calling type _CALLTYPE1, added #include
+* <cruntime.h> and fixed copyright. Also, cleaned
+* up the formatting a bit.
+* 06-05-90 SBM Recoded as pure 32-bit, using new file handle state bits
+* 07-24-90 SBM Removed '32' from API names
+* 08-13-90 SBM Compiles cleanly with -W3
+* 09-28-90 GJF New-style function declarator.
+* 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
+* 12-13-90 GJF Fixed a couple of bugs.
+* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
+* 01-16-91 GJF ANSI naming.
+* 01-25-91 SRW Get/SetConsoleMode parameters changed (_WIN32_)
+* 02-18-91 SRW Get/SetConsoleMode required read/write access (_WIN32_)
+* 02-19-91 SRW Adapt to OpenFile/CreateFile changes (_WIN32_)
+* 02-25-91 MHL Adapt to ReadFile/WriteFile changes (_WIN32_)
+* 07-26-91 GJF Took out init. stuff and cleaned up the error
+* handling [_WIN32_].
+* 04-19-93 GJF Use ReadConsole instead of ReadFile.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <os2dll.h>
+#include <conio.h>
+#include <stdlib.h>
+
+/*
+ * mask to clear the bits required to be 0 in the handle state passed to
+ * DOSSETFHSTATE.
+ */
+#define FHSTATEMASK 0xffd07888
+
+/*
+ * declaration for console handle
+ */
+
+extern int _coninpfh;
+
+/***
+*char *_cgets(string) - read string from console
+*
+*Purpose:
+* Reads a string from the console via DOSREAD on a cooked console
+* handle. string[0] must contain the maximum length of the
+* string. Returns pointer to str[2].
+*
+* NOTE: _cgets() does NOT check the pushback character buffer (i.e.,
+* _chbuf). Thus, _cgets() will not return any character that is
+* pushed back by the _ungetch() call.
+*
+*Entry:
+* char *string - place to store read string, str[0] = max length.
+*
+*Exit:
+* returns pointer to str[2], where the string starts.
+* returns NULL if error occurs
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+char * __cdecl _cgets (
+ char *string
+ )
+{
+ ULONG oldstate;
+ ULONG num_read;
+ char *result;
+
+ _mlock(_CONIO_LOCK); /* lock the console */
+
+ string[1] = 0; /* no chars read yet */
+ result = &string[2];
+
+ if ( _coninpfh == -1 ) {
+ _munlock(_CONIO_LOCK); /* unlock the console */
+ return(NULL); /* return failure */
+ }
+
+ GetConsoleMode( (HANDLE)_coninpfh, &oldstate );
+ SetConsoleMode( (HANDLE)_coninpfh, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT |
+ ENABLE_ECHO_INPUT );
+
+ if ( !ReadConsole( (HANDLE)_coninpfh,
+ (LPVOID)result,
+ (unsigned char)string[0],
+ &num_read,
+ NULL )
+ )
+ result = NULL;
+
+ if ( result != NULL ) {
+
+ /* set length of string and null terminate it */
+
+ if (string[num_read] == '\r') {
+ string[1] = (char)(num_read - 2);
+ string[num_read] = '\0';
+ } else if ( (num_read == (ULONG)(unsigned char)string[0]) &&
+ (string[num_read + 1] == '\r') ) {
+ /* special case 1 - \r\n straddles the boundary */
+ string[1] = (char)(num_read -1);
+ string[1 + num_read] = '\0';
+ } else if ( (num_read == 1) && (string[2] == '\n') ) {
+ /* special case 2 - read a single '\n'*/
+ string[1] = string[2] = '\0';
+ } else {
+ string[1] = (char)num_read;
+ string[2 + num_read] = '\0';
+ }
+ }
+
+ SetConsoleMode( (HANDLE)_coninpfh, oldstate );
+
+ _munlock(_CONIO_LOCK); /* unlock the console */
+
+ return result;
+}
diff --git a/private/crt32/lowio/chsize.c b/private/crt32/lowio/chsize.c
new file mode 100644
index 000000000..d25278023
--- /dev/null
+++ b/private/crt32/lowio/chsize.c
@@ -0,0 +1,231 @@
+/***
+*chsize.c - OS/2 change size of a file
+*
+* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* contains the _chsize() function - changes the size of a file.
+*
+*Revision History:
+* 03-13-84 RN initial version
+* 05-17-86 SKS ported to OS/2
+* 07-07-87 JCR Added (_doserrno == 5) check that is in DOS 3.2 version
+* 10-29-87 JCR Multi-thread support; also, re-wrote for efficiency
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 05-25-88 PHG Merged DLL and normal versions
+* 10-03-88 GJF Changed DOSNEWSIZE to SYSNEWSIZE
+* 10-10-88 GJF Made API names match DOSCALLS.H
+* 04-13-89 JCR New syscall interface
+* 05-25-89 JCR 386 OS/2 calls use '_syscall' calling convention
+* 03-12-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h>, removed #include <register.h> and fixed
+* the copyright. Also, cleaned up the formatting a bit.
+* 04-04-90 GJF Added #include <string.h>, removed #include <dos.h>.
+* 05-21-90 GJF Fixed stack checking pragma syntax.
+* 07-24-90 SBM Replaced <assertm.h> by <assert.h>, removed '32'
+* from API names
+* 09-28-90 GJF New-style function declarator.
+* 12-03-90 GJF Appended Win32 version of the function. It is based
+* on the Cruiser version and probably could be merged
+* in later (much later).
+* 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
+* 12-28-90 SRW Added _CRUISER_ conditional around check_stack pragma
+* 01-16-91 GJF ANSI naming. Also, fixed _chsize_lk parameter decls.
+* 02-07-91 SRW Changed to call _get_osfhandle [_WIN32_]
+* 04-09-91 PNT Added _MAC_ conditional
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+* 05-01-92 GJF Fixed embarrassing bug (didn't work for Win32)!
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <msdos.h>
+#include <io.h>
+#include <string.h>
+#include <oscalls.h>
+#include <internal.h>
+#include <os2dll.h>
+
+#ifdef _CRUISER_
+#pragma check_stack(on) /* turn stack probes on */
+#endif /* ndef _CRUISER_ */
+
+/***
+*int _chsize(filedes, size) - change size of a file
+*
+*Purpose:
+* Change file size. Assume file is open for writing, or we can't do it.
+* The DOS way to do this is to go to the right spot and write 0 bytes. The
+* Xenix way to do this is to make a system call. We write '\0' bytes because
+* DOS won't do this for you if you lseek beyond eof, though Xenix will.
+*
+*Entry:
+* int filedes - file handle to change size of
+* long size - new size of file
+*
+*Exit:
+* return 0 if successful
+* returns -1 and sets errno if fails
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+#ifdef MTHREAD
+
+/* define normal version that locks/unlocks, validates fh */
+
+int _CALLTYPE1 _chsize (
+ REG1 int filedes,
+ long size
+ )
+{
+ int r; /* return value */
+
+#ifdef _WIN32_
+ if ( (unsigned)filedes >= (unsigned)_nhandle ) {
+#else
+ if (filedes < 0 || filedes >= _nfile) {
+#endif
+ errno = EBADF;
+ return(-1);
+ }
+ _lock_fh(filedes);
+ r = _chsize_lk(filedes,size);
+ _unlock_fh(filedes);
+
+ return r;
+}
+
+/* now define version that doesn't lock/unlock, validate fh */
+int _CALLTYPE1 _chsize_lk (
+ REG1 int filedes,
+ long size
+ )
+{
+ long filend;
+ long extend;
+ long place;
+ int cnt;
+ char blanks[BUFSIZ];
+ REG2 char *bl = blanks;
+ int oldmode;
+ int retval = 0; /* assume good return */
+
+#else
+
+/* now define normal version */
+
+int _CALLTYPE1 _chsize (
+ REG1 int filedes,
+ long size
+ )
+{
+ long filend;
+ long extend;
+ long place;
+ int cnt;
+ char blanks[BUFSIZ];
+ REG2 char *bl = blanks;
+ int oldmode;
+ int retval = 0; /* assume good return */
+
+#ifdef _WIN32_
+ if ( (unsigned)filedes >= (unsigned)_nhandle ) {
+#else
+ if (filedes < 0 || filedes >= _nfile) {
+#endif
+ errno = EBADF;
+ return(-1);
+ }
+
+#endif
+ assert(size >= 0);
+
+ /* Get current file position and seek to end */
+ if ( ((place = _lseek_lk(filedes, 0L, SEEK_CUR)) == -1L) ||
+ ((filend = _lseek_lk(filedes, 0L, SEEK_END)) == -1L) )
+ return -1;
+
+ extend = size - filend;
+
+ /* Grow or shrink the file as necessary */
+
+ if (extend > 0L) {
+
+ /* extending the file */
+
+ memset(bl, '\0', BUFSIZ);
+ oldmode = _setmode_lk(filedes, _O_BINARY);
+
+ /* pad out with nulls */
+ do {
+ cnt = (extend >= (long)BUFSIZ ) ? BUFSIZ : (int)extend;
+ if ( ( cnt = _write_lk( filedes, bl, (extend >=
+ (long)BUFSIZ ) ? BUFSIZ : (int)extend)) == -1 ) {
+ /* Error on write */
+ if (_doserrno == ERROR_ACCESS_DENIED)
+ errno = EACCES;
+ retval = cnt;
+ break; /* leave write loop */
+ }
+ }
+ while ((extend -= (long)cnt) > 0L);
+
+ _setmode_lk(filedes, oldmode);
+ /* retval set correctly */
+ }
+
+ else if (extend < 0L) {
+ /* shortening the file */
+#ifdef _CRUISER_
+
+ retval = ( DOSSETFILESIZE(filedes, size) ? -1 : 0 );
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+ /*
+ * Set file pointer to new eof...and truncate it there.
+ */
+ _lseek_lk(filedes, size, SEEK_SET);
+
+ if ( (retval = SetEndOfFile((HANDLE)_get_osfhandle(filedes)) ?
+ 0 : -1) == -1 ) {
+ errno = EACCES;
+ _doserrno = GetLastError();
+ }
+
+#else /* ndef _WIN32_ */
+
+#ifdef _MAC_
+
+ TBD();
+
+#else /* ndef _MAC_ */
+
+#error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED!
+
+#endif /* _MAC_ */
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+ }
+
+ /* else */
+ /* no file change needed */
+ /* retval = 0; */
+
+
+/* Common return code */
+
+ _lseek_lk(filedes, place, SEEK_SET);
+ return retval;
+}
diff --git a/private/crt32/lowio/close.c b/private/crt32/lowio/close.c
new file mode 100644
index 000000000..c96a8a4b9
--- /dev/null
+++ b/private/crt32/lowio/close.c
@@ -0,0 +1,135 @@
+/***
+*close.c - close file handle for Windows NT
+*
+* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _close() - close a file handle
+*
+*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_]
+* 04-09-91 PNT Added _MAC_ conditional
+* 07-17-91 GJF Syntax error in multi-thread build [_WIN32_]
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+* 02-21-92 GJF Removed bogus _unlock_fh() call.
+* 03-22-93 GJF Check for STDOUT and STDERR being mapped to the same
+* OS file handle. Also, purged Cruiser support.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <io.h>
+#include <os2dll.h>
+#include <errno.h>
+#include <stdlib.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 MTHREAD
+
+/* define normal version that locks/unlocks, validates fh */
+
+int _CRTAPI1 _close (
+ int fh
+ )
+{
+ int r; /* return value */
+
+ /* validate file handle */
+ if ( (unsigned)fh >= (unsigned)_nhandle ) {
+ /* bad file handle, set errno and abort */
+ errno = EBADF;
+ _doserrno = 0; /* no OS/2 error */
+ 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 _CRTAPI1 _close_lk (
+ int fh
+ )
+{
+ DWORD dosretval;
+
+#else
+
+/* now define normal version */
+int _CRTAPI1 _close (
+ int fh
+ )
+{
+ DWORD dosretval;
+
+ /* validate file handle */
+ if ( (unsigned)fh >= (unsigned)_nhandle ) {
+ /* bad file handle, set errno and abort */
+ errno = EBADF;
+ _doserrno = 0; /* no OS/2 error */
+ return -1;
+ }
+#endif
+ /*
+ * Close the underlying OS file handle. Note that if fh is STDOUT
+ * or STDERR, and if STDOUT and STDERR are mapped to the same OS
+ * file handle, the close 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 ( ( ((fh == 1) || (fh == 2)) &&
+ (_get_osfhandle(1) == _get_osfhandle(2)) ) ||
+ CloseHandle( (HANDLE)_get_osfhandle(fh) ) )
+ {
+
+ dosretval = 0L;
+ }
+ else
+ dosretval = GetLastError();
+
+ _free_osfhnd(fh);
+
+ if (dosretval) {
+ /* OS error */
+ _dosmaperr(dosretval);
+ return -1;
+ }
+ _osfile[fh] = 0; /* clear file flags */
+
+ return 0; /* good return */
+}
diff --git a/private/crt32/lowio/commit.c b/private/crt32/lowio/commit.c
new file mode 100644
index 000000000..1393907f4
--- /dev/null
+++ b/private/crt32/lowio/commit.c
@@ -0,0 +1,115 @@
+/***
+*commit.c - flush buffer to disk
+*
+* Copyright (c) 1990-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* contains _commit() - flush buffer to disk
+*
+*Revision History:
+* 05-25-90 SBM initial version
+* 07-24-90 SBM Removed '32' from API names
+* 09-28-90 GJF New-style function declarator.
+* 12-03-90 GJF Appended Win32 version onto the source with #ifdef-s.
+* It is close enough to the Cruiser version that it
+* should be more closely merged with it later on (much
+* later on).
+* 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
+* 02-07-91 SRW Changed to call _get_osfhandle [_WIN32_]
+* 04-09-91 PNT Added _MAC_ conditional
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h> /* for RESETBUFFER */
+#include <errno.h>
+#include <io.h>
+#include <internal.h>
+#include <msdos.h> /* for FOPEN */
+#include <os2dll.h>
+#include <stdlib.h> /* for _doserrno */
+
+/***
+*int _commit(filedes) - flush buffer to disk
+*
+*Purpose:
+* Flushes cache buffers for the specified file handle to disk
+*
+*Entry:
+* int filedes - file handle of file
+/*
+*Exit:
+* returns success code
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _commit (
+ REG1 int filedes
+ )
+{
+ REG2 int retval;
+
+ /* if filedes out of range, complain */
+#ifdef _WIN32_
+ if ( (unsigned)filedes >= (unsigned)_nhandle ) {
+#else
+ if (filedes < 0 || filedes >= _nfile) {
+#endif
+ errno = EBADF;
+ return (-1);
+ }
+
+ _lock_fh(filedes);
+
+ /* if filedes open, try to commit, else fall through to bad */
+ if (_osfile[filedes] & FOPEN) {
+
+#ifdef _CRUISER_
+
+ retval = DOSRESETBUFFER(filedes);
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ if ( !FlushFileBuffers((HANDLE)_get_osfhandle(filedes)) ) {
+ retval = GetLastError();
+ } else {
+ retval = 0; /* return success */
+ }
+#else /* ndef _WIN32_ */
+
+#ifdef _MAC_
+
+ TBD();
+
+#else /* ndef _MAC_ */
+
+#error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED!
+
+#endif /* _MAC_ */
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+ /* map the OS return code to C errno value and return code */
+ if (retval == 0) {
+ goto good;
+ } else {
+ _doserrno = retval;
+ goto bad;
+ }
+
+ }
+
+bad :
+ errno = EBADF;
+ retval = -1;
+good :
+ _unlock_fh(filedes);
+ return (retval);
+}
diff --git a/private/crt32/lowio/cputs.c b/private/crt32/lowio/cputs.c
new file mode 100644
index 000000000..cc19b79a3
--- /dev/null
+++ b/private/crt32/lowio/cputs.c
@@ -0,0 +1,100 @@
+/***
+*cputs.c - direct console output
+*
+* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _cputs() - write string directly to console
+*
+*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-10-90 GJF Now _CALLTYPE1.
+* 06-05-90 SBM Recoded as pure 32-bit, using new file handle state bits
+* 07-24-90 SBM Removed '32' from API names
+* 09-28-90 GJF New-style function declarator.
+* 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
+* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
+* 01-16-91 GJF ANSI naming.
+* 02-19-91 SRW Adapt to OpenFile/CreateFile changes (_WIN32_)
+* 02-25-91 MHL Adapt to ReadFile/WriteFile changes (_WIN32_)
+* 07-26-91 GJF Took out init. stuff and cleaned up the error
+* handling [_WIN32_].
+* 04-19-93 GJF Use WriteConsole instead of WriteFile.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <os2dll.h>
+#include <conio.h>
+#include <stdio.h>
+#include <string.h>
+
+/*
+ * declaration for console handle
+ */
+extern int _confh;
+
+/***
+*int _cputs(string) - put a string to the console
+*
+*Purpose:
+* Writes the string directly to the console. No newline
+* is appended.
+*
+*Entry:
+* char *string - string to write
+*
+*Exit:
+* Good return = 0
+* Error return = !0
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CRTAPI1 _cputs (
+ const char *string
+ )
+{
+ ULONG num_written;
+ int error = 0; /* error occurred? */
+
+ _mlock(_CONIO_LOCK); /* acquire console lock */
+
+ /* write string to console file handle */
+
+#ifdef _CRUISER_
+
+ if (DOSWRITE(_confh, (char*)string, strlen(string), &num_written)) {
+ /* OS/2 error, return error indicator */
+ error = -1;
+ }
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ if ( (_confh == -1) || !WriteConsole( (HANDLE)_confh,
+ (LPVOID)string,
+ strlen(string),
+ &num_written,
+ NULL )
+ )
+ /* return error indicator */
+ error = -1;
+
+#else /* ndef _WIN32_ */
+
+#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+ _munlock(_CONIO_LOCK); /* release console lock */
+
+ return error;
+}
diff --git a/private/crt32/lowio/creat.c b/private/crt32/lowio/creat.c
new file mode 100644
index 000000000..fe1437989
--- /dev/null
+++ b/private/crt32/lowio/creat.c
@@ -0,0 +1,52 @@
+/***
+*creat.c - create a new file or truncate existing file
+*
+* Copyright (c) 1989-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _creat() - create new file
+*
+*Revision History:
+* 06-08-89 PHG Module created, based on asm version
+* 03-12-90 GJF Made calling type _CALLTYPE1, added #include
+* <cruntime.h>, fixed compiler warning and fixed the
+* copyright. Also, cleaned up the formatting a bit.
+* 09-28-90 GJF New-style function declarator.
+* 01-16-91 GJF ANSI naming.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <io.h>
+#include <fcntl.h>
+
+/***
+*int _creat(path, pmode) - create a new file
+*
+*Purpose:
+* If file specified does not exist, _creat creates a new file
+* with the given permission setting and opens it for writing.
+* If the file already exists and its permission allows writing,
+* _creat truncates it to 0 length and open it for writing.
+* The only Xenix mode bit supprted by DOS is user write (S_IWRITE).
+*
+*Entry:
+* char *path - filename to create
+* int pmode - permission mode setting for new file
+*
+*Exit:
+* returns handle for created file
+* returns -1 and sets errno if fails.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _creat (
+ const char *path,
+ int pmode
+ )
+{
+ /* creat is just the same as open... */
+ return _open(path, _O_CREAT + _O_TRUNC + _O_RDWR, pmode);
+}
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;
+}
diff --git a/private/crt32/lowio/dup2.c b/private/crt32/lowio/dup2.c
new file mode 100644
index 000000000..dfa6724ec
--- /dev/null
+++ b/private/crt32/lowio/dup2.c
@@ -0,0 +1,200 @@
+/***
+*dup2.c - Duplicate file handles
+*
+* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _dup2() - 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-04-92 GJF Check for unopened fh1 and gracefully handle fh1 ==
+* fh2.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <io.h>
+#include <oscalls.h>
+#include <msdos.h>
+#include <os2dll.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <internal.h>
+
+/***
+*int _dup2(fh1, fh2) - force handle 2 to refer to handle 1
+*
+*Purpose:
+* Forces file handle 2 to refer to the same file as file
+* handle 1. If file handle 2 referred to an open file, that file
+* is closed.
+*
+* Multi-thread: We must hold 2 lowio locks at the same time
+* to ensure multi-thread integrity. In order to prevent deadlock,
+* we always get the lower file handle lock first. Order of unlocking
+* does not matter. If you modify this routine, make sure you don't
+* cause any deadlocks! Scary stuff, kids!!
+*
+*Entry:
+* int fh1 - file handle to duplicate
+* int fh2 - file handle to assign to file handle 1
+*
+*Exit:
+* returns 0 if successful, -1 (and sets errno) if fails.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _dup2 (
+ int fh1,
+ int fh2
+ )
+{
+ ULONG dosretval; /* OS/2 return code */
+
+ /* validate file handles */
+#ifdef _WIN32_
+ if ( ((unsigned)fh1 >= (unsigned)_nhandle) ||
+ ((unsigned)fh2 >= (unsigned)_nhandle) ) {
+#else
+ if ((unsigned)fh1 >= (unsigned)_nfile ||
+ (unsigned)fh2 >= (unsigned)_nfile ) {
+#endif
+ /* handle out of range */
+ errno = EBADF;
+ _doserrno = 0; /* not an OS error */
+ return -1;
+ }
+
+#ifdef MTHREAD
+ /* get the two file handle locks; in order to prevent deadlock,
+ get the lowest handle lock first. */
+ if ( fh1 < fh2 ) {
+ _lock_fh(fh1);
+ _lock_fh(fh2);
+ }
+ else if ( fh1 > fh2 ) {
+ _lock_fh(fh2);
+ _lock_fh(fh1);
+ }
+#endif
+
+ /*
+ * Take care of case of equal handles.
+ */
+ if ( fh1 == fh2 ) {
+ /*
+ * Two handles are the same. Return success or failure
+ * depending on whether or not the handle is open. This is
+ * conformance with the POSIX specification for dup2().
+ */
+ if ( _osfile[fh1] & FOPEN )
+ return 0;
+ else
+ return -1;
+ }
+
+ /*
+ * Take care of case of unopened source handle.
+ */
+ if ( !(_osfile[fh1] & FOPEN) ) {
+ /*
+ * Source handle isn't open, release locks and bail out with
+ * an error. Note that the DuplicateHandle API will not detect
+ * this error since it implies that _osfhnd[fh1] ==
+ * INVALID_HANDLE_VALUE, and this is a legal HANDLE value (it's
+ * the HANDLE for the current process).
+ */
+ _unlock_fh(fh1);
+ _unlock_fh(fh2);
+ errno = EBADF;
+ _doserrno = 0; /* not an OS error */
+ return -1;
+ }
+
+
+ /*
+ * if fh2 is open, close it.
+ */
+ if ( _osfile[fh2] & FOPEN )
+ /*
+ * close the handle. ignore the possibility of an error - an
+ * error simply means that an OS handle value may remain bound
+ * for the duration of the process. Use _close_lk as we
+ * already own lock
+ */
+ (void) _close_lk(fh2);
+
+
+ /* Duplicate source file onto target file */
+#ifdef _CRUISER_
+
+ dosretval = DOSDUPHANDLE(fh1, &fh2);
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ {
+ long new_osfhandle;
+
+ if ( !(DuplicateHandle(GetCurrentProcess(),
+ (HANDLE)_get_osfhandle(fh1),
+ GetCurrentProcess(),
+ (PHANDLE)&new_osfhandle,
+ 0L,
+ TRUE,
+ DUPLICATE_SAME_ACCESS)
+ ) ) {
+
+ dosretval = GetLastError();
+ } else {
+ _set_osfhnd(fh2, new_osfhandle);
+ dosretval = 0;
+ }
+ }
+
+
+#else /* ndef _WIN32_ */
+
+#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+ if (dosretval) {
+ _dosmaperr(dosretval);
+ _unlock_fh(fh1);
+ _unlock_fh(fh2);
+ return -1;
+ }
+
+ /* copy _osfile information */
+ _osfile[fh2] = _osfile[fh1];
+
+ /* unlock file handles */
+ _unlock_fh(fh1);
+ _unlock_fh(fh2);
+
+ return 0;
+}
diff --git a/private/crt32/lowio/eof.c b/private/crt32/lowio/eof.c
new file mode 100644
index 000000000..e4e2f7a2c
--- /dev/null
+++ b/private/crt32/lowio/eof.c
@@ -0,0 +1,90 @@
+/***
+*eof.c - test a handle for end of file
+*
+* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _eof() - determine if a file is at eof
+*
+*Revision History:
+* 09-07-83 RN initial version
+* 10-28-87 JCR Multi-thread support
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 05-25-88 PHG DLL replaces normal version
+* 07-11-88 JCR Added REG allocation to declarations
+* 03-12-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h>, removed #include <register.h> and fixed
+* the copyright. Also, cleaned up the formatting a bit.
+* 09-28-90 GJF New-style function declarator.
+* 12-04-90 GJF Improved range check of file handle.
+* 01-16-91 GJF ANSI naming.
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <io.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <internal.h>
+#include <os2dll.h>
+
+/***
+*int _eof(filedes) - test a file for eof
+*
+*Purpose:
+* see if the file length is the same as the present position. if so, return
+* 1. if not, return 0. if an error occurs, return -1
+*
+*Entry:
+* int filedes - handle of file to test
+*
+*Exit:
+* returns 1 if at eof
+* returns 0 if not at eof
+* returns -1 and sets errno if fails
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _eof (
+ REG1 int filedes
+ )
+{
+ long here;
+ long end;
+ REG2 int retval;
+#ifdef _WIN32_
+ if ( (unsigned)filedes >= (unsigned)_nhandle ) {
+#else
+ if ( (unsigned)filedes >= (unsigned)_nfile ) {
+#endif
+ errno = EBADF;
+ _doserrno = 0;
+ return(-1);
+ }
+
+ /* Lock the file */
+ _lock_fh(filedes);
+
+ /* See if the current position equals the end of the file. */
+
+ if ( ((here = _lseek_lk(filedes, 0L, SEEK_CUR)) == -1L)
+ || ((end = _lseek_lk(filedes, 0L, SEEK_END)) == -1L) )
+ retval = -1;
+ else if ( here == end )
+ retval = 1;
+ else {
+ _lseek_lk(filedes, here, SEEK_SET);
+ retval = 0;
+ }
+
+ /* Unlock the file */
+ _unlock_fh(filedes);
+
+ /* Done */
+ return(retval);
+}
diff --git a/private/crt32/lowio/flength.c b/private/crt32/lowio/flength.c
new file mode 100644
index 000000000..9b81ced8c
--- /dev/null
+++ b/private/crt32/lowio/flength.c
@@ -0,0 +1,84 @@
+/***
+*flength.c - find length of a file
+*
+* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _filelength() - find the length of a file
+*
+*Revision History:
+* 10-22-84 RN initial version
+* 10-27-87 JCR Multi-thread support; also, cleaned up code to save
+* an lseek() in some cases.
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 05-25-88 PHG Merged DLL and normal versions
+* 03-12-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h>, removed #include <register.h> and fixed
+* the copyright. Also, cleaned up the formatting a bit.
+* 07-23-90 SBM Removed #include <assertm.h>
+* 09-28-90 GJF New-style function declarator.
+* 12-04-90 GJF Improved range check of file handle. Also, replaced
+* numeric values with symbolic constants for seek
+* methods.
+* 01-16-91 GJF ANSI naming.
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <stdio.h>
+#include <errno.h>
+#include <io.h>
+#include <internal.h>
+#include <os2dll.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+/***
+*long _filelength(filedes) - find length of a file
+*
+*Purpose:
+* Returns the length in bytes of the specified file.
+*
+*Entry:
+* int filedes - handle referring to file to find length of
+*
+*Exit:
+* returns length of file in bytes
+* returns -1L if fails
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+long _CALLTYPE1 _filelength (
+ REG1 int filedes
+ )
+{
+ long length;
+ long here;
+#ifdef _WIN32_
+ if ( (unsigned)filedes >= (unsigned)_nhandle ) {
+#else
+ if ( (unsigned)filedes >= (unsigned)_nfile ) {
+#endif
+ errno = EBADF;
+ _doserrno = 0L; /* not an OS error */
+ return(-1L);
+ }
+
+ _lock_fh(filedes);
+
+ /* Seek to end to get length of file. */
+ if ( (here = _lseek_lk(filedes, 0L, SEEK_CUR)) == -1L )
+ length = -1L; /* return error */
+ else {
+ length = _lseek_lk(filedes, 0L, SEEK_END);
+ if ( here != length )
+ _lseek_lk(filedes, here, SEEK_SET);
+ }
+
+ _unlock_fh(filedes);
+
+ return(length);
+}
diff --git a/private/crt32/lowio/fstat.c b/private/crt32/lowio/fstat.c
new file mode 100644
index 000000000..dcb013203
--- /dev/null
+++ b/private/crt32/lowio/fstat.c
@@ -0,0 +1,352 @@
+/***
+*fstat.c - OS/2 return file status info
+*
+* Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines fstat() - return file status info
+*
+*Revision History:
+* 03-??-84 RLB Module created
+* 05-??-84 DCW Added register variables
+* 05-19-86 SKS Ported to OS/2
+* 05-21-87 SKS Cleaned up declarations and include files
+* 11-01-87 JCR Multi-thread support
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 05-25-88 PHG Merged DLL and normal version
+* 10-03-88 GJF Adapted for new DOSCALLS.H, DOSTYPES.H.
+* 10-04-88 JCR 386: Removed 'far' keyword
+* 10-10-88 GJF Made API names match DOSCALLS.H
+* 11-07-88 GJF Cleanup, now specific to 386
+* 04-13-89 JCR New syscall interface
+* 05-23-89 PHG Added mask to ignore network bit when testing handle
+* type
+* 05-25-89 JCR 386 OS/2 calls use '_syscall' calling convention
+* 03-12-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h>, removed #include <register.h> and fixed
+* the copyright. Also, cleaned up the formatting a bit.
+* 04-04-90 GJF Removed #include <dos.h>.
+* 07-24-90 SBM Removed '32' from API names
+* 08-13-90 SBM Compiles cleanly with -W3
+* 09-28-90 GJF New-style function declarator.
+* 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
+* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
+* 01-21-91 GJF ANSI naming.
+* 04-26-91 SRW Implemented fstat for _WIN32_ and removed level 3
+* warnings.
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+* 05-27-92 SKS File Creation and File Last Access timestamps may be 0
+* on some file systems (e.g. FAT) in which case the
+* File Last Write time should be used instead.
+* 06-04-92 SKS Changed comment that used to say "This is a BUG!"
+* to explain that this value cannot be computed on
+* OS/2 or NT. Only MS-DOS provides this functionality.
+* The drive number is not valid for UNC names.
+* 06-25-92 GJF Use GetFileInformationByHandle API, also cleaned up
+* formatting of Win32 verson [_WIN32_].
+* 08-18-92 SKS Add a call to FileTimeToLocalFileTime
+* as a temporary fix until _dtoxtime takes UTC
+* 08-20-92 GJF Merged two changes above.
+* 12-16-92 GJF Win32 GetFileInformationByHandle API doesn't like
+* device or pipe handles. Use _S_IFIFO for pipes.
+* 04-06-93 GJF Made computation of file times consistent with _stat().
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <msdos.h>
+#include <dostypes.h>
+#include <io.h>
+#include <internal.h>
+#include <stddef.h>
+#include <oscalls.h>
+#include <stdio.h>
+#include <os2dll.h>
+
+#ifndef _CRUISER_
+#include <time.h>
+#endif
+
+#define IO_DEVNBR 0x3f
+
+/***
+*int _fstat(fildes, buf) - fills supplied buffer with status info
+*
+*Purpose:
+* Fills the supplied buffer with status information on the
+* file represented by the specified file designator.
+* WARNING: the dev/rdev fields are zero for files. This is
+* incompatible with DOS 3 version of this routine.
+*
+*Entry:
+* int fildes - file descriptor
+* struct stat *buf - buffer to store result in
+*
+*Exit:
+* fills in buffer pointed to by buf
+* returns 0 if successful
+* returns -1 and sets errno if unsuccessful
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+#ifdef _CRUISER_
+
+int _CRTAPI1 _fstat (
+ REG2 int fildes,
+ REG1 struct _stat *buf
+ )
+{
+
+ long cpos;
+ int isdev; /* 0 for a file, 1 for a device */
+ int retval = 0; /* assume good return */
+ if (fildes < 0 || fildes >= _nfile) {
+ errno = EBADF;
+ return(-1);
+ }
+
+ /* Lock the file */
+
+ _lock_fh(fildes);
+
+ /* Issue the get-device-info call. */
+ {
+ int descrip; /* device descriptor word */
+
+ if (DOSQUERYHTYPE(fildes, (unsigned *)&isdev, (unsigned *)&descrip))
+ {
+ errno = EBADF;
+ retval = -1; /* error from DOS call - bad file designator */
+ goto done; /* join common return code */
+ }
+
+ /* set the common fields */
+
+ buf->st_ino = buf->st_uid = buf->st_gid = buf->st_mode = 0;
+ buf->st_nlink = 1;
+
+ buf->st_mode |= (_osfile[fildes] & FRDONLY)
+ ? (_S_IREAD + (_S_IREAD >> 3) + (_S_IREAD >> 6))
+ : ((_S_IREAD|_S_IWRITE) +
+ ((_S_IREAD|_S_IWRITE) >> 3)
+ + ((_S_IREAD|_S_IWRITE) >> 6));
+
+ /* set file date fields - NOTE for code below, it should be
+ * remembered that calls to QFILEINFO cannot fail since the file
+ * handle is known to be good since we got by the QHANDTYPE call.
+ */
+
+ {
+ FILESTATUS fs;
+
+ (void)DOSQUERYFILEINFO(fildes, 1, (FILESTATUS *) & fs, sizeof(fs));
+
+ buf->st_mtime = XTIME(fs.fdateLastWrite, fs.ftimeLastWrite);
+
+ if ( _DATECAST(fs.fdateLastAccess) || _TIMECAST(fs.ftimeLastAccess) )
+ buf->st_atime = XTIME(fs.fdateLastAccess, fs.ftimeLastAccess);
+ else
+ buf->st_atime = buf->st_mtime ;
+
+ if ( _DATECAST(fs.fdateCreation) || _TIMECAST(fs.ftimeCreation) )
+ buf->st_ctime = XTIME(fs.fdateCreation, fs.ftimeCreation);
+ else
+ buf->st_ctime = buf->st_mtime ;
+
+ buf->st_mtime = XTIME(fs.fdateLastWrite, fs.ftimeLastWrite);
+ }
+
+ /* check for device or file */
+
+ if (isdev & 0xFF) {
+ /* file designator refers to a device - set file size to 0 */
+
+ buf->st_size = 0;
+ buf->st_mode |= _S_IFCHR;
+ buf->st_rdev = buf->st_dev = (_dev_t)fildes;
+ }
+ else {
+ /* file designator refers to a file - set actual file size */
+
+ cpos = _lseek_lk(fildes, 0L, 1);
+ buf->st_size = _lseek_lk(fildes, 0L, 2);
+ _lseek_lk(fildes, cpos, 0);
+
+ buf->st_mode |= _S_IFREG;
+
+ /*
+ * On DOS, this field contains the drive number, but
+ * the drive number is not available on this platform.
+ * Also, for UNC network names, there is no drive number.
+ */
+ buf->st_rdev = buf->st_dev = 0;
+ }
+
+/* Common return code */
+
+done:
+ _unlock_fh(fildes);
+ return(retval);
+}
+
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+
+int _CRTAPI1 _fstat (
+ int fildes,
+ struct _stat *buf
+ )
+{
+ int isdev; /* 0 for a file, 1 for a device */
+ int retval = 0; /* assume good return */
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ SYSTEMTIME SystemTime;
+
+ if ( (unsigned)fildes >= (unsigned)_nhandle ) {
+ errno = EBADF;
+ return(-1);
+ }
+
+ /* Lock the file */
+
+ _lock_fh(fildes);
+
+ /* Find out what kind of handle underlies filedes
+ */
+ isdev = GetFileType((HANDLE)_osfhnd[fildes]) & ~FILE_TYPE_REMOTE;
+
+ if ( isdev != FILE_TYPE_DISK ) {
+
+ /* not a disk file. probably a device or pipe
+ */
+ if ( (isdev == FILE_TYPE_CHAR) || (isdev == FILE_TYPE_PIPE) ) {
+ /* treat pipes and devices similarly. no further info is
+ * available from any API, so set the fields as reasonably
+ * as possible and return.
+ */
+ if ( isdev == FILE_TYPE_CHAR )
+ buf->st_mode = _S_IFCHR;
+ else
+ buf->st_mode = _S_IFIFO;
+
+ buf->st_rdev = buf->st_dev = (_dev_t)fildes;
+ buf->st_nlink = 1;
+ buf->st_uid = buf->st_gid = buf->st_ino = 0;
+ buf->st_atime = buf->st_mtime = buf->st_ctime = buf->st_size
+ = 0;
+
+ goto done;
+
+ }
+ else if ( isdev == FILE_TYPE_UNKNOWN ) {
+ errno = EBADF;
+ retval = -1;
+ goto done; /* join common return code */
+ }
+ else {
+ /* according to the documentation, this cannot happen, but
+ * play it safe anyway.
+ */
+ _dosmaperr(GetLastError());
+ retval = -1;
+ goto done;
+ }
+ }
+
+
+ /* set the common fields
+ */
+ buf->st_ino = buf->st_uid = buf->st_gid = buf->st_mode = 0;
+ buf->st_nlink = 1;
+
+ /* use the file handle to get all the info about the file
+ */
+ if ( !GetFileInformationByHandle((HANDLE)_osfhnd[fildes], &bhfi) ) {
+ _dosmaperr(GetLastError());
+ retval = -1;
+ goto done;
+ }
+
+ if ( bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY )
+ buf->st_mode |= (_S_IREAD + (_S_IREAD >> 3) + (_S_IREAD >> 6));
+ else
+ buf->st_mode |= ((_S_IREAD|_S_IWRITE) + ((_S_IREAD|_S_IWRITE) >> 3)
+ + ((_S_IREAD|_S_IWRITE) >> 6));
+
+ /* set file date fields
+ */
+ FileTimeToSystemTime( &(bhfi.ftLastWriteTime), &SystemTime );
+
+ buf->st_mtime = __gmtotime_t(SystemTime.wYear,
+ SystemTime.wMonth,
+ SystemTime.wDay,
+ SystemTime.wHour,
+ SystemTime.wMinute,
+ SystemTime.wSecond
+ );
+
+ if ( bhfi.ftLastAccessTime.dwLowDateTime || bhfi.ftLastAccessTime.
+ dwHighDateTime ) {
+
+ FileTimeToSystemTime( &(bhfi.ftLastAccessTime), &SystemTime );
+
+ buf->st_atime = __gmtotime_t(SystemTime.wYear,
+ SystemTime.wMonth,
+ SystemTime.wDay,
+ SystemTime.wHour,
+ SystemTime.wMinute,
+ SystemTime.wSecond
+ );
+ }
+ else
+ buf->st_atime = buf->st_mtime;
+
+ if ( bhfi.ftCreationTime.dwLowDateTime || bhfi.ftCreationTime.
+ dwHighDateTime ) {
+
+ FileTimeToSystemTime( &(bhfi.ftCreationTime), &SystemTime );
+
+ buf->st_ctime = __gmtotime_t(SystemTime.wYear,
+ SystemTime.wMonth,
+ SystemTime.wDay,
+ SystemTime.wHour,
+ SystemTime.wMinute,
+ SystemTime.wSecond
+ );
+ }
+ else
+ buf->st_ctime = buf->st_mtime;
+
+
+ buf->st_size = bhfi.nFileSizeLow;
+
+ buf->st_mode |= _S_IFREG;
+
+ /* On DOS, this field contains the drive number, but
+ * the drive number is not available on this platform.
+ * Also, for UNC network names, there is no drive number.
+ */
+ buf->st_rdev = buf->st_dev = 0;
+
+/* Common return code */
+
+done:
+ _unlock_fh(fildes);
+ return(retval);
+}
+
+#else /* ndef _WIN32_ */
+
+#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
diff --git a/private/crt32/lowio/getch.c b/private/crt32/lowio/getch.c
new file mode 100644
index 000000000..db7d2c585
--- /dev/null
+++ b/private/crt32/lowio/getch.c
@@ -0,0 +1,672 @@
+/***
+*getch.c - contains _getch(), _getche(), _ungetch() and kbhit for Windows NT
+*
+* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* Defines the "direct console" functions listed above.
+*
+* NOTE: The real-mode DOS versions of these functions read from
+* standard input and are therefore redirected when standard input
+* is redirected. However, these versions ALWAYS read from the console,
+* even when standard input is redirected.
+*
+*Revision History:
+* 06-08-89 PHG Module created, based on asm version
+* 03-12-90 GJF Made calling type _CALLTYPE1, added #include
+* <cruntime.h> and fixed the copyright. Also, cleaned
+* up the formatting a bit.
+* 06-05-90 SBM Recoded as pure 32-bit, using new file handle state bits
+* 07-24-90 SBM Removed '32' from API names
+* 10-03-90 GJF New-style function declarators.
+* 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
+* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
+* 01-16-91 GJF ANSI naming.
+* 01-25-91 SRW Get/SetConsoleMode parameters changed (_WIN32_)
+* 02-18-91 SRW Get/SetConsoleMode required read/write access (_WIN32_)
+* 02-19-91 SRW Adapt to OpenFile/CreateFile changes (_WIN32_)
+* 02-25-91 MHL Adapt to ReadFile/WriteFile changes (_WIN32_)
+* 07-26-91 GJF Took out init. stuff and cleaned up the error
+* handling [_WIN32_].
+* 12-11-92 GJF Initialize character buffer to 0 (int ch = 0;) and
+* use ReadConsole instead of ReadFile.
+* 03-20-93 GJF Completely rewritten, Cruiser support purged, _kbhit
+* (also rewritten) and _ungetch also merged in.
+* 05-10-93 GJF Fixed bug in _kbhit, pointer passed to free no
+* longer pointed to the allocated block.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <conio.h>
+#include <os2dll.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct {
+ unsigned char LeadChar;
+ unsigned char SecondChar;
+ } CharPair;
+
+typedef struct {
+ unsigned short ScanCode;
+ CharPair RegChars;
+ CharPair ShiftChars;
+ CharPair CtrlChars;
+ CharPair AltChars;
+ } EnhKeyVals;
+
+typedef struct {
+ CharPair RegChars;
+ CharPair ShiftChars;
+ CharPair CtrlChars;
+ CharPair AltChars;
+ } NormKeyVals;
+
+/*
+ * Table of key values for enhanced keys
+ */
+static EnhKeyVals EnhancedKeys[] = {
+ { 28, { 13, 0 }, { 13, 0 }, { 10, 0 }, { 0, 166 } },
+ { 53, { 47, 0 }, { 63, 0 }, { 0, 149 }, { 0, 164 } },
+ { 71, { 224, 71 }, { 224, 71 }, { 224, 119 }, { 0, 151 } },
+ { 72, { 224, 72 }, { 224, 72 }, { 224, 141 }, { 0, 152 } },
+ { 73, { 224, 73 }, { 224, 73 }, { 224, 134 }, { 0, 153 } },
+ { 75, { 224, 75 }, { 224, 75 }, { 224, 115 }, { 0, 155 } },
+ { 77, { 224, 77 }, { 224, 77 }, { 224, 116 }, { 0, 157 } },
+ { 79, { 224, 79 }, { 224, 79 }, { 224, 117 }, { 0, 159 } },
+ { 80, { 224, 80 }, { 224, 80 }, { 224, 145 }, { 0, 160 } },
+ { 81, { 224, 81 }, { 224, 81 }, { 224, 118 }, { 0, 161 } },
+ { 82, { 224, 82 }, { 224, 82 }, { 224, 146 }, { 0, 162 } },
+ { 83, { 224, 83 }, { 224, 83 }, { 224, 147 }, { 0, 163 } }
+ };
+
+/*
+ * macro for the number of elements of in EnhancedKeys[]
+ */
+#define NUM_EKA_ELTS ( sizeof( EnhancedKeys ) / sizeof( EnhKeyVals ) )
+
+/*
+ * Table of key values for normal keys. Note that the table is padded so
+ * that the key scan code serves as an index into the table.
+ */
+static NormKeyVals NormalKeys[] = {
+
+ /* padding */
+ { /* 0 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+
+ { /* 1 */ { 27, 0 }, { 27, 0 }, { 27, 0 }, { 0, 1 } },
+ { /* 2 */ { 49, 0 }, { 33, 0 }, { 0, 0 }, { 0, 120 } },
+ { /* 3 */ { 50, 0 }, { 64, 0 }, { 0, 3 }, { 0, 121 } },
+ { /* 4 */ { 51, 0 }, { 35, 0 }, { 0, 0 }, { 0, 122 } },
+ { /* 5 */ { 52, 0 }, { 36, 0 }, { 0, 0 }, { 0, 123 } },
+ { /* 6 */ { 53, 0 }, { 37, 0 }, { 0, 0 }, { 0, 124 } },
+ { /* 7 */ { 54, 0 }, { 94, 0 }, { 30, 0 }, { 0, 125 } },
+ { /* 8 */ { 55, 0 }, { 38, 0 }, { 0, 0 }, { 0, 126 } },
+ { /* 9 */ { 56, 0 }, { 42, 0 }, { 0, 0 }, { 0, 127 } },
+ { /* 10 */ { 57, 0 }, { 40, 0 }, { 0, 0 }, { 0, 128 } },
+ { /* 11 */ { 48, 0 }, { 41, 0 }, { 0, 0 }, { 0, 129 } },
+ { /* 12 */ { 45, 0 }, { 95, 0 }, { 31, 0 }, { 0, 130 } },
+ { /* 13 */ { 61, 0 }, { 43, 0 }, { 0, 0 }, { 0, 131 } },
+ { /* 14 */ { 8, 0 }, { 8, 0 }, { 127, 0 }, { 0, 14 } },
+ { /* 15 */ { 9, 0 }, { 0, 15 }, { 0, 148 }, { 0, 15 } },
+ { /* 16 */ { 113, 0 }, { 81, 0 }, { 17, 0 }, { 0, 16 } },
+ { /* 17 */ { 119, 0 }, { 87, 0 }, { 23, 0 }, { 0, 17 } },
+ { /* 18 */ { 101, 0 }, { 69, 0 }, { 5, 0 }, { 0, 18 } },
+ { /* 19 */ { 114, 0 }, { 82, 0 }, { 18, 0 }, { 0, 19 } },
+ { /* 20 */ { 116, 0 }, { 84, 0 }, { 20, 0 }, { 0, 20 } },
+ { /* 21 */ { 121, 0 }, { 89, 0 }, { 25, 0 }, { 0, 21 } },
+ { /* 22 */ { 117, 0 }, { 85, 0 }, { 21, 0 }, { 0, 22 } },
+ { /* 23 */ { 105, 0 }, { 73, 0 }, { 9, 0 }, { 0, 23 } },
+ { /* 24 */ { 111, 0 }, { 79, 0 }, { 15, 0 }, { 0, 24 } },
+ { /* 25 */ { 112, 0 }, { 80, 0 }, { 16, 0 }, { 0, 25 } },
+ { /* 26 */ { 91, 0 }, { 123, 0 }, { 27, 0 }, { 0, 26 } },
+ { /* 27 */ { 93, 0 }, { 125, 0 }, { 29, 0 }, { 0, 27 } },
+ { /* 28 */ { 13, 0 }, { 13, 0 }, { 10, 0 }, { 0, 28 } },
+
+ /* padding */
+ { /* 29 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+
+ { /* 30 */ { 97, 0 }, { 65, 0 }, { 1, 0 }, { 0, 30 } },
+ { /* 31 */ { 115, 0 }, { 83, 0 }, { 19, 0 }, { 0, 31 } },
+ { /* 32 */ { 100, 0 }, { 68, 0 }, { 4, 0 }, { 0, 32 } },
+ { /* 33 */ { 102, 0 }, { 70, 0 }, { 6, 0 }, { 0, 33 } },
+ { /* 34 */ { 103, 0 }, { 71, 0 }, { 7, 0 }, { 0, 34 } },
+ { /* 35 */ { 104, 0 }, { 72, 0 }, { 8, 0 }, { 0, 35 } },
+ { /* 36 */ { 106, 0 }, { 74, 0 }, { 10, 0 }, { 0, 36 } },
+ { /* 37 */ { 107, 0 }, { 75, 0 }, { 11, 0 }, { 0, 37 } },
+ { /* 38 */ { 108, 0 }, { 76, 0 }, { 12, 0 }, { 0, 38 } },
+ { /* 39 */ { 59, 0 }, { 58, 0 }, { 0, 0 }, { 0, 39 } },
+ { /* 40 */ { 39, 0 }, { 34, 0 }, { 0, 0 }, { 0, 40 } },
+ { /* 41 */ { 96, 0 }, { 126, 0 }, { 0, 0 }, { 0, 41 } },
+
+ /* padding */
+ { /* 42 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+
+ { /* 43 */ { 92, 0 }, { 124, 0 }, { 28, 0 }, { 0, 0 } },
+ { /* 44 */ { 122, 0 }, { 90, 0 }, { 26, 0 }, { 0, 44 } },
+ { /* 45 */ { 120, 0 }, { 88, 0 }, { 24, 0 }, { 0, 45 } },
+ { /* 46 */ { 99, 0 }, { 67, 0 }, { 3, 0 }, { 0, 46 } },
+ { /* 47 */ { 118, 0 }, { 86, 0 }, { 22, 0 }, { 0, 47 } },
+ { /* 48 */ { 98, 0 }, { 66, 0 }, { 2, 0 }, { 0, 48 } },
+ { /* 49 */ { 110, 0 }, { 78, 0 }, { 14, 0 }, { 0, 49 } },
+ { /* 50 */ { 109, 0 }, { 77, 0 }, { 13, 0 }, { 0, 50 } },
+ { /* 51 */ { 44, 0 }, { 60, 0 }, { 0, 0 }, { 0, 51 } },
+ { /* 52 */ { 46, 0 }, { 62, 0 }, { 0, 0 }, { 0, 52 } },
+ { /* 53 */ { 47, 0 }, { 63, 0 }, { 0, 0 }, { 0, 53 } },
+
+ /* padding */
+ { /* 54 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+
+ { /* 55 */ { 42, 0 }, { 0, 0 }, { 114, 0 }, { 0, 0 } },
+
+ /* padding */
+ { /* 56 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+
+ { /* 57 */ { 32, 0 }, { 32, 0 }, { 32, 0 }, { 32, 0 } },
+
+ /* padding */
+ { /* 58 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+
+ { /* 59 */ { 0, 59 }, { 0, 84 }, { 0, 94 }, { 0, 104 } },
+ { /* 60 */ { 0, 60 }, { 0, 85 }, { 0, 95 }, { 0, 105 } },
+ { /* 61 */ { 0, 61 }, { 0, 86 }, { 0, 96 }, { 0, 106 } },
+ { /* 62 */ { 0, 62 }, { 0, 87 }, { 0, 97 }, { 0, 107 } },
+ { /* 63 */ { 0, 63 }, { 0, 88 }, { 0, 98 }, { 0, 108 } },
+ { /* 64 */ { 0, 64 }, { 0, 89 }, { 0, 99 }, { 0, 109 } },
+ { /* 65 */ { 0, 65 }, { 0, 90 }, { 0, 100 }, { 0, 110 } },
+ { /* 66 */ { 0, 66 }, { 0, 91 }, { 0, 101 }, { 0, 111 } },
+ { /* 67 */ { 0, 67 }, { 0, 92 }, { 0, 102 }, { 0, 112 } },
+ { /* 68 */ { 0, 68 }, { 0, 93 }, { 0, 103 }, { 0, 113 } },
+
+ /* padding */
+ { /* 69 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+ { /* 70 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+
+ { /* 71 */ { 0, 71 }, { 55, 0 }, { 0, 119 }, { 0, 0 } },
+ { /* 72 */ { 0, 72 }, { 56, 0 }, { 0, 141 }, { 0, 0 } },
+ { /* 73 */ { 0, 73 }, { 57, 0 }, { 0, 132 }, { 0, 0 } },
+ { /* 74 */ { 0, 0 }, { 45, 0 }, { 0, 0 }, { 0, 0 } },
+ { /* 75 */ { 0, 75 }, { 52, 0 }, { 0, 115 }, { 0, 0 } },
+ { /* 76 */ { 0, 0 }, { 53, 0 }, { 0, 0 }, { 0, 0 } },
+ { /* 77 */ { 0, 77 }, { 54, 0 }, { 0, 116 }, { 0, 0 } },
+ { /* 78 */ { 0, 0 }, { 43, 0 }, { 0, 0 }, { 0, 0 } },
+ { /* 79 */ { 0, 79 }, { 49, 0 }, { 0, 117 }, { 0, 0 } },
+ { /* 80 */ { 0, 80 }, { 50, 0 }, { 0, 145 }, { 0, 0 } },
+ { /* 81 */ { 0, 81 }, { 51, 0 }, { 0, 118 }, { 0, 0 } },
+ { /* 82 */ { 0, 82 }, { 48, 0 }, { 0, 146 }, { 0, 0 } },
+ { /* 83 */ { 0, 83 }, { 46, 0 }, { 0, 147 }, { 0, 0 } },
+
+ /* padding */
+ { /* 84 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+ { /* 85 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+ { /* 86 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+
+ { /* 87 */ { 224, 133 }, { 224, 135 }, { 224, 137 }, { 224, 139 } },
+ { /* 88 */ { 224, 134 }, { 224, 136 }, { 224, 138 }, { 224, 140 } }
+
+};
+
+
+/*
+ * This is the one character push-back buffer used by _getch(), _getche()
+ * and _ungetch().
+ */
+static int chbuf = EOF;
+
+
+/*
+ * Declaration for console handle
+ */
+extern int _coninpfh;
+
+/*
+ * Function that looks up the extended key code for a given event.
+ */
+static CharPair * _CRTAPI3 GetExtendedKeyCode(KEY_EVENT_RECORD *);
+
+
+/***
+*int _getch(), _getche() - read one char. from console (without and with echo)
+*
+*Purpose:
+* If the "_ungetch()" push-back buffer is not empty (empty==-1) Then
+* Mark it empty (-1) and RETURN the value that was in it
+* Read a character using DOSREAD in RAW mode
+* Return the Character Code
+* _getche(): Same as _getch() except that the character value returned
+* is echoed (via "_putch()")
+*
+* No _ext_code buffer is required (unlike the DOS & 16 bit OS/2 world,)
+* since OS/2 buffers the extended code for us.
+*
+*Entry:
+* None, reads from console.
+*
+*Exit:
+* If an error is returned from the API
+* Then EOF
+* Otherwise
+* next byte from console
+* Static variable "chbuf" may be altered
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+#ifdef MTHREAD
+
+int _CRTAPI1 _getch (
+ void
+ )
+{
+ int ch;
+
+ _mlock(_CONIO_LOCK); /* secure the console lock */
+ ch = _getch_lk(); /* input the character */
+ _munlock(_CONIO_LOCK); /* release the console lock */
+
+ return ch;
+}
+
+int _CRTAPI1 _getche (
+ void
+ )
+{
+ int ch;
+
+ _mlock(_CONIO_LOCK); /* secure the console lock */
+ ch = _getche_lk(); /* input and echo the character */
+ _munlock(_CONIO_LOCK); /* unlock the console */
+
+ return ch;
+}
+
+#endif /* MTHREAD */
+
+
+#ifdef MTHREAD
+int _CRTAPI1 _getch_lk (
+#else
+int _CRTAPI1 _getch (
+#endif
+ void
+ )
+{
+ INPUT_RECORD ConInpRec;
+ DWORD NumRead;
+ CharPair *pCP;
+ int ch = 0; /* single character buffer */
+ DWORD oldstate;
+
+ /*
+ * check pushback buffer (chbuf) a for character
+ */
+ if ( chbuf != EOF ) {
+ /*
+ * something there, clear buffer and return the character.
+ */
+ ch = (unsigned char)(chbuf & 0xFF);
+ chbuf = EOF;
+ return ch;
+ }
+
+ if (_coninpfh == -1)
+ return EOF;
+
+ /*
+ * Switch to raw mode (no line input, no echo input)
+ */
+ GetConsoleMode( (HANDLE)_coninpfh, &oldstate );
+ SetConsoleMode( (HANDLE)_coninpfh, 0L );
+
+ for ( ; ; ) {
+
+ /*
+ * Get a console input event.
+ */
+ if ( !ReadConsoleInput( (HANDLE)_coninpfh,
+ &ConInpRec,
+ 1L,
+ &NumRead )
+ || (NumRead == 0L) )
+ {
+ ch = EOF;
+ break;
+ }
+
+ /*
+ * Look for, and decipher, key events.
+ */
+ if ( (ConInpRec.EventType == KEY_EVENT) &&
+ ConInpRec.Event.KeyEvent.bKeyDown ) {
+ /*
+ * Easy case: if uChar.AsciiChar is non-zero, just stuff it
+ * into ch and quit.
+ */
+ if ( ch = (unsigned char)ConInpRec.Event.KeyEvent.uChar.AsciiChar )
+ break;
+
+ /*
+ * Hard case: either an extended code or an event which should
+ * not be recognized. let GetExtendedKeyCode() do the work...
+ */
+ if ( pCP = GetExtendedKeyCode( &(ConInpRec.Event.KeyEvent) ) ) {
+ ch = pCP->LeadChar;
+ chbuf = pCP->SecondChar;
+ break;
+ }
+ }
+ }
+
+
+ /*
+ * Restore previous console mode.
+ */
+ SetConsoleMode( (HANDLE)_coninpfh, oldstate );
+
+ return ch;
+}
+
+
+/*
+ * getche is just getch followed by a putch if no error occurred
+ */
+
+#ifdef MTHREAD
+int _CRTAPI1 _getche_lk (
+#else
+int _CRTAPI1 _getche (
+#endif
+ void
+ )
+{
+ int ch; /* character read */
+
+ ch = _getch_lk(); /* read character */
+ if (ch != EOF) {
+ if (_putch_lk(ch) != EOF) {
+ return ch; /* if no error, return char */
+ }
+ }
+ return EOF; /* get or put failed, return EOF */
+}
+
+
+/***
+*int _kbhit() - return flag if a keystroke is already waiting to be read
+*
+*Purpose:
+* If the "_ungetch()" push-back buffer is not empty (empty==-1) Then
+* Return TRUE
+* Otherwise get the Keyboard Status (via DOSQUERYFHSTATE)
+* No _ext_code buffer is required (unlike the DOS & 16 bit OS/2 world,)
+* since OS/2 buffers the extended code for us.
+*
+*Entry:
+* None, tests console.
+*
+*Exit:
+* returns 0 if no key waiting
+* = !0 if key waiting
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+#ifdef MTHREAD
+
+int _CRTAPI1 _kbhit_lk(void);
+
+int _CRTAPI1 _kbhit (
+ void
+ )
+{
+ int retval;
+
+ _mlock(_CONIO_LOCK); /* secure the console lock */
+ retval = _kbhit_lk(); /* determine if a key is waiting */
+ _munlock(_CONIO_LOCK); /* release the console lock */
+
+ return retval;
+}
+
+int _CRTAPI1 _kbhit_lk (
+
+#else
+
+int _CRTAPI1 _kbhit (
+
+#endif
+ void
+ )
+{
+ void *pblk;
+ PINPUT_RECORD pIRBuf;
+ DWORD NumPending;
+ DWORD NumPeeked;
+
+ /*
+ * if a character has been pushed back, return TRUE
+ */
+ if ( chbuf != -1 )
+ return TRUE;
+
+ /*
+ * Peek all pending console events
+ */
+ if ( (_coninpfh == -1) ||
+
+ !GetNumberOfConsoleInputEvents((HANDLE)_coninpfh, &NumPending) ||
+
+ ((pblk = malloc( NumPending * sizeof(INPUT_RECORD) )) == NULL) )
+ {
+ return FALSE;
+ }
+
+ /*
+ * Keep pblk unmodified, for use in a later call to free()
+ */
+ pIRBuf = (PINPUT_RECORD)pblk;
+
+ if ( PeekConsoleInput( (HANDLE)_coninpfh,
+ pIRBuf,
+ NumPending,
+ &NumPeeked ) &&
+
+ (NumPeeked != 0L) &&
+
+ (NumPeeked <= NumPending) )
+ {
+
+ /*
+ * Scan all of the peeked events to determine if any is a key event
+ * which should be recognized.
+ */
+ for ( ; NumPeeked > 0 ; NumPeeked--, pIRBuf++ ) {
+
+ if ( (pIRBuf->EventType == KEY_EVENT) &&
+
+ (pIRBuf->Event.KeyEvent.bKeyDown) &&
+
+ ( pIRBuf->Event.KeyEvent.uChar.AsciiChar ||
+ GetExtendedKeyCode( &(pIRBuf->Event.KeyEvent) ) ) )
+ {
+ /*
+ * Key event corresponding to an ASCII character or an
+ * extended code. In either case, success!
+ */
+ free(pblk);
+ return TRUE;
+ }
+ }
+ }
+
+ free(pblk);
+ return FALSE;
+}
+
+
+/***
+*int _ungetch(c) - push back one character for "_getch()" or "_getche()"
+*
+*Purpose:
+* If the Push-back buffer "chbuf" is -1 Then
+* Set "chbuf" to the argument and return the argument
+* Else
+* Return EOF to indicate an error
+*
+*Entry:
+* int c - Character to be pushed back
+*
+*Exit:
+* If successful
+* returns character that was pushed back
+* Else if error
+* returns EOF
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+#ifdef MTHREAD
+
+int _CRTAPI1 _ungetch (
+ int c
+ )
+{
+ int retval;
+
+ _mlock(_CONIO_LOCK); /* lock the console */
+ retval = _ungetch_lk(c); /* pushback character */
+ _munlock(_CONIO_LOCK); /* unlock the console */
+
+ return retval;
+}
+int _CRTAPI1 _ungetch_lk (
+
+#else
+
+int _CRTAPI1 _ungetch (
+
+#endif
+ int c
+ )
+{
+ /*
+ * Fail if the char is EOF or the pushback buffer is non-empty
+ */
+ if ( (c == EOF) || (chbuf != EOF) )
+ return EOF;
+
+ chbuf = (c & 0xFF);
+ return chbuf;
+}
+
+
+
+
+/***
+* static CharPair * GetExtendedKeyCode(pKE) - return extended code (if any)
+* for key event.
+*
+*Purpose:
+* Core function for _getch (and getche) and essential to _kbhit. This
+* is the function that determines whether or not a key event NOT
+* accompanied by an ASCII character has an extended code and returns
+* that code.
+*
+*Entry:
+* None, tests console.
+*
+*Exit:
+* if successful, returns a pointer to a CharPair value holding the lead
+* and second characters of the extended code.
+*
+* if unsuccesful, returns NULL
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+
+static CharPair * _CRTAPI3 GetExtendedKeyCode (
+ KEY_EVENT_RECORD *pKE
+ )
+{
+ DWORD CKS; /* hold dwControlKeyState value */
+ CharPair *pCP; /* pointer to CharPair containing extended
+ code */
+ int i;
+
+ // printf("pKE->wVirtualScanCode = %d\n", (int) (pKE->wVirtualScanCode) );
+ // printf("pKE->dwControlKeyState = %lx\n\n", pKE->dwControlKeyState);
+
+ if ( (CKS = pKE->dwControlKeyState) & ENHANCED_KEY ) {
+
+ /*
+ * Find the appropriate entry in EnhancedKeys[]
+ */
+ for ( pCP = NULL, i = 0 ; i < NUM_EKA_ELTS ; i++ ) {
+
+ if ( EnhancedKeys[i].ScanCode == pKE->wVirtualScanCode ) {
+
+ if ( CKS & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) )
+
+ pCP = &(EnhancedKeys[i].AltChars);
+
+ else if ( CKS & (LEFT_CTRL_PRESSED | LEFT_CTRL_PRESSED) )
+
+ pCP = &(EnhancedKeys[i].CtrlChars);
+
+ else if ( CKS & SHIFT_PRESSED)
+
+ pCP = &(EnhancedKeys[i].ShiftChars);
+
+ else
+
+ pCP = &(EnhancedKeys[i].RegChars);
+
+ break;
+
+ }
+ }
+
+ }
+
+ else {
+
+ /*
+ * Regular key or a keyboard event which shouldn't be recognized.
+ * Determine which by getting the proper field of the proper
+ * entry in NormalKeys[], and examining the extended code.
+ */
+ if ( CKS & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) )
+
+ pCP = &(NormalKeys[pKE->wVirtualScanCode].AltChars);
+
+ else if ( CKS & (LEFT_CTRL_PRESSED | LEFT_CTRL_PRESSED) )
+
+ pCP = &(NormalKeys[pKE->wVirtualScanCode].CtrlChars);
+
+ else if ( CKS & SHIFT_PRESSED)
+
+ pCP = &(NormalKeys[pKE->wVirtualScanCode].ShiftChars);
+
+ else
+
+ pCP = &(NormalKeys[pKE->wVirtualScanCode].RegChars);
+
+ if ( ((pCP->LeadChar != 0) && (pCP->LeadChar != 224)) ||
+ (pCP->SecondChar == 0) )
+ /*
+ * Must be a keyboard event which should not be recognized
+ * (e.g., shift key was pressed)
+ */
+ pCP = NULL;
+
+ }
+
+ return(pCP);
+}
diff --git a/private/crt32/lowio/i386/_initcon.asm b/private/crt32/lowio/i386/_initcon.asm
new file mode 100644
index 000000000..3ec35d9b6
--- /dev/null
+++ b/private/crt32/lowio/i386/_initcon.asm
@@ -0,0 +1,17 @@
+ page ,132
+
+;*******
+;
+; Alternate form of CINITCON.ASM
+;
+; The MIPS C Compiler does not prepend underscores to C
+; variables and functions like the I386 C Compiler does.
+;
+; The EQUate below will yield an object file
+; which will be appropriate for MIPS COFF format.
+;
+;*******
+
+NO_UNDERSCORE equ 1
+
+include i386\cinitcon.asm
diff --git a/private/crt32/lowio/i386/cinitcon.asm b/private/crt32/lowio/i386/cinitcon.asm
new file mode 100644
index 000000000..aa6f8074a
--- /dev/null
+++ b/private/crt32/lowio/i386/cinitcon.asm
@@ -0,0 +1,99 @@
+ page ,132
+ title cinitcon - C Run-Time Startup Initialization for Console I/O
+;***
+;cinitcon.asm - C Run-Time Startup Initialization for WIN32
+;
+; Copyright (c) 1990-1992, Microsoft Corporation. All rights reserved.
+;
+;Purpose:
+; Initialization and Termination for console I/O
+;
+;Notes:
+; _confh and _coninpfh are defined in this module to force the
+; inclusion of this module if any console I/O is performed.
+; This module places the address of _initcon() in the initializer
+; table and the address of _termcon() in the pre-terminator table.
+;
+;Revision History:
+; 03-19-92 SKS Module created.
+; 03-24-92 SKS Added MIPS support (NO_UNDERSCORE)
+; 04-30-92 SKS Add "offset FLAT:" to get correct fixups for OMF objs
+; 08-06-92 SKS Revised to use new section names and macros
+;
+;*******************************************************************************
+
+.xlist
+include cruntime.inc
+include defsects.inc
+.list
+
+ifndef _WIN32_
+.err
+%out _WIN32_ MUST be defined!
+endif
+
+
+ifndef NO_UNDERSCORE ; I386 VERSION *************************
+
+
+ extrn _initcon:NEAR
+ extrn _termcon:NEAR
+
+
+beginSection XIC
+
+ dd offset FLAT: _initcon
+
+endSection XIC
+
+
+beginSection XPX
+
+ dd offset FLAT: _termcon
+
+endSection XPX
+
+
+ .DATA
+
+ public _coninpfh
+ public _confh
+
+_coninpfh dd -1 ; console input
+_confh dd -1 ; console output
+
+
+else ; NO_UNDERSCORE ; MIPS VERSION *************************
+
+
+ extrn initcon:NEAR
+ extrn termcon:NEAR
+
+
+beginSection XIC
+
+ dd offset FLAT: initcon
+
+endSection XIC
+
+
+beginSection XPX
+
+ dd offset FLAT: termcon
+
+endSection XPX
+
+
+ .DATA
+
+ public coninpfh
+ public confh
+
+coninpfh dd -1 ; console input
+confh dd -1 ; console output
+
+
+endif ; NO_UNDERSCORE ; **** VERSION *************************
+
+
+ end
diff --git a/private/crt32/lowio/initcon.c b/private/crt32/lowio/initcon.c
new file mode 100644
index 000000000..0302e5d84
--- /dev/null
+++ b/private/crt32/lowio/initcon.c
@@ -0,0 +1,113 @@
+/***
+*_initcon.c - direct console I/O initialization and termination for Win32
+*
+* Copyright (c) 1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* Defines _initcon() and _termcon() routines.
+*
+* NOTE: The _initcon() and _termcon() routines are called indirectly
+* by the startup and termination code, thru the pointers _pinitcon
+* and _ptermcon.
+*
+*Revision History:
+* 07-26-91 GJF Module created. Based on the original code by Stevewo
+* (which was distributed across several sources).
+* 03-12-92 SKS Split out initializer
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+
+void __cdecl _initcon(void);
+void __cdecl _termcon(void);
+
+#ifdef _MSC_VER
+
+#pragma data_seg(".CRT$XIC")
+static void (__cdecl *pinit)(void) = _initcon;
+
+#pragma data_seg(".CRT$XPX")
+static void (__cdecl *pterm)(void) = _termcon;
+
+#pragma data_seg()
+
+#endif /* _MSC_VER */
+
+/*
+ * define console handles. these definitions cause this file to be linked
+ * in if one of the direct console I/O functions is referenced.
+ */
+int _coninpfh = -1; /* console input */
+int _confh = -1; /* console output */
+
+/***
+*void _initcon(void) - open handles for console I/O
+*
+*Purpose:
+* Opens handles for console input and output.
+*
+*Entry:
+* None.
+*
+*Exit:
+* No return value. If successful, handle values are copied into the
+* global variables _coninpfh and _confh.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+void __cdecl _initcon (
+ void
+ )
+{
+ _coninpfh = (int)CreateFile( "CONIN$",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL
+ );
+
+ _confh = (int)CreateFile( "CONOUT$",
+ GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL
+ );
+}
+
+
+/***
+*void _termcon(void) - close console I/O handles
+*
+*Purpose:
+* Closes _coninpfh and _confh.
+*
+*Entry:
+* None.
+*
+*Exit:
+* No return value.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+void __cdecl _termcon (
+ void
+ )
+{
+ if ( _confh != -1 ) {
+ CloseHandle( (HANDLE)_confh );
+ }
+
+ if ( _coninpfh != -1 ) {
+ CloseHandle( (HANDLE)_coninpfh );
+ }
+}
diff --git a/private/crt32/lowio/ioinit.c b/private/crt32/lowio/ioinit.c
new file mode 100644
index 000000000..d359f9686
--- /dev/null
+++ b/private/crt32/lowio/ioinit.c
@@ -0,0 +1,242 @@
+/***
+*ioinit.c - Initialization for lowio functions
+*
+* Copyright (c) 1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* Contains all initialization for lowio functions. Currently, this
+* includes:
+* 1. Definitions of _nhandle, _osfhnd[], _osfile[] and _pipech[],
+* including initial values.
+* 2. Processing of inherited file info from parent process.
+* 3. Initialization of _osfhnd[] and _osfile[] entries for
+* standard input/output/error.
+*
+*Revision History:
+* 02-14-92 GJF Module created.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <internal.h>
+#include <msdos.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * Number of allowable file handles. The static initialization of the
+ * _osfhnd[] and _pipech[] arrays (below) supports only two values of
+ * _NHANDLE, 64 (for single-thread) and 256 (for multi-thread)!
+ */
+int _nhandle = _NHANDLE_;
+
+/*
+ * File handle database
+ */
+char _osfile[_NHANDLE_] = { 0 };
+
+/*
+ * Array of OS file handles. Statically initialized to INVALID_HANDLE_VALUE.
+ * Note that if _NHANDLE_ differs from 64 for single-thread, or differs from
+ * 256 for multi-thread, this initialization needs to be revised.
+ */
+#define NOHNDL (long)INVALID_HANDLE_VALUE
+
+long _osfhnd[_NHANDLE_] = {
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+#ifdef MTHREAD
+ NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+ NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL, NOHNDL,
+#endif
+ NOHNDL };
+
+/*
+ * Peek-ahead buffers for pipes, each initialized to a newline. Note that if
+ * _NHANDLE_ differs from 64 for single-thread, or differs from 256 for
+ * multi-thread, this initialization needs to be revised.
+ */
+char _pipech[_NHANDLE_] = {
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+#ifdef MTHREAD
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+#endif
+ 10 };
+
+/*
+ * macro used to map 0, 1 and 2 to right value for call to GetStdHandle
+ */
+#define stdhndl(fh) ( (fh == 0) ? STD_INPUT_HANDLE : ((fh == 1) ? \
+ STD_OUTPUT_HANDLE : STD_ERROR_HANDLE) )
+
+/***
+*_ioinit() -
+*
+*Purpose:
+* First, _ioinit() obtains and processes information on inherited file
+* handles from the parent process (e.g., cmd.exe)
+*
+* Obtains the StartupInfo structure from the OS. The inherited file
+* handle information is pointed to by the lpReserved2 field. The format
+* of the information is as follows:
+*
+* bytes 0 thru 3 - integer value, say N, which is the number of handles
+* information is passed about.
+*
+* bytes 4 thru N+3 - values for _osfile[0] thru _osfile[N-1]
+*
+* bytes N+4 thru 5*N+3 - N double-words, the N OS handle values being
+* passed.
+*
+* Next, _osfhnd[i] and _osfile[i] are initialized for i = 0, 1, 2, as
+* follows:
+*
+* If the value in _osfhnd[i] is INVALID_HANDLE_VALUE, then try to
+* obtain a handle by calling GetStdHandle, and call GetFileType to
+* help set _osfile[i]. Otherwise, assume _osfhndl[i] and _osfile[i]
+* are valid, but force it to text mode (standard input/output/error
+* are to always start out in text mode).
+*
+* Notes:
+* 1. In general, not all of the passed info from the parent process
+* will describe open handles! If, for example, only C handle 1
+* (STDOUT) and C handle 6 are open in the parent, info for C
+* handles 0 thru 6 is passed to the the child.
+*
+* 2. Care is taken not to 'overflow' _osfhnd[] and _osfile[]. Only
+* info on the first _NHANDLE_ handles from the parent process is
+* used.
+*
+* 3. See exec\dospawn.c for the encodes of the file handle info
+* to be passed to a child process.
+*
+*Entry:
+* No parameters: reads the environment.
+*
+*Exit:
+* No return value.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+void _CALLTYPE1 _ioinit (
+ void
+ )
+{
+ STARTUPINFO StartupInfo;
+ int cfi_len;
+ int fh;
+ DWORD htype;
+
+ /*
+ * Process inherited file handle information, if any
+ */
+
+ GetStartupInfo( &StartupInfo );
+
+ if ( StartupInfo.cbReserved2 != 0 && StartupInfo.lpReserved2 != NULL ) {
+ /*
+ * Get the number of handles inherited.
+ */
+ memcpy( &cfi_len,
+ StartupInfo.lpReserved2,
+ sizeof( int )
+ );
+ /*
+ * Now, get one byte of info (_osfile[] entry) for each
+ * inherited handle. Be careful not to overflow the _osfile[]
+ * array.
+ */
+ memcpy( _osfile,
+ StartupInfo.lpReserved2 + sizeof( int ),
+ __min(_NHANDLE_, cfi_len) * sizeof( char )
+ );
+ /*
+ * Finally, copy each each inherited handle into _osfhnd[].
+ * Be careful not to overflow _osfile[].
+ */
+ memcpy( _osfhnd,
+ StartupInfo.lpReserved2 + sizeof( int ) +
+ (cfi_len * sizeof( char )),
+ __min(_NHANDLE_, cfi_len) * sizeof( long )
+ );
+ }
+
+ /*
+ * If handles for standard input, output and error were not inherited,
+ * try to obtain them directly from the OS. Also, set appropriate bits
+ * in _osfile[0], _osfile[1] and _osfile[2].
+ */
+
+ for ( fh = 0 ; fh <= 2 ; ++fh ) {
+
+ if ( _osfhnd[fh] == (long)INVALID_HANDLE_VALUE ) {
+ if ( (_osfhnd[fh] = (long)GetStdHandle( stdhndl(fh) ))
+ != (long)INVALID_HANDLE_VALUE ) {
+ /*
+ * mark the stream as open in text mode.
+ * determine if it isa char device or pipe.
+ */
+ _osfile[fh] = (char)(FOPEN | FTEXT);
+ htype = GetFileType( (HANDLE)_osfhnd[fh] );
+ if ( (htype & 0xFF) == FILE_TYPE_CHAR )
+ _osfile[fh] |= FDEV;
+ else if ( (htype & 0xFF) == FILE_TYPE_PIPE )
+ _osfile[fh] |= FPIPE;
+ }
+ }
+ else
+ /*
+ * handle was passed to us by parent process. make
+ * sure it is text mode.
+ */
+ _osfile[fh] |= FTEXT;
+ }
+
+
+}
diff --git a/private/crt32/lowio/isatty.c b/private/crt32/lowio/isatty.c
new file mode 100644
index 000000000..9bb931d18
--- /dev/null
+++ b/private/crt32/lowio/isatty.c
@@ -0,0 +1,62 @@
+/***
+*isatty.c - check if file handle refers to a device
+*
+* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _isatty() - check if file handle refers to a device
+*
+*Revision History:
+* 06-08-89 PHG Module created
+* 03-12-90 GJF Made calling type _CALLTYPE1, added #include
+* <cruntime.h> and fixed the copyright. Also, cleaned
+* up the formatting a bit.
+* 08-14-90 SBM Compiles cleanly with -W3, minor optimization
+* 09-28-90 GJF New-style function declarator.
+* 12-04-90 GJF Appended Win32 version onto the source with #ifdef-s.
+* It's not worth it to try to merge the versions more
+* closely.
+* 12-06-90 SRW Changed to use _osfile and _osfhnd instead of _osfinfo
+* 01-16-91 GJF ANSI naming.
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <msdos.h>
+#include <internal.h>
+#include <io.h>
+
+/***
+*int _isatty(handle) - check if handle is a device
+*
+*Purpose:
+* Checks if the given handle is associated with a character device
+* (terminal, console, printer, serial port)
+*
+*Entry:
+* int handle - handle of file to be tested
+*
+*Exit:
+* returns non-0 if handle refers to character device,
+* returns 0 otherwise
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _isatty (
+ int fh
+ )
+{
+ /* see if file handle is valid, otherwise return FALSE */
+#ifdef _WIN32_
+ if ( (unsigned)fh >= (unsigned)_nhandle )
+#else
+ if ((unsigned)fh >= (unsigned)_nfile)
+#endif
+ return 0;
+
+ /* check file handle database to see if device bit set */
+ return (int)(_osfile[fh] & FDEV);
+}
diff --git a/private/crt32/lowio/locking.c b/private/crt32/lowio/locking.c
new file mode 100644
index 000000000..8eca84b29
--- /dev/null
+++ b/private/crt32/lowio/locking.c
@@ -0,0 +1,187 @@
+/***
+*locking.c - OS/2 file locking function
+*
+* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* Defined the _locking() function - file locking and unlocking
+*
+*Revision History:
+* 06-09-89 PHG Module created, based on asm version
+* 08-10-89 JCR Changed DOS32FILELOCKS to DOS32SETFILELOCKS
+* 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_]
+* 12-05-91 GJF Fixed usage of [Un]LockFile APIs [_WIN32_].
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+* 05-06-92 SRW WIN32 LockFile API changed. [_WIN32_].
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <errno.h>
+#include <sys\locking.h>
+#include <io.h>
+#include <stdlib.h>
+#include <internal.h>
+#include <os2dll.h>
+
+/***
+*int _locking(fh,lmode,nbytes) - file record locking function
+*
+*Purpose:
+* Locks or unlocks nbytes of a specified file
+*
+* Multi-thread - Must lock/unlock the file handle to prevent
+* other threads from working on the file at the same time as us.
+* [NOTE: We do NOT release the lock during the 1 second delays
+* since some other thread could get in and do something to the
+* file. The DOSFILELOCK call locks out other processes, not
+* threads, so there is no multi-thread deadlock at the DOS file
+* locking level.]
+*
+*Entry:
+* int fh - file handle
+* int lmode - locking mode:
+* _LK_LOCK/_LK_RLCK -> lock, retry 10 times
+* _LK_NBLCK/_LK_N_BRLCK -> lock, don't retry
+* _LK_UNLCK -> unlock
+* long nbytes - number of bytes to lock/unlock
+*
+*Exit:
+* returns 0 if successful
+* returns -1 and sets errno if unsuccessful
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _locking (
+ int fh,
+ int lmode,
+ long nbytes
+ )
+{
+ ULONG dosretval; /* OS/2 return code */
+ LONG lockoffset;
+ int retry; /* retry count */
+
+ /* validate file handle */
+#ifdef _WIN32_
+ if ( (unsigned)fh >= (unsigned)_nhandle ) {
+#else
+ if ((unsigned)fh >= (unsigned)_nfile) {
+#endif
+ /* fh out of range */
+ errno = EBADF;
+ _doserrno = 0; /* not an OS/2 error */
+ return -1;
+ }
+
+ _lock_fh(fh); /* acquire file handle lock */
+
+ /* obtain current position in file by calling _lseek */
+ /* Use _lseek_lk as we already own lock */
+ lockoffset = _lseek_lk(fh, 0L, 1);
+ if (lockoffset == -1) {
+ _unlock_fh(fh);
+ return -1;
+ }
+
+
+ /* set retry count based on mode */
+ if (lmode == _LK_LOCK || lmode == _LK_RLCK)
+ retry = 9; /* retry 9 times */
+ else
+ retry = 0; /* don't retry */
+
+ /* ask OS/2 to lock the file until success or retry count finished */
+ /* note that the only error possible is a locking violation, since */
+ /* an invalid handle would have already failed above */
+ for (;;) {
+#ifdef _CRUISER_
+ FILELOCK filelock; /* OS/2 file locking structure */
+
+ filelock.lOffset = lockoffset;
+ filelock.lRange = nbytes;
+
+ if (lmode == _LK_UNLCK)
+ dosretval = DOSSETFILELOCKS(fh, &filelock, NULL);
+ else
+ dosretval = DOSSETFILELOCKS(fh, NULL, &filelock);
+
+ if (retry <= 0 || dosretval == 0)
+ break; /* exit loop on success or retry exhausted */
+
+ DOSSLEEP(1000); /* wait 1 sec until try again */
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ dosretval = 0;
+ if (lmode == _LK_UNLCK) {
+ if ( !(UnlockFile((HANDLE)_get_osfhandle(fh),
+ lockoffset,
+ 0L,
+ nbytes,
+ 0L))
+ )
+ dosretval = GetLastError();
+
+ } else {
+ if ( !(LockFile((HANDLE)_get_osfhandle(fh),
+ lockoffset,
+ 0L,
+ nbytes,
+ 0L))
+ )
+ dosretval = GetLastError();
+ }
+
+ if (retry <= 0 || dosretval == 0)
+ break; /* exit loop on success or retry exhausted */
+
+ Sleep(1000L);
+
+#else /* ndef _WIN32_ */
+
+#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+ --retry;
+ }
+
+ _unlock_fh(fh); /* release the file handle lock */
+
+ if (dosretval != 0) {
+ /* OS/2 error occurred -- file was already locked; if a
+ blocking call, then return EDEADLOCK, otherwise map
+ error normally */
+ if (lmode == _LK_LOCK || lmode == _LK_RLCK) {
+ errno = EDEADLOCK;
+ _doserrno = dosretval;
+ }
+ else {
+ _dosmaperr(dosretval);
+ }
+ return -1;
+ }
+ else
+ return 0;
+}
diff --git a/private/crt32/lowio/lseek.c b/private/crt32/lowio/lseek.c
new file mode 100644
index 000000000..bf3524e5f
--- /dev/null
+++ b/private/crt32/lowio/lseek.c
@@ -0,0 +1,187 @@
+/***
+*lseek.c - OS/2 change file position
+*
+* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _lseek() - move the file pointer
+*
+*Revision History:
+* 06-20-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 declarators.
+* 12-04-90 GJF Appended Win32 version with #ifdef-s. It's probably
+* worth coming back and doing a more complete merge later
+* (much later).
+* 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_]
+* 04-09-91 PNT Added _MAC_ conditional
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <os2dll.h>
+#include <io.h>
+#include <internal.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <msdos.h>
+#include <stdio.h>
+
+/***
+*long _lseek(fh,pos,mthd) - move the file pointer
+*
+*Purpose:
+* Moves the file pointer associated with fh to a new position.
+* The new position is pos bytes (pos may be negative) away
+* from the origin specified by mthd.
+*
+* If mthd == SEEK_SET, the origin in the beginning of file
+* If mthd == SEEK_CUR, the origin is the current file pointer position
+* If mthd == SEEK_END, the origin is the end of the file
+*
+* Multi-thread:
+* _lseek() = locks/unlocks the file
+* _lseek_lk() = does NOT lock/unlock the file (it is assumed that
+* the caller has the aquired the file lock,if needed).
+*
+*Entry:
+* int fh - file handle to move file pointer on
+* long pos - position to move to, relative to origin
+* int mthd - specifies the origin pos is relative to (see above)
+*
+*Exit:
+* returns the offset, in bytes, of the new position from the beginning
+* of the file.
+* returns -1L (and sets errno) if fails.
+* Note that seeking beyond the end of the file is not an error.
+* (although seeking before the beginning is.)
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+#ifdef MTHREAD
+
+/* define locking/validating lseek */
+long _CALLTYPE1 _lseek (
+ int fh,
+ long pos,
+ int mthd
+ )
+{
+ int r;
+
+ /* validate fh */
+#ifdef _WIN32_
+ if ( (unsigned)fh >= (unsigned)_nhandle ) {
+#else
+ if ((unsigned)fh >= (unsigned)_nfile) {
+#endif
+ /* bad file handle */
+ errno = EBADF;
+ _doserrno = 0; /* not OS/2 error */
+ return -1;
+ }
+
+ _lock_fh(fh); /* lock file handle */
+ r = _lseek_lk(fh, pos, mthd); /* seek */
+ _unlock_fh(fh); /* unlock file handle */
+
+ return r;
+}
+
+/* define core _lseek -- doesn't lock or validate fh */
+long _CALLTYPE1 _lseek_lk (
+ int fh,
+ long pos,
+ int mthd
+ )
+{
+ ULONG newpos; /* new file position */
+ ULONG dosretval; /* OS/2 return value */
+
+#else
+
+/* define normal _lseek */
+long _CALLTYPE1 _lseek (
+ int fh,
+ long pos,
+ int mthd
+ )
+{
+ ULONG newpos; /* new file position */
+ ULONG dosretval; /* OS/2 return value */
+
+ /* validate fh */
+#ifdef _WIN32_
+ if ( (unsigned)fh >= (unsigned)_nhandle ) {
+#else
+ if ((unsigned)fh >= (unsigned)_nfile) {
+#endif
+ /* bad file handle */
+ errno = EBADF;
+ _doserrno = 0; /* not OS/2 error */
+ return -1;
+ }
+
+#endif
+
+ /* tell OS/2 to seek */
+
+#ifdef _CRUISER_
+
+#if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END
+ #error Xenix and OS/2 seek constants not compatible
+#endif
+
+ dosretval = DOSSETFILEPTR(fh, pos, mthd, &newpos);
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+#if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END
+ #error Xenix and Win32 seek constants not compatible
+#endif
+
+ if ((newpos = SetFilePointer((HANDLE)_get_osfhandle(fh),
+ pos, NULL, mthd)) == -1)
+ dosretval = GetLastError();
+ else
+ dosretval = 0;
+
+#else /* ndef _WIN32_ */
+
+#ifdef _MAC_
+
+ TBD();
+
+#else /* ndef _MAC_ */
+
+#error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED!
+
+#endif /* _MAC_ */
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+ if (dosretval) {
+ /* OS/2 error */
+ _dosmaperr(dosretval);
+ return -1;
+ }
+
+ _osfile[fh] &= ~FEOFLAG; /* clear the ctrl-z flag on the file */
+ return newpos; /* return */
+}
diff --git a/private/crt32/lowio/makefile b/private/crt32/lowio/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/crt32/lowio/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/crt32/lowio/mktemp.c b/private/crt32/lowio/mktemp.c
new file mode 100644
index 000000000..a4d827ecf
--- /dev/null
+++ b/private/crt32/lowio/mktemp.c
@@ -0,0 +1,115 @@
+/***
+*mktemp.c - create a unique file name
+*
+* Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _mktemp() - create a unique file name
+*
+*Revision History:
+* 06-02-86 JMB eliminated unneccesary routine exits
+* 05-26-87 JCR fixed bug where mktemp was incorrectly modifying
+* the errno value.
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 07-11-88 JCR Optimized REG allocation
+* 03-12-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h>, removed #include <register.h> and
+* fixed the copyright. Also, cleaned up the formatting
+* a bit.
+* 04-04-90 GJF Added #include <process.h> and #include <io.h>. Removed
+* #include <sizeptr.h>.
+* 07-23-90 SBM Replaced <assertm.h> by <assert.h>
+* 08-13-90 SBM Compiles cleanly with -W3
+* 09-28-90 GJF New-style function declarator.
+* 01-16-91 GJF ANSI naming.
+* 11-30-92 KRS Ported _MBCS code from 16-bit tree.
+* 06-18-93 KRS MBCS-only bug fix ported from 16-bit tree.
+* 08-03-93 KRS Call _ismbstrail instead of isdbcscode.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <stdio.h>
+#include <io.h>
+#include <process.h>
+#include <errno.h>
+#include <assert.h>
+#include <stddef.h>
+#ifdef _MBCS
+#include <mbctype.h>
+#include <mbdata.h>
+#endif
+
+/***
+*char *_mktemp(template) - create a unique file name
+*
+*Purpose:
+* given a template of the form "fnamXXXXXX", insert number on end
+* of template, insert unique letter if needed until unique filename
+* found or run out of letters
+#ifdef OS2_COMMENT
+* Note: this version can be used for both DOS 3 and OS/2
+#endif
+*
+*Entry:
+* char *template - template of form "fnamXXXXXX"
+*
+*Exit:
+* return pointer to modifed template
+* returns NULL if template malformed or no more unique names
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+char * _CALLTYPE1 _mktemp (
+ char *template
+ )
+{
+ REG1 char *string = template;
+ REG3 unsigned number;
+ int letter = 'a';
+ REG2 int xcount = 0;
+ int olderrno;
+
+ assert(template != NULL);
+ assert(*template != '\0');
+
+ number = _getpid();
+
+ while (*string)
+ string++;
+
+#ifdef _MBCS
+ while ((--string>=template) && (!_ismbstrail(template,string))
+ && (*string == 'X'))
+#else
+ while (*--string == 'X')
+#endif
+ {
+ xcount++;
+ *string = (char)((number % 10) + '0');
+ number /= 10;
+ }
+
+ if (*++string == '\0' || xcount != 6 )
+ return(NULL);
+
+ olderrno = errno; /* save current errno */
+ errno = 0; /* make sure errno isn't EACCESS */
+
+ while ((_access(template,0) == 0) || (errno == EACCES))
+ /* while file exists */
+ {
+ errno = 0;
+ if (letter == 'z'+1) {
+ errno = olderrno;
+ return(NULL);
+ }
+
+ *string = (char)letter++;
+ }
+
+ errno = olderrno;
+ return(template);
+}
diff --git a/private/crt32/lowio/open.c b/private/crt32/lowio/open.c
new file mode 100644
index 000000000..a365f4aac
--- /dev/null
+++ b/private/crt32/lowio/open.c
@@ -0,0 +1,590 @@
+/***
+*open.c - file open
+*
+* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _open() and _sopen() - open or create a file
+*
+*Revision History:
+* 06-13-89 PHG Module created, based on asm version
+* 11-11-89 JCR Replaced DOS32QUERYFILEMODE with DOS32QUERYPATHINFO
+* 03-13-90 GJF Made calling type _CALLTYPE2 (for now), added #include
+* <cruntime.h>, fixed some compiler warnings and fixed
+* copyright. Also, cleaned up the formatting a bit.
+* 07-24-90 SBM Removed '32' from API names
+* 08-14-90 SBM Compiles cleanly with -W3
+* 09-07-90 SBM Added stdarg code (inside #if 0..#endif) to make
+* open and sopen match prototypes. Test and use this
+* someday.
+* 10-01-90 GJF New-style function declarators.
+* 11-16-90 GJF Wrote version for Win32 API and appended it via an
+* #ifdef. The Win32 version is similar to the old DOS
+* version (though in C) and far different from either
+* the Cruiser or OS/2 versions.
+* 12-03-90 GJF Fixed a dozen or so minor errors in the Win32 version.
+* 12-06-90 SRW Changed to use _osfile and _osfhnd instead of _osfinfo
+* 12-28-90 SRW Added cast of void * to char * for Mips C Compiler
+* 12-31-90 SRW Fixed spen to call CreateFile instead of OpenFile
+* 01-16-91 GJF ANSI naming.
+* 02-07-91 SRW Changed to call _get_osfhandle [_WIN32_]
+* 02-19-91 SRW Adapt to OpenFile/CreateFile changes [_WIN32_]
+* 02-25-91 SRW Renamed _get_free_osfhnd to be _alloc_osfhnd [_WIN32_]
+* 04-09-91 PNT Added _MAC_ conditional
+* 07-10-91 GJF Store fileflags into _osfile array before call to
+* _lseek_lk (bug found by LarryO) [_WIN32_].
+* 01-02-92 GJF Fixed Win32 version (not Cruiser!) so that pmode is not
+* referenced unless _O_CREAT has been specified.
+* 02-04-92 GJF Make better use of CreateFile options.
+* 04-06-92 SRW Pay attention to _O_NOINHERIT flag in oflag parameter
+* 05-02-92 SRW Add support for _O_TEMPORARY flag in oflag parameter.
+* Causes FILE_ATTRIBUTE_TEMPORARY flag to be set in call
+* to the Win32 CreateFile API.
+* 07-01-92 GJF Close handle in case of error. Also, don't try to set
+* FRDONLY bit anymore - no longer needed/used. [_WIN32_].
+* 01-03-93 SRW Fix va_arg/va_end usage
+* 05-24-93 PML Add support for _O_SEQUENTIAL, _O_RANDOM,
+* and _O_SHORT_LIVED
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <msdos.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <internal.h>
+#include <io.h>
+#include <share.h>
+#include <stdlib.h>
+#include <sys\types.h>
+#include <sys\stat.h>
+#include <os2dll.h>
+#include <stdarg.h>
+
+/***
+*int _open(path, flag, pmode) - open or create a file
+*
+*Purpose:
+* Opens the file and prepares for subsequent reading or writing.
+* the flag argument specifies how to open the file:
+* _O_APPEND - reposition file ptr to end before every write
+* _O_BINARY - open in binary mode
+* _O_CREAT - create a new file* no effect if file already exists
+* _O_EXCL - return error if file exists, only use with O_CREAT
+* _O_RDONLY - open for reading only
+* _O_RDWR - open for reading and writing
+* _O_TEXT - open in text mode
+* _O_TRUNC - open and truncate to 0 length (must have write permission)
+* _O_WRONLY - open for writing only
+* _O_NOINHERIT -handle will not be inherited by child processes.
+* exactly one of _O_RDONLY, _O_WRONLY, _O_RDWR must be given
+*
+* The pmode argument is only required when _O_CREAT is specified. Its
+* flag settings:
+* _S_IWRITE - writing permitted
+* _S_IREAD - reading permitted
+* _S_IREAD | _S_IWRITE - both reading and writing permitted
+* The current file-permission maks is applied to pmode before
+* setting the permission (see umask).
+*
+* The oflag and mode parameter have different meanings under DOS. See
+* the A_xxx attributes in msdos.inc
+*
+* Note, the _creat() function also uses this function but setting up the
+* correct arguments and calling _open(). _creat() sets the __creat_flag
+* to 1 prior to calling _open() so _open() can return correctly. _open()
+* returns the file handle in eax in this case.
+*
+*Entry:
+* char *path - file name
+* int flag - flags for _open()
+* int pmode - permission mode for new files
+*
+*Exit:
+* returns file handle of open file if successful
+* returns -1 (and sets errno) if fails
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CRTAPI2 _open (
+ const char *path,
+ int oflag,
+ ...
+ )
+{
+ va_list ap;
+ int pmode;
+
+ va_start(ap, oflag);
+ pmode = va_arg(ap, int);
+ va_end(ap);
+
+ /* default sharing mode is DENY NONE */
+ return _sopen(path, oflag, _SH_DENYNO, pmode);
+}
+
+/***
+*int _sopen(path, oflag, shflag, pmode) - opne a file with sharing
+*
+*Purpose:
+* Opens the file with possible file sharing.
+* shflag defines the sharing flags:
+* _SH_COMPAT - set compatability mode
+* _SH_DENYRW - deny read and write access to the file
+* _SH_DENYWR - deny write access to the file
+* _SH_DENYRD - deny read access to the file
+* _SH_DENYNO - permit read and write access
+*
+* Other flags are the same as _open().
+*
+* SOPEN is the routine used when file sharing is desired.
+*
+*Entry:
+* char *path - file to open
+* int oflag - open flag
+* int shflag - sharing flag
+* int pmode - permission mode (needed only when creating file)
+*
+*Exit:
+* returns file handle for the opened file
+* returns -1 and sets errno if fails.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CRTAPI2 _sopen (
+ const char *path,
+ int oflag,
+ int shflag,
+ ...
+ )
+{
+
+ int fh; /* handle of opened file */
+ int filepos; /* length of file - 1 */
+ char ch; /* character at end of file */
+ char fileflags; /* _osfile flags */
+ va_list ap; /* variable argument (pmode) */
+ int pmode;
+
+#ifdef _CRUISER_
+ int t; /* temp */
+ int dosretval; /* OS/2 return value */
+ int isdev; /* device indicator in low byte */
+ int attrib; /* attribute */
+ int openflag; /* OS/2 open flag */
+ int openmode; /* OS/2 open mode */
+#endif /* _CRUISER_ */
+
+#ifdef _WIN32_
+ HANDLE osfh; /* OS handle of opened file */
+ DWORD fileaccess; /* OS file access (requested) */
+ DWORD fileshare; /* OS file sharing mode */
+ DWORD filecreate; /* OS method of opening/creating */
+ DWORD fileattrib; /* OS file attribute flags */
+ DWORD isdev; /* device indicator in low byte */
+ SECURITY_ATTRIBUTES SecurityAttributes;
+
+ SecurityAttributes.nLength = sizeof( SecurityAttributes );
+ SecurityAttributes.lpSecurityDescriptor = NULL;
+ if (oflag & _O_NOINHERIT) {
+ SecurityAttributes.bInheritHandle = FALSE;
+ }
+ else {
+ SecurityAttributes.bInheritHandle = TRUE;
+ }
+
+#endif /* _WIN32_ */
+#ifdef _CRUISER_
+/* Set up variable argument list stuff */
+
+ va_start(ap, shflag);
+ pmode = va_arg(ap, int);
+ va_end(ap);
+#endif
+
+ /* figure out binary/text mode */
+ if (oflag & _O_BINARY)
+ fileflags = 0;
+ else if (oflag & _O_TEXT)
+ fileflags = (char)FTEXT;
+ else if (_fmode == _O_BINARY) /* check default mode */
+ fileflags = 0;
+ else
+ fileflags = (char)FTEXT;
+
+#ifdef _CRUISER_ /* CRUISER TARGET */
+
+/* code requires below conditions */
+#if _O_RDONLY != OPEN_ACCESS_READONLY || _O_WRONLY != OPEN_ACCESS_WRITEONLY || _O_RDWR != OPEN_ACCESS_READWRITE
+ #error OS/2 and XENIX flags not compatible
+#endif
+#if _O_RDWR != 2 || _O_RDONLY != 0 || _O_WRONLY != 1
+ #error access flags are wrong
+#endif
+
+/*
+ Set up the OpenMode and OpenFlag parameters for the DOSOPEN call
+
+ OpenMode fields will be set as follows:
+ high byte
+ DASD 0 (normal file)
+ File Write-through 0 (use buffer cache)
+ Fail-Errors 0 (use hard error handler)
+ low byte
+ Inheritance 0 (child inherits files)
+ Sharing Mode <from shflag param>
+ Access Mode <from oflag parameter>
+
+ OpenFlag bytes are set as follows:
+ high byte
+ 0x00
+ low byte - low nibble
+ 0x0 _O_EXCL specified
+ 0x2 _O_TRUNC specified
+ 0x1 otherwise
+ low byte - high nibble
+ 0x1 _O_CREAT specified
+ 0x0 otherwise
+*/
+
+
+ /* first, convert the permission mode to the DOS attribute byte */
+ if ((pmode & ~_umaskval) & _S_IWRITE)
+ attrib = 0; /* writable */
+ else
+ attrib = FILE_READONLY; /* read-only */
+
+ if ((oflag & _O_EXCL) && !(oflag & _O_CREAT))
+ oflag &= ~_O_EXCL; /* _O_EXCL only works with _O_CREAT */
+
+ if (oflag & _O_EXCL) {
+ openflag = 0; /* just create */
+ }
+ else if (oflag & _O_TRUNC) {
+ FILESTATUS fs; /* File Status structure */
+
+ openflag = FILE_TRUNCATE; /* truncate file */
+
+ /* if the file exists, don't change its attribute */
+ if (!DOSQUERYPATHINFO((char *)path, 1, &fs, sizeof(fs)))
+ /* file exists, use current attribute */
+ attrib = fs.attrFile;
+ }
+ else
+ openflag = FILE_OPEN; /* open the file */
+
+ if (oflag & _O_CREAT)
+ openflag |= FILE_CREATE;
+
+ /* here we take advantage of the fact that OS/2 and XENIX access flags
+ are the same bits -- the bottom two */
+ openmode = shflag | (oflag & 3);
+
+ /* OK, we're now ready to open the file */
+ if (dosretval = DOSOPEN((char *)path, &fh, &t, 0, attrib, openflag,
+ openmode, 0, 0)) {
+ /* OS/2 error occured */
+ if (dosretval == ERROR_OPEN_FAILED) {
+ _doserrno = dosretval;
+ if (openflag & FILE_CREATE)
+ errno = EEXIST; /* file existed */
+ else
+ errno = ENOENT; /* file didn't exist */
+ return -1;
+ }
+ else {
+ _dosmaperr(dosretval); /* map error */
+ return -1;
+ }
+ }
+
+ if ((unsigned)fh >= (unsigned)_nfile) {
+ /* handle is out of range; close and return EMFILE */
+ DOSCLOSE(fh);
+ errno = EMFILE;
+ _doserrno = 0; /* not OS/2 error */
+ return -1;
+ }
+
+ _lock_fh(fh); /* lock the file handle */
+
+ /* find out what type of file (file/device/pipe) */
+ if (dosretval = DOSQUERYHTYPE(fh, &isdev, &t)) {
+ /* OS/2 error */
+ _unlock_fh(fh);
+ _dosmaperr(dosretval); /* map error */
+ return -1;
+ }
+
+ /* is isdev value to set flags */
+ if ((isdev & 0xFF) == HANDTYPE_DEVICE)
+ fileflags |= FDEV;
+ else if ((isdev & 0xFF) == HANDTYPE_PIPE)
+ fileflags |= FPIPE;
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ /*
+ * decode the access flags
+ */
+ switch( oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR) ) {
+
+ case _O_RDONLY: /* read access */
+ fileaccess = GENERIC_READ;
+ break;
+ case _O_WRONLY: /* write access */
+ fileaccess = GENERIC_WRITE;
+ break;
+ case _O_RDWR: /* read and write access */
+ fileaccess = GENERIC_READ | GENERIC_WRITE;
+ break;
+ default: /* error, bad oflag */
+ errno = EINVAL;
+ _doserrno = 0L; /* not an OS error */
+ return -1;
+ }
+
+ /*
+ * decode sharing flags
+ */
+ switch ( shflag ) {
+
+ case _SH_DENYRW: /* exclusive access */
+ fileshare = 0L;
+ break;
+
+ case _SH_DENYWR: /* share read access */
+ fileshare = FILE_SHARE_READ;
+ break;
+
+ case _SH_DENYRD: /* share write access */
+ fileshare = FILE_SHARE_WRITE;
+ break;
+
+ case _SH_DENYNO: /* share read and write access */
+ fileshare = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ break;
+
+ default: /* error, bad shflag */
+ errno = EINVAL;
+ _doserrno = 0L; /* not an OS error */
+ return -1;
+ }
+
+ /*
+ * decode open/create method flags
+ */
+ switch ( oflag & (_O_CREAT | _O_EXCL | _O_TRUNC) ) {
+ case 0:
+ filecreate = OPEN_EXISTING;
+ break;
+
+ case _O_CREAT:
+ filecreate = OPEN_ALWAYS;
+ break;
+
+ case _O_CREAT | _O_EXCL:
+ filecreate = CREATE_NEW;
+ break;
+
+ case _O_TRUNC:
+ filecreate = TRUNCATE_EXISTING;
+ break;
+
+ case _O_CREAT | _O_TRUNC:
+ filecreate = CREATE_ALWAYS;
+ break;
+
+ default:
+ errno = EINVAL;
+ _doserrno = 0L;
+ return -1;
+ }
+
+ /*
+ * decode file attribute flags if _O_CREAT was specified
+ */
+ fileattrib = FILE_ATTRIBUTE_NORMAL; /* default */
+
+ if ( oflag & _O_CREAT ) {
+ /*
+ * set up variable argument list stuff
+ */
+ va_start(ap, shflag);
+ pmode = va_arg(ap, int);
+ va_end(ap);
+
+ if ( !((pmode & ~_umaskval) & _S_IWRITE) )
+ fileattrib = FILE_ATTRIBUTE_READONLY;
+ }
+
+ /*
+ * Set temporary file (delete-on-close) attribute if requested.
+ */
+ if ( oflag & _O_TEMPORARY ) {
+ fileattrib |= FILE_FLAG_DELETE_ON_CLOSE;
+ fileaccess |= DELETE;
+ }
+
+ /*
+ * Set temporary file (delay-flush-to-disk) attribute if requested.
+ */
+ if ( oflag & _O_SHORT_LIVED )
+ fileattrib |= FILE_ATTRIBUTE_TEMPORARY;
+
+ /*
+ * Set sequential or random access attribute if requested.
+ */
+ if ( oflag & _O_SEQUENTIAL )
+ fileattrib |= FILE_FLAG_SEQUENTIAL_SCAN;
+ else if ( oflag & _O_RANDOM )
+ fileattrib |= FILE_FLAG_RANDOM_ACCESS;
+
+ /*
+ * get an available handle.
+ *
+ * multi-thread note: the returned handle is locked!
+ */
+ if ( (fh = _alloc_osfhnd()) == -1 ) {
+ errno = EMFILE; /* too many open files */
+ _doserrno = 0L; /* not an OS error */
+ return -1; /* return error to caller */
+ }
+
+ /*
+ * try to open/create the file
+ */
+ if ( (osfh = CreateFile((LPSTR)path,
+ fileaccess,
+ fileshare,
+ &SecurityAttributes,
+ filecreate,
+ fileattrib,
+ NULL
+ ))
+ == (HANDLE)0xffffffff ) {
+ /*
+ * OS call to open/create file failed! map the error, release
+ * the lock, and return -1. note that it's not necessary to
+ * call _free_osfhnd (it hasn't been used yet).
+ */
+ _dosmaperr(GetLastError()); /* map error */
+ _unlock_fh(fh);
+ return -1; /* return error to caller */
+ }
+
+ /* find out what type of file (file/device/pipe) */
+ if ( (isdev = GetFileType(osfh)) == FILE_TYPE_UNKNOWN ) {
+ CloseHandle(osfh);
+ _dosmaperr(GetLastError()); /* map error */
+ _unlock_fh(fh);
+ return -1;
+ }
+
+ /* is isdev value to set flags */
+ if (isdev == FILE_TYPE_CHAR)
+ fileflags |= FDEV;
+ else if (isdev == FILE_TYPE_PIPE)
+ fileflags |= FPIPE;
+
+ /*
+ * the file is open. now, set the info in _osfhnd array
+ */
+ _set_osfhnd(fh, (long)osfh);
+
+#else /* ndef _WIN32_ */
+
+#ifdef _MAC_
+
+ TBD();
+
+#else /* ndef _MAC_ */
+
+#error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED!
+
+#endif /* _MAC_ */
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+ /*
+ * mark the handle as open. store flags gathered so far in _osfile
+ * array.
+ */
+ fileflags |= FOPEN;
+ _osfile[fh] = fileflags;
+
+ if (!(fileflags & (FDEV|FPIPE)) && (fileflags & FTEXT) &&
+ (oflag & _O_RDWR)) {
+ /* We have a text mode file. If it ends in CTRL-Z, we wish to
+ remove the CTRL-Z character, so that appending will work.
+ We do this by seeking to the end of file, reading the last
+ byte, and shortening the file if it is a CTRL-Z. */
+
+ if ((filepos = _lseek_lk(fh, -1, FILE_END)) == -1) {
+ /* OS error -- should ignore negative seek error,
+ since that means we had a zero-length file. */
+ if (_doserrno != ERROR_NEGATIVE_SEEK) {
+ _close(fh);
+ _unlock_fh(fh);
+ return -1;
+ }
+ }
+ else {
+ /* seek was OK, read the last char in file */
+ if (_read_lk(fh, &ch, 1) == 1 && ch == 26) {
+ /* read was OK and we got CTRL-Z! Wipe it
+ out! */
+ if (_chsize_lk(fh,filepos) == -1)
+ {
+ _close(fh);
+ _unlock_fh(fh);
+ return -1;
+ }
+ }
+
+ /* now rewind the file to the beginning */
+ if ((filepos = _lseek_lk(fh, 0, FILE_BEGIN)) == -1) {
+ _close(fh);
+ _unlock_fh(fh);
+ return -1;
+ }
+ }
+ }
+
+#ifdef _CRUISER_
+ /* We want to know if we have write access to set the FRDONLY flag
+ in the _osfile entry. We also set the FAPPEND flag.
+ Don't do this for pipes or devices. */
+
+ if (!(fileflags & (FDEV|FPIPE))) {
+ if (_access((char *)path, 2) == -1)
+ _osfile[fh] |= FRDONLY;
+
+ if (oflag & _O_APPEND)
+ _osfile[fh] |= FAPPEND;
+ }
+#else /* ndef _CRUISER_ */
+#ifdef _WIN32_
+
+ /*
+ * Set FAPPEND flag if appropriate. Don't do this for devices or pipes.
+ */
+ if ( !(fileflags & (FDEV|FPIPE)) && (oflag & _O_APPEND) )
+ _osfile[fh] |= FAPPEND;
+
+#endif /* _WIN32_ */
+#endif /* _CRUISER_*/
+
+ _unlock_fh(fh); /* unlock handle */
+
+ return fh; /* return handle */
+}
diff --git a/private/crt32/lowio/osfinfo.c b/private/crt32/lowio/osfinfo.c
new file mode 100644
index 000000000..8ccff39c4
--- /dev/null
+++ b/private/crt32/lowio/osfinfo.c
@@ -0,0 +1,319 @@
+/***
+*osfinfo.c - Win32 _osfhnd[] support routines
+*
+* Copyright (c) 1990-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* Defines the internally used routine _alloc_osfhnd()
+* and the user visible routine _get_osfhandle().
+*
+*Revision History:
+* 11-16-90 GJF What can I say? The custom heap business was getting
+* a little slow...
+* 12-03-90 GJF Fixed my stupid syntax errors.
+* 12-06-90 SRW Changed to use _osfile and _osfhnd instead of _osfinfo
+* 12-28-90 SRW Added cast of void * to char * for Mips C Compiler
+* 02-18-91 SRW Fixed bug in _alloc_osfhnd with setting FOPEN bit
+* (only caller should do that) [_WIN32_]
+* 02-18-91 SRW Fixed bug in _alloc_osfhnd with checking against
+* _NFILE_ instead of _nfile [_WIN32_]
+* 02-18-91 SRW Added debug output to _alloc_osfhnd if out of
+* file handles. [_WIN32_]
+* 02-25-91 SRW Renamed _get_free_osfhnd to be _alloc_osfhnd [_WIN32_]
+* 02-25-91 SRW Exposed _get_osfhandle and _open_osfhandle [_WIN32_]
+* 08-08-91 GJF Use ANSI-fied form of constant names.
+* 11-25-91 GJF Lock fh before checking whether it's free.
+* 12-31-91 GJF Improved multi-thread lock usage [_WIN32_].
+* 02-13-92 GJF Replaced _nfile with _nhandle
+* 07-15-92 GJF Fixed setting of flags in _open_osfhnd.
+* 02-19-93 GJF If GetFileType fails in _open_osfhandle, don't unlock
+* fh (it wasn't locked)!
+*
+*******************************************************************************/
+
+#ifdef _WIN32_
+
+#include <cruntime.h>
+#include <errno.h>
+#include <internal.h>
+#include <fcntl.h>
+#include <msdos.h>
+#include <os2dll.h>
+#include <stdlib.h>
+#include <oscalls.h>
+
+/***
+*int _alloc_osfhnd() - get free _osfhnd[] entry
+*
+*Purpose:
+* Finds the first free entry in _osfhnd[], mark it in use and return
+* the index of the entry to the caller.
+*
+*Entry:
+* none
+*
+*Exit:
+* returns index of entry in fh, if successful
+* return -1, if no free entry is found in _osfhnd[].
+*
+* MULTITHREAD NOTE: IF SUCCESSFUL, THE HANDLE IS LOCKED WHEN IT IS
+* RETURNED TO THE CALLER!
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CRTAPI1 _alloc_osfhnd(
+ void
+ )
+{
+ int fh; /* _osfhnd[] index */
+
+ _mlock(_OSFHND_LOCK); /* lock the _osfhnd[] table */
+
+ /*
+ * search _osfhnd[] for an entry that is not currently being used.
+ * if one is found, mark it in use and set the _osfhandle field to
+ * INVALID_HANDLE_VALUE.
+ */
+ for ( fh = 0 ; fh < _nhandle ; fh++ ) {
+ if ( (_osfile[fh] & FOPEN) == 0 ) {
+#ifdef MTHREAD
+ _lock_fh(fh);
+
+ /*
+ * make sure the entry is still free
+ */
+ if ( (_osfile[fh] & FOPEN) != 0 ) {
+ /*
+ * entry now in use! release the lock and
+ * continue looping.
+ */
+ _unlock_fh(fh);
+ continue;
+ }
+#endif
+
+ /*
+ * free entry found! initialize it and
+ * break out of the loop
+ */
+ _osfhnd[fh] = (long)INVALID_HANDLE_VALUE;
+ break;
+ }
+ }
+
+ _munlock(_OSFHND_LOCK); /* unlock the _osfhnd[] table */
+
+#if defined(DEBUG) && defined(_WIN32_)
+ if (fh >= _nhandle) {
+ DbgPrint( "WINCRT: more than %d open files\n", _nhandle );
+ }
+#endif
+
+ /*
+ * return the index of the previously free table entry, if one was
+ * found. return -1 otherwise.
+ */
+ return( (fh >= _nhandle) ? -1 : fh );
+}
+
+
+/***
+*int _set_osfhnd(int fh) - set OS file handle table value
+*
+*Purpose:
+* If fh is in range and if _osfhnd[fh] is marked with
+* INVALID_HANDLE_VALUE then set _osfhnd[fh] to the passed value.
+*
+*Entry:
+* int fh - index of _osfhnd[] entry
+* long fh - new value of this handle entry
+*
+*Exit:
+* Returns zero if successful.
+* Returns -1 and sets errno to EBADF otherwise.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CRTAPI1 _set_osfhnd (
+ int fh, /* index into _osfhnd[] (user's file handle) */
+ long value
+ )
+{
+ if ( ((unsigned)fh < (unsigned)_nhandle) &&
+ (_osfhnd[fh] == (long)INVALID_HANDLE_VALUE)
+ ) {
+ switch (fh) {
+ case 0: SetStdHandle( STD_INPUT_HANDLE, (HANDLE)value ); break;
+ case 1: SetStdHandle( STD_OUTPUT_HANDLE, (HANDLE)value ); break;
+ case 2: SetStdHandle( STD_ERROR_HANDLE, (HANDLE)value ); break;
+ }
+
+ _osfhnd[fh] = value;
+ return(0);
+ } else {
+ errno = EBADF; /* bad handle */
+ _doserrno = 0L; /* not an OS error */
+ return -1;
+ }
+}
+
+
+/***
+*int _free_osfhnd(int fh) - free OS file handle table entry
+*
+*Purpose:
+* If fh is in range and if _osfhnd[fh] is in use and NOT marked
+* with 0xfffffff
+*
+*Entry:
+* int fh - index of _osfhnd[] entry
+*
+*Exit:
+* Returns zero if successful.
+* Returns -1 and sets errno to EBADF otherwise.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CRTAPI1 _free_osfhnd (
+ int fh /* index into _osfhnd[] (user's file handle) */
+ )
+{
+ if ( ((unsigned)fh < (unsigned)_nhandle) &&
+ (_osfile[fh] & FOPEN) &&
+ (_osfhnd[fh] != (long)INVALID_HANDLE_VALUE)
+ ) {
+ switch (fh) {
+ case 0: SetStdHandle( STD_INPUT_HANDLE, NULL ); break;
+ case 1: SetStdHandle( STD_OUTPUT_HANDLE, NULL ); break;
+ case 2: SetStdHandle( STD_ERROR_HANDLE, NULL ); break;
+ }
+
+ _osfhnd[fh] = (long)INVALID_HANDLE_VALUE;
+ return(0);
+ } else {
+ errno = EBADF; /* bad handle */
+ _doserrno = 0L; /* not an OS error */
+ return -1;
+ }
+}
+
+
+/***
+*long _get_osfhandle(int fh) - get OS file handle
+*
+*Purpose:
+* If fh is in range and if _osfhnd[fh] is marked free, return
+* _osfhnd[fh]
+*
+*Entry:
+* int fh - index of _osfhnd[] entry
+*
+*Exit:
+* Returns the OS file handle if successful.
+* Returns -1 and sets errno to EBADF otherwise.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+long _CRTAPI1 _get_osfhandle (
+ int fh /* index into _osfhnd[] (user's file handle) */
+ )
+{
+ if ( ((unsigned)fh < (unsigned)_nhandle) && (_osfile[fh] & FOPEN) )
+ return(_osfhnd[fh]);
+ else {
+ errno = EBADF; /* bad handle */
+ _doserrno = 0L; /* not an OS error */
+ return -1;
+ }
+}
+
+/***
+*int _open_osfhandle(long osfhandle, int flags) - open C Runtime file handle
+*
+*Purpose:
+* This function allocates a free C Runtime file handle and sets it
+* to point to the Win32 file handle specified by the first parameter.
+*
+*Entry:
+* long osfhandle -Win32 file handle to associate with C Runtime file handle.
+* int flags - flags to associate with C Runtime file handle.
+*
+*Exit:
+* returns index of entry in fh, if successful
+* return -1, if no free entry is found in _osfhnd[].
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CRTAPI1 _open_osfhandle(
+ long osfhandle,
+ int flags
+ )
+{
+ int fh;
+ char fileflags; /* _osfile flags */
+ DWORD isdev; /* device indicator in low byte */
+
+ /* copy relevant flags from second parameter */
+
+ fileflags = 0;
+
+ if ( flags & _O_APPEND )
+ fileflags |= FAPPEND;
+
+ if ( flags & _O_TEXT )
+ fileflags |= FTEXT;
+
+ /* find out what type of file (file/device/pipe) */
+
+ isdev = GetFileType((HANDLE)osfhandle);
+ if (isdev == FILE_TYPE_UNKNOWN) {
+ /* OS error */
+ _dosmaperr( GetLastError() ); /* map error */
+ return -1;
+ }
+
+ /* is isdev value to set flags */
+ if (isdev == FILE_TYPE_CHAR)
+ fileflags |= FDEV;
+ else if (isdev == FILE_TYPE_PIPE)
+ fileflags |= FPIPE;
+
+
+ /* attempt to allocate a C Runtime file handle */
+
+ if ( (fh = _alloc_osfhnd()) == -1 ) {
+ errno = EMFILE; /* too many open files */
+ _doserrno = 0L; /* not an OS error */
+ return -1; /* return error to caller */
+ }
+
+ /*
+ * the file is open. now, set the info in _osfhnd array
+ */
+
+ _set_osfhnd(fh, osfhandle);
+
+ fileflags |= FOPEN; /* mark as open */
+
+ _osfile[fh] = fileflags; /* set osfile entry */
+
+ _unlock_fh(fh); /* unlock handle */
+
+ return fh; /* return handle */
+}
+
+#else
+
+#error ERROR - WIN32 TARGET ONLY!
+
+#endif
diff --git a/private/crt32/lowio/pipe.c b/private/crt32/lowio/pipe.c
new file mode 100644
index 000000000..a414d1c40
--- /dev/null
+++ b/private/crt32/lowio/pipe.c
@@ -0,0 +1,180 @@
+/***
+*pipe.c - create a pipe
+*
+* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _pipe() - creates a pipe (i.e., an I/O channel for interprocess
+* communication)
+*
+*Revision History:
+* 06-20-89 PHG Module created, based on asm version
+* 03-13-90 GJF Made calling type _CALLTYPE2 (for now), added #include
+* <cruntime.h> and fixed 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
+* 10-01-90 GJF New-style function declarator.
+* 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
+* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
+* 01-18-91 GJF ANSI naming.
+* 02-18-91 SRW Added _WIN32_ implementation [_WIN32_]
+* 02-25-91 SRW Renamed _get_free_osfhnd to be _alloc_osfhnd [_WIN32_]
+* 03-13-91 SRW Fixed _pipe so it works [_WIN32_]
+* 03-18-91 SRW Fixed _pipe NtCreatePipe handles are inherited [_WIN32_]
+* 04-06-92 SRW Pay attention to _O_NOINHERIT flag in oflag parameter
+* 01-10-93 GJF Fixed bug in checking for _O_BINARY (inadvertently
+* introduced by SRW's change above).
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <os2dll.h>
+#include <io.h>
+#include <internal.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <msdos.h>
+#include <fcntl.h>
+
+/***
+*int _pipe(phandles, psize, textmode) - open a pipe
+*
+*Purpose:
+* Checks if the given handle is associated with a character device
+* (terminal, console, printer, serial port)
+*
+* Multi-thread notes: No locking is performed or deemed necessary. The
+* handles returned by DOSCREATEPIPE are newly opened and, therefore,
+* should not be referenced by any thread until after the _pipe call is
+* complete. The function is not protected from some thread of the caller
+* doing, say, output to a previously invalid handle that becomes one of
+* the pipe handles. However, any such program is doomed anyway and
+* protecting the _pipe function such a case would be of little value.
+*
+*Entry:
+* int phandle[2] - array to hold returned read (phandle[0]) and write
+* (phandle[1]) handles
+*
+* unsigned psize - amount of memory, in bytes, to ask OS/2 to reserve
+* for the pipe
+*
+* int textmode - _O_TEXT, _O_BINARY, _O_NOINHERIT, or 0 (use default)
+*
+*Exit:
+* returns 0 if successful
+* returns -1 if an error occurs in which case, errno is set to:
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CRTAPI1 _pipe (
+ int phandles[2],
+ unsigned psize,
+ int textmode
+ )
+{
+ ULONG dosretval; /* OS/2 return value */
+
+#ifdef _CRUISER_
+
+ if (dosretval = DOSCREATEPIPE(&phandles[0], &phandles[1], psize)) {
+ /* OS/2 error */
+ _dosmaperr(dosretval);
+ return -1;
+ }
+
+ if ((unsigned)phandles[0] >= (unsigned)_nfile ||
+ (unsigned)phandles[1] >= (unsigned)_nfile)
+ {
+ /* one or both of the handles are too large -- close both */
+ DOSCLOSE(phandles[0]);
+ DOSCLOSE(phandles[1]);
+ errno = EMFILE; /* too many files */
+ _doserrno = 0; /* not an OS/2 error */
+ return -1;
+ }
+
+ /* now we must set the _osfile values */
+ if (textmode == _O_BINARY || (textmode == 0 && _fmode == _O_BINARY)) {
+ /* binary mode */
+ _osfile[phandles[0]] = _osfile[phandles[1]] = FOPEN | FPIPE;
+ }
+ else {
+ /* text mode */
+ _osfile[phandles[0]] = _osfile[phandles[1]] = FOPEN | FPIPE |
+ FTEXT;
+ }
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+ HANDLE ReadHandle, WriteHandle;
+ SECURITY_ATTRIBUTES SecurityAttributes;
+
+ SecurityAttributes.nLength = sizeof(SecurityAttributes);
+ SecurityAttributes.lpSecurityDescriptor = NULL;
+ if (textmode & _O_NOINHERIT) {
+ SecurityAttributes.bInheritHandle = FALSE;
+ }
+ else {
+ SecurityAttributes.bInheritHandle = TRUE;
+ }
+ if (!CreatePipe(&ReadHandle, &WriteHandle, &SecurityAttributes, psize)) {
+ /* OS/2 error */
+ dosretval = GetLastError();
+ _dosmaperr(dosretval);
+ return -1;
+ }
+
+ /* now we must allocate C Runtime handles for Read and Write handles */
+ if ((phandles[0] = _alloc_osfhnd()) != -1) {
+ _osfile[phandles[0]] = (char)(FOPEN | FPIPE | FTEXT);
+ if ((phandles[1] = _alloc_osfhnd()) != -1) {
+ _osfile[phandles[1]] = (char)(FOPEN | FPIPE | FTEXT);
+ if ( (textmode & _O_BINARY) ||
+ ((textmode & _O_TEXT == 0) &&
+ (_fmode == _O_BINARY)) ) {
+ /* binary mode */
+ _osfile[phandles[0]] &= ~FTEXT;
+ _osfile[phandles[1]] &= ~FTEXT;
+ }
+
+ _set_osfhnd(phandles[0], (long)ReadHandle);
+ _set_osfhnd(phandles[1], (long)WriteHandle);
+ errno = 0;
+
+ _unlock_fh(phandles[1]); /* unlock handle */
+ }
+ else {
+ _osfile[phandles[0]] = 0;
+ errno = EMFILE; /* too many files */
+ }
+
+ _unlock_fh(phandles[0]); /* unlock handle */
+ }
+ else {
+ errno = EMFILE; /* too many files */
+ }
+
+ /* If error occurred, close Win32 handles and return -1 */
+ if (errno != 0) {
+ CloseHandle(ReadHandle);
+ CloseHandle(WriteHandle);
+ _doserrno = 0; /* not an OS/2 error */
+ return -1;
+ }
+
+#else /* ndef _WIN32_ */
+
+#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+ return 0;
+}
diff --git a/private/crt32/lowio/ppc/cinitcon.s b/private/crt32/lowio/ppc/cinitcon.s
new file mode 100644
index 000000000..5e5b71e6b
--- /dev/null
+++ b/private/crt32/lowio/ppc/cinitcon.s
@@ -0,0 +1,53 @@
+// page ,132
+// title cinitcon - C Run-Time Startup Initialization for Console I/O
+//
+//cinitcon.asm - C Run-Time Startup Initialization for WIN32
+//
+// Copyright (c) 1990-1992, Microsoft Corporation. All rights reserved.
+//
+//Purpose:
+// Initialization and Termination for console I/O
+//
+//Notes:
+// _confh and _coninpfh are defined in this module to force the
+// inclusion of this module if any console I/O is performed.
+// This module places the address of _initcon() in the initializer
+// table and the address of _termcon() in the pre-terminator table.
+//
+//Revision History:
+// 03-19-92 SKS Module created.
+// 03-24-92 SKS Added MIPS support (NO_UNDERSCORE)
+// 04-30-92 SKS Add "offset FLAT:" to get correct fixups for OMF objs
+// 08-06-92 SKS Revised to use new section names and macros
+//
+// ****************************************************************************
+
+#include "kxppc.h"
+
+ .extern _initcon
+ .extern _termcon
+
+
+beginSection(XIC)
+
+ .long _initcon
+
+endSection(XIC)
+
+
+beginSection(XPX)
+
+ .long _termcon
+
+endSection(XPX)
+
+
+ .data
+ .align 2
+
+ .globl _coninpfh
+ .globl _confh
+
+_coninpfh: .long -1 // console input
+_confh: .long -1 // console output
+
diff --git a/private/crt32/lowio/putch.c b/private/crt32/lowio/putch.c
new file mode 100644
index 000000000..addd0c6b2
--- /dev/null
+++ b/private/crt32/lowio/putch.c
@@ -0,0 +1,129 @@
+/***
+*putch.c - contains the _putch() routine for OS/2 Protected Mode
+*
+* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved
+*
+*Purpose:
+* The routine "_putch()" writes a single character to the console.
+*
+* NOTE: In real-mode DOS the character is actually written to standard
+* output, and is therefore redirected when standard output is redirected.
+* However, in Protected-Mode OS/2 the character is ALWAYS written
+* to the console, even when standard output has been redirected.
+*
+*Revision History:
+* 06-08-89 PHG Module created, based on asm version
+* 03-13-90 GJF Made calling type _CALLTYPE1, added #include
+* <cruntime.h> and fixed copyright. Also, cleaned up
+* the formatting a bit.
+* 06-05-90 SBM Recoded as pure 32-bit, using new file handle state bits
+* 07-24-90 SBM Removed '32' from API names
+* 10-01-90 GJF New-style function declarators.
+* 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
+* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
+* 01-16-91 GJF ANSI naming.
+* 02-19-91 SRW Adapt to OpenFile/CreateFile changes (_WIN32_)
+* 02-25-91 MHL Adapt to ReadFile/WriteFile changes (_WIN32_)
+* 07-26-91 GJF Took out init. stuff and cleaned up the error
+* handling [_WIN32_].
+* 03-20-93 GJF Use WriteConsole instead of WriteFile.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <conio.h>
+#include <os2dll.h>
+#include <stdio.h>
+
+/*
+ * declaration for console handle
+ */
+extern int _confh;
+
+/***
+*int _putch(c) - write a character to the console
+*
+*Purpose:
+* Calls DOSWRITE to output the character
+* Note: in OS/2 protect mode always writes to console even
+* when stdout redirected
+*
+*Entry:
+* c - Character to be output
+*
+*Exit:
+* If an error is returned from DOSWRITE
+* Then returns EOF
+* Otherwise
+* returns character that was output
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+#ifdef MTHREAD
+/* normal version lock and unlock the console, and then call the _lk version
+ which directly accesses the console without locking. */
+
+int _CRTAPI1 _putch (
+ int c
+ )
+{
+ int ch;
+
+ _mlock(_CONIO_LOCK); /* secure the console lock */
+ ch = _putch_lk(c); /* output the character */
+ _munlock(_CONIO_LOCK); /* release the console lock */
+
+ return ch;
+}
+#endif /* MTHREAD */
+
+/* define version which accesses the console directly - normal version in
+ non-MTHREAD situations, special _lk version in MTHREAD */
+
+#ifdef MTHREAD
+int _CRTAPI1 _putch_lk (
+#else
+int _CRTAPI1 _putch (
+#endif
+ int c
+ )
+{
+ /* can't use ch directly unless sure we have a big-endian machine */
+ unsigned char ch = (unsigned char)c;
+ ULONG num_written;
+
+ /* write character to console file handle */
+
+#ifdef _CRUISER_
+
+ if (DOSWRITE(_confh, &ch, 1L, &num_written)) {
+ /* OS/2 error, return error indicator */
+ return EOF;
+ }
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ if ( (_confh == -1) || !WriteConsole( (HANDLE)_confh,
+ (LPVOID)&ch,
+ 1,
+ &num_written,
+ NULL )
+ )
+ /* return error indicator */
+ return EOF;
+
+#else /* ndef _WIN32_ */
+
+#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+ return ch;
+}
diff --git a/private/crt32/lowio/read.c b/private/crt32/lowio/read.c
new file mode 100644
index 000000000..d11805761
--- /dev/null
+++ b/private/crt32/lowio/read.c
@@ -0,0 +1,349 @@
+/***
+*read.c - OS/2 read from a file handle
+*
+* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _read() - read from a file handle
+*
+*Revision History:
+* 06-19-89 PHG Module created, based on asm version
+* 03-13-90 GJF Made calling type _CALLTYPE2 (for now), added #include
+* <cruntime.h> and fixed compiler warnings. Also, fixed
+* the copyright.
+* 04-03-90 GJF Now _CALLTYPE1.
+* 07-24-90 SBM Removed '32' from API names
+* 08-14-90 SBM Compiles cleanly with -W3
+* 10-01-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
+* 12-28-90 SRW Added cast of void * to char * for Mips C Compiler
+* 01-16-91 GJF ANSI naming.
+* 01-29-91 SRW Changed to not read ahead on char devices [_WIN32_]
+* 02-01-91 SRW Changed to use ERROR_HANDLE_EOF error code (_WIN32_)
+* 02-25-91 MHL Adapt to ReadFile/WriteFile changes (_WIN32_)
+* 04-09-91 PNT Added _MAC_ conditional
+* 04-16-91 SRW Character device bug fix [_WIN32_]
+* 05-23-91 GJF Don't set FEOFLAG if handle corresponds to a device.
+* 10-24-91 GJF Added LPDWORD casts to make MIPS compiler happy.
+* ASSUMES THAT sizeof(int) == sizeof(DWORD).
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+* 06-16-92 GJF Bug fix - if CR was the very last char read, and the
+* last char in the file, CRLF was getting written to
+* user's buffer.
+* 12-18-93 GJF Don't treat ERROR_BROKEN_PIPE as an error. Instead,
+* just return 0.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <os2dll.h>
+#include <io.h>
+#include <internal.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <msdos.h>
+
+#define LF 10 /* line feed */
+#define CR 13 /* carriage return */
+#define CTRLZ 26 /* ctrl-z means eof for text */
+
+/***
+*int _read(fh, buf, cnt) - read bytes from a file handle
+*
+*Purpose:
+* Attempts to read cnt bytes from fh into a buffer.
+* If the file is in text mode, CR-LF's are mapped to LF's, thus
+* affecting the number of characters read. This does not
+* affect the file pointer.
+*
+* NOTE: The stdio _IOCTRLZ flag is tied to the use of FEOFLAG.
+* Cross-reference the two symbols before changing FEOFLAG's use.
+*
+*Entry:
+* int fh - file handle to read from
+* char *buf - buffer to read into
+* int cnt - number of bytes to read
+*
+*Exit:
+* Returns number of bytes read (may be less than the number requested
+* if the EOF was reached or the file is in text mode).
+* returns -1 (and sets errno) if fails.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+#ifdef MTHREAD
+
+/* define normal version that locks/unlocks, validates fh */
+int _CALLTYPE1 _read (
+ int fh,
+ void *buf,
+ unsigned cnt
+ )
+{
+ int r; /* return value */
+
+ /* validate handle */
+#ifdef _WIN32_
+ if ( (unsigned)fh >= (unsigned)_nhandle ) {
+#else
+ if ((unsigned)fh >= (unsigned)_nfile) {
+#endif
+ /* out of range -- return error */
+ errno = EBADF;
+ _doserrno = 0; /* not OS/2 error */
+ return -1;
+ }
+
+ _lock_fh(fh); /* lock file */
+ r = _read_lk(fh, buf, cnt); /* read bytes */
+ _unlock_fh(fh); /* unlock file */
+
+ return r;
+}
+
+/* now define version that doesn't lock/unlock, validate fh */
+int _CALLTYPE1 _read_lk (
+ int fh,
+ void *buf,
+ unsigned cnt
+ )
+{
+ int bytes_read; /* number of bytes read */
+ char *buffer; /* buffer to read to */
+ int os_read; /* bytes read on OS call */
+ char *p, *q; /* pointers into buffer */
+ char peekchr; /* peek-ahead character */
+ ULONG filepos; /* file position after seek */
+ ULONG dosretval; /* OS/2 return value */
+
+
+#else
+
+/* now define normal version */
+int _CALLTYPE1 _read (
+ int fh,
+ void *buf,
+ unsigned cnt
+ )
+{
+ int bytes_read; /* number of bytes read */
+ char *buffer; /* buffer to read to */
+ int os_read; /* bytes read on OS call */
+ char *p, *q; /* pointers into buffer */
+ char peekchr; /* peek-ahead character */
+ ULONG filepos; /* file position after seek */
+ ULONG dosretval; /* OS/2 return value */
+
+ /* validate fh */
+#ifdef _WIN32_
+ if ( (unsigned)fh >= (unsigned)_nhandle ) {
+#else
+ if ((unsigned)fh >= (unsigned)_nfile) {
+#endif
+ /* bad file handle */
+ errno = EBADF;
+ _doserrno = 0; /* not OS/2 error */
+ return -1;
+ }
+
+#endif
+
+ bytes_read = 0; /* nothing read yet */
+ buffer = buf;
+
+ if (cnt == 0 || (_osfile[fh] & FEOFLAG)) {
+ /* nothing to read or at EOF, so return 0 read */
+ return 0;
+ }
+
+ if ((_osfile[fh] & (FPIPE|FDEV)) && _pipech[fh] != LF) {
+ /* a pipe/device and pipe lookahead non-empty: read the lookahead char */
+ *buffer++ = _pipech[fh];
+ ++bytes_read;
+ --cnt;
+ _pipech[fh] = LF; /* mark as empty */
+ }
+
+ /* read the data */
+#ifdef _CRUISER_
+
+ if ( dosretval = DOSREAD(fh, buffer, cnt, &os_read) ) {
+ /* OS error, map it and return */
+ if (dosretval == ERROR_ACCESS_DENIED) {
+ /* wrong read/write mode should return EBADF, not EACCES */
+ errno = EBADF;
+ _doserrno = dosretval;
+ }
+ else
+ _dosmaperr(dosretval);
+ return -1;
+ }
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ if ( !ReadFile((HANDLE)_osfhnd[fh], buffer, cnt, (LPDWORD)&os_read,
+ NULL) ) {
+
+ /* ReadFile has reported an error. recognize two special cases.
+ *
+ * 1. map ERROR_ACCESS_DENIED to EBADF
+ *
+ * 2. just return 0 if ERROR_BROKEN_PIPE has occurred. it
+ * means the handle is a read-handle on a pipe for which
+ * all write-handles have been closed and all data has been
+ * read. */
+
+ if ( (dosretval = GetLastError()) == ERROR_ACCESS_DENIED ) {
+ /* wrong read/write mode should return EBADF, not EACCES */
+ errno = EBADF;
+ _doserrno = dosretval;
+ return -1;
+ }
+ else if ( dosretval == ERROR_BROKEN_PIPE ) {
+ return 0;
+ }
+ else {
+ _dosmaperr(dosretval);
+ return -1;
+ }
+ }
+
+#else /* ndef _WIN32_ */
+
+#ifdef _MAC_
+
+ TBD();
+
+#else /* ndef _MAC_ */
+
+#error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED!
+
+#endif /* _MAC_ */
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+ bytes_read += os_read; /* update bytes read */
+
+ if (_osfile[fh] & FTEXT) {
+ /* now must translate CR-LFs to LFs in the buffer */
+
+ /* set CRLF flag to indicate LF at beginning of buffer */
+ if (*(char *)buf == LF)
+ _osfile[fh] |= FCRLF;
+ else
+ _osfile[fh] &= ~FCRLF;
+
+ /* convert chars in the buffer: p is src, q is dest */
+ p = q = buf;
+ while (p < (char *)buf + bytes_read) {
+ if (*p == CTRLZ) {
+ /* if fh is not a device, set ctrl-z flag */
+ if ( !(_osfile[fh] & FDEV) )
+ _osfile[fh] |= FEOFLAG;
+ break; /* stop translating */
+ }
+ else if (*p != CR)
+ *q++ = *p++;
+ else {
+ /* *p is CR, so must check next char for LF */
+ if (p < (char *)buf + bytes_read - 1) {
+ if (*(p+1) == LF) {
+ p += 2;
+ *q++ = LF; /* convert CR-LF to LF */
+ }
+ else
+ *q++ = *p++; /* store char normally */
+ }
+ else {
+ /* This is the hard part. We found a CR at end of
+ buffer. We must peek ahead to see if next char
+ is an LF. */
+ ++p;
+#ifdef _CRUISER_
+
+ dosretval = DOSREAD(fh, &peekchr, 1, &os_read);
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ dosretval = 0;
+ if ( !ReadFile((HANDLE)_osfhnd[fh], &peekchr, 1,
+ (LPDWORD)&os_read, NULL) )
+ dosretval = GetLastError();
+
+#else /* ndef _WIN32_ */
+
+#ifdef _MAC_
+
+ TBD();
+
+#else /* ndef _MAC_ */
+
+#error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED!
+
+#endif /* _MAC_ */
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+ if (dosretval != 0 || os_read == 0) {
+ /* couldn't read ahead, store CR */
+ *q++ = CR;
+ }
+ else {
+ /* peekchr now has the extra character -- we now have
+ several possibilities:
+ 1. disk file and char is not LF; just seek back
+ and copy CR
+ 2. disk file and char is LF; seek back and discard CR
+ 3. disk file, char is LF but this is a one-byte read:
+ store LF, don't seek back
+ 4. pipe/device and char is LF; store LF.
+ 5. pipe/device and char isn't LF, store CR and put
+ char in pipe lookahead buffer. */
+ if (_osfile[fh] & (FDEV|FPIPE)) {
+ /* non-seekable device */
+ if (peekchr == LF)
+ *q++ = LF;
+ else {
+ *q++ = CR;
+ _pipech[fh] = peekchr;
+ }
+ }
+ else {
+ /* disk file */
+ if (q == buf && peekchr == LF) {
+ /* nothing read yet; must make some progress */
+ *q++ = LF;
+ }
+ else {
+ /* seek back */
+ filepos = _lseek_lk(fh, -1, FILE_CURRENT);
+ if (peekchr != LF)
+ *q++ = CR;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* we now change bytes_read to reflect the true number of chars
+ in the buffer */
+ bytes_read = q - (char *)buf;
+ }
+
+ return bytes_read; /* and return */
+}
diff --git a/private/crt32/lowio/setmode.c b/private/crt32/lowio/setmode.c
new file mode 100644
index 000000000..a9bf34e8e
--- /dev/null
+++ b/private/crt32/lowio/setmode.c
@@ -0,0 +1,155 @@
+/***
+*setmode.c - set file translation mode
+*
+* Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defined _setmode() - set file translation mode of a file
+*
+*Revision History:
+* 08-16-84 RN initial version
+* 10-29-87 JCR Multi-thread support
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 05-25-88 PHG Merged DLL and normal versions
+* 03-13-90 GJF Made calling type _CALLTYPE1, added #include
+* <cruntime.h>, removed #include <register.h> and
+* fixed the copyright. Also, cleaned up the formatting
+* a bit.
+* 04-04-90 GJF Added #include <io.h>.
+* 10-01-90 GJF New-style function declarators.
+* 12-04-90 GJF Appended Win32 version onto the source with #ifdef-s.
+* Two versions should be merged together, the differences
+* are trivial.
+* 12-06-90 SRW Changed to use _osfile and _osfhnd instead of _osfinfo
+* 01-17-91 GJF ANSI naming.
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <stdio.h>
+#include <io.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <msdos.h>
+#include <os2dll.h>
+#include <stddef.h>
+#include <internal.h>
+
+/***
+*int _setmode(fh, mode) - set file translation mode
+*
+*Purpose:
+* changes file mode to text/binary, depending on mode arg. this affects
+* whether read's and write's on the file translate between CRLF and LF
+* or is untranslated
+*
+*Entry:
+* int fh - file handle to change mode on
+* int mode - file translation mode (one of O_TEXT and O_BINARY)
+*
+*Exit:
+* returns old file translation mode
+* returns -1 and sets errno if fails
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+#ifdef MTHREAD /* multi-thread code calls _lk_setmode() */
+
+int _CALLTYPE1 _setmode (
+ int fh,
+ int mode
+ )
+{
+ int retval;
+#ifdef _WIN32_
+ if ( (unsigned)fh >= (unsigned)_nhandle ) {
+#else
+ if (fh < 0 || fh >= _nfile) {
+#endif
+ errno = EBADF;
+ return(-1);
+ }
+
+ /* lock the file */
+ _lock_fh(fh);
+
+ /* set the text/binary mode */
+ retval = _setmode_lk(fh, mode);
+
+ /* unlock the file */
+ _unlock_fh(fh);
+
+ /* Return to user (_setmode_lk sets errno, if needed) */
+ return(retval);
+
+}
+
+/***
+*_setmode_lk() - Perform core setmode operation
+*
+*Purpose:
+* Core setmode code. Assumes:
+* (1) Caller has validated fh to make sure it's in range.
+* (2) Caller has locked the file handle.
+*
+* [See _setmode() description above.]
+*
+*Entry: [Same as _setmode()]
+*
+*Exit: [Same as _setmode()]
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _setmode_lk (
+ REG1 int fh,
+ int mode
+ )
+{
+ int oldmode;
+
+#else /* non multi-thread code */
+
+int _CALLTYPE1 _setmode (
+ REG1 int fh,
+ int mode
+ )
+{
+ int oldmode;
+
+#ifdef _WIN32_
+ if ( (unsigned)fh >= (unsigned)_nhandle ) {
+#else
+ if (fh < 0 || fh >= _nfile) {
+#endif
+ errno = EBADF;
+ return(-1);
+ }
+
+#endif /* now join common code */
+
+ if (!(_osfile[fh] & FOPEN)) {
+ errno = EBADF;
+ return(-1);
+ }
+
+ else {
+ oldmode = _osfile[fh] & FTEXT;
+
+ if (mode == _O_BINARY)
+ _osfile[fh] &= ~FTEXT;
+ else if (mode == _O_TEXT)
+ _osfile[fh] |= FTEXT;
+ else {
+ errno = EINVAL;
+ return(-1);
+ }
+ }
+
+ return(oldmode ? _O_TEXT : _O_BINARY);
+
+}
diff --git a/private/crt32/lowio/sources b/private/crt32/lowio/sources
new file mode 100644
index 000000000..6c95035f2
--- /dev/null
+++ b/private/crt32/lowio/sources
@@ -0,0 +1,62 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+ Steve Wood (stevewo) 12-Apr-1990
+ jeffrob 29-sep-1990, use crt32.def
+
+NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl
+
+!ENDIF
+
+MAJORCOMP=crt
+MINORCOMP=lowio
+
+TARGETNAME=lowio
+TARGETPATH=..\obj
+TARGETTYPE=LIBRARY
+386_STDCALL=0
+
+!INCLUDE ..\crt32.def
+
+SOURCES=chsize.c \
+ close.c \
+ commit.c \
+ creat.c \
+ dup.c \
+ dup2.c \
+ eof.c \
+ flength.c \
+ fstat.c \
+ initcon.c \
+ ioinit.c \
+ isatty.c \
+ locking.c \
+ lseek.c \
+ mktemp.c \
+ open.c \
+ osfinfo.c \
+ pipe.c \
+ read.c \
+ setmode.c \
+ tell.c \
+ txtmode.c \
+ write.c \
+ cgets.c \
+ cputs.c \
+ getch.c \
+ putch.c
diff --git a/private/crt32/lowio/tell.c b/private/crt32/lowio/tell.c
new file mode 100644
index 000000000..0f8a2a497
--- /dev/null
+++ b/private/crt32/lowio/tell.c
@@ -0,0 +1,46 @@
+/***
+*tell.c - find file position
+*
+* Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* contains _tell() - find file position
+*
+*Revision History:
+* 09-02-83 RN initial version
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 03-13-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
+* <cruntime.h> and fixed the copyright. Also, cleaned
+* up the formatting a bit.
+* 10-01-90 GJF New-style function declarator.
+* 01-17-91 GJF ANSI naming.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <io.h>
+
+/***
+*long _tell(filedes) - find file position
+*
+*Purpose:
+* Gets the current position of the file pointer (no adjustment
+* for buffering).
+*
+*Entry:
+* int filedes - file handle of file
+*
+*Exit:
+* returns file position or -1L (sets errno) if bad file descriptor or
+* pipe
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+long _CALLTYPE1 _tell (
+ int filedes
+ )
+{
+ return(_lseek(filedes,0L,1));
+}
diff --git a/private/crt32/lowio/txtmode.c b/private/crt32/lowio/txtmode.c
new file mode 100644
index 000000000..b40b0db61
--- /dev/null
+++ b/private/crt32/lowio/txtmode.c
@@ -0,0 +1,19 @@
+/***
+*txtmode.c - set global text mode flag
+*
+* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* Sets the global file mode to text. This is the default.
+*
+*Revision History:
+* 06-08-89 PHG Module created, based on asm version.
+* 04-04-90 GJF Added #include <cruntime.h>. Also, fixed the copyright.
+* 01-23-92 GJF Added #include <stdlib.h> (contains decl of _fmode).
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <stdlib.h>
+
+int _fmode = 0; /* set text mode */
diff --git a/private/crt32/lowio/write.c b/private/crt32/lowio/write.c
new file mode 100644
index 000000000..73d57bba1
--- /dev/null
+++ b/private/crt32/lowio/write.c
@@ -0,0 +1,324 @@
+/***
+*write.c - write to a file handle
+*
+* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* defines _write() - write to a file handle
+*
+*Revision History:
+* 06-14-89 PHG Module created, based on asm version
+* 03-13-90 GJF Made calling type _CALLTYPE2 (for now), added #include
+* <cruntime.h>, fixed compiler warnings 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
+* 10-01-90 GJF New-style function declarators.
+* 12-04-90 GJF Appended Win32 version onto source with #ifdef-s.
+* Should come back latter and do a better merge.
+* 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
+* 12-28-90 SRW Added _CRUISER_ conditional around check_stack pragma
+* 12-28-90 SRW Added cast of void * to char * for Mips C Compiler
+* 01-17-91 GJF ANSI naming.
+* 02-25-91 MHL Adapt to ReadFile/WriteFile changes (_WIN32_)
+* 04-09-91 PNT Added _MAC_ conditional
+* 07-18-91 GJF Removed unreferenced local variable from _write_lk
+* routine [_WIN32_].
+* 10-24-91 GJF Added LPDWORD casts to make MIPS compiler happy.
+* ASSUMES THAT sizeof(int) == sizeof(DWORD).
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+* 02-15-92 GJF Increased BUF_SIZE and simplified LF translation code
+* for Win32.
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <io.h>
+#include <errno.h>
+#include <msdos.h>
+#include <os2dll.h>
+#include <stdlib.h>
+#include <string.h>
+#include <internal.h>
+
+#ifdef _WIN32_
+#define BUF_SIZE 1025 /* size of LF translation buffer */
+#else /* ndef _WIN32_ */
+#define BUF_SIZE 513 /* size of LF translation buffer, sector size+1 is ok */
+#endif /* _WIN32_ */
+
+#define LF '\n' /* line feed */
+#define CR '\r' /* carriage return */
+#define CTRLZ 26 /* ctrl-z */
+
+#ifdef _CRUISER_
+#pragma check_stack(on)
+#endif /* ndef _CRUISER_ */
+
+/***
+*int _write(fh, buf, cnt) - write bytes to a file handle
+*
+*Purpose:
+* Writes count bytes from the buffer to the handle specified.
+* If the file was opened in text mode, each LF is translated to
+* CR-LF. This does not affect the return value. In text
+* mode ^Z indicates end of file.
+*
+* Multi-thread notes:
+* (1) _write() - Locks/unlocks file handle
+* _write_lk() - Does NOT lock/unlock file handle
+*
+*Entry:
+* int fh - file handle to write to
+* char *buf - buffer to write from
+* unsigned int cnt - number of bytes to write
+*
+*Exit:
+* returns number of bytes actually written.
+* This may be less than cnt, for example, if out of disk space.
+* returns -1 (and set errno) if fails.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+#ifdef MTHREAD
+
+/* define normal version that locks/unlocks, validates fh */
+int _CALLTYPE1 _write (
+ int fh,
+ const void *buf,
+ unsigned cnt
+ )
+{
+ int r; /* return value */
+
+ /* validate handle */
+#ifdef _WIN32_
+ if ( (unsigned)fh >= (unsigned)_nhandle ) {
+#else
+ if ((unsigned)fh >= (unsigned)_nfile) {
+#endif
+ /* out of range -- return error */
+ errno = EBADF;
+ _doserrno = 0; /* not OS/2 error */
+ return -1;
+ }
+
+ _lock_fh(fh); /* lock file */
+ r = _write_lk(fh, buf, cnt); /* write bytes */
+ _unlock_fh(fh); /* unlock file */
+
+ return r;
+}
+
+/* now define version that doesn't lock/unlock, validate fh */
+int _CALLTYPE1 _write_lk (
+ int fh,
+ const void *buf,
+ unsigned cnt
+ )
+{
+ int lfcount; /* count of line feeds */
+ int charcount; /* count of chars written so far */
+ int written; /* count of chars written on this write */
+#ifdef _CRUISER_
+ int error; /* error occured */
+#endif
+ ULONG dosretval; /* OS/2 return value */
+ char ch; /* current character */
+ char *p, *q; /* pointers into buf and lfbuf resp. */
+ char lfbuf[BUF_SIZE]; /* lf translation buffer */
+
+#else
+
+/* now define normal version */
+int _CALLTYPE1 _write (
+ int fh,
+ const void *buf,
+ unsigned cnt
+ )
+{
+ int lfcount; /* count of line feeds */
+ int charcount; /* count of chars written so far */
+ int written; /* count of chars written on this write */
+#ifdef _CRUISER_
+ int error; /* error occured */
+#endif
+ ULONG dosretval; /* OS/2 return value */
+ char ch; /* current character */
+ char *p, *q; /* pointers into buf and lfbuf resp. */
+ char lfbuf[BUF_SIZE]; /* lf translation buffer */
+
+ /* validate handle */
+#ifdef _WIN32_
+ if ( (unsigned)fh >= (unsigned)_nhandle ) {
+#else
+ if ((unsigned)fh >= (unsigned)_nfile) {
+#endif
+ /* out of range -- return error */
+ errno = EBADF;
+ _doserrno = 0; /* not OS/2 error */
+ return -1;
+ }
+
+#endif
+
+ lfcount = charcount = 0; /* nothing written yet */
+
+ if (cnt == 0)
+ return 0; /* nothing to do */
+
+
+ if (_osfile[fh] & FAPPEND) {
+ /* appending - seek to end of file; ignore error, because maybe
+ file doesn't allow seeking */
+ (void)_lseek_lk(fh, 0, FILE_END);
+ }
+
+ /* check for text mode with LF's in the buffer */
+
+#ifdef _CRUISER_
+ if ((_osfile[fh] & FTEXT) && memchr(buf, LF, cnt)) {
+ /* text mode, translate LF's to CR/LF's on output */
+
+ p = (char *)buf; /* start at beginning of buffer */
+ error = 0; /* no error yet */
+
+ while ((unsigned)(p - (char *)buf) < cnt && !error) {
+ q = lfbuf; /* start at beginning of lfbuf */
+
+ /* fill the lf buf, except maybe last char */
+ while (q - lfbuf < BUF_SIZE - 1 && (unsigned)(p - (char *)buf) < cnt) {
+ ch = *p++;
+ if (ch == LF) {
+ ++lfcount;
+ *q++ = CR;
+ *q++ = LF; /* store CR-LF */
+ }
+ else
+ *q++ = ch;
+ }
+
+ /* write the lf buf and update total */
+ if (dosretval = DOSWRITE(fh, lfbuf, q - lfbuf,
+ &written))
+ error = 1;
+ else {
+ charcount += written;
+ if (written < q - lfbuf)
+ error = 1;
+ }
+ }
+ }
+ else {
+ /* binary mode, no translation */
+ if (!(dosretval = DOSWRITE(fh, (char *)buf, cnt, &written)))
+ charcount = written;
+ }
+
+#else /* _CRUISER_ */
+
+#ifdef _WIN32_
+ if ( _osfile[fh] & FTEXT ) {
+ /* text mode, translate LF's to CR/LF's on output */
+
+ p = (char *)buf; /* start at beginning of buffer */
+ dosretval = 0; /* no OS error yet */
+
+ while ( (unsigned)(p - (char *)buf) < cnt ) {
+ q = lfbuf; /* start at beginning of lfbuf */
+
+ /* fill the lf buf, except maybe last char */
+ while ( q - lfbuf < BUF_SIZE - 1 &&
+ (unsigned)(p - (char *)buf) < cnt ) {
+ ch = *p++;
+ if ( ch == LF ) {
+ ++lfcount;
+ *q++ = CR;
+ }
+ *q++ = ch;
+ }
+
+ /* write the lf buf and update total */
+ if ( WriteFile( (HANDLE)_osfhnd[fh],
+ lfbuf,
+ q - lfbuf,
+ (LPDWORD)&written,
+ NULL) )
+ {
+ charcount += written;
+ if (written < q - lfbuf)
+ break;
+ }
+ else {
+ dosretval = GetLastError();
+ break;
+ }
+ }
+ }
+ else {
+ /* binary mode, no translation */
+ if ( WriteFile( (HANDLE)_osfhnd[fh],
+ (LPVOID)buf,
+ cnt,
+ (LPDWORD)&written,
+ NULL) )
+ {
+ dosretval = 0;
+ charcount = written;
+ }
+ else
+ dosretval = GetLastError();
+ }
+
+#else /* ndef _WIN32_ */
+
+#ifdef _MAC_
+
+ }
+ }
+
+ TBD();
+
+#else /* ndef _MAC_ */
+
+#error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED!
+
+#endif /* _MAC_ */
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+ if (charcount == 0) {
+ /* If nothing was written, first check if an OS/2 error,
+ otherwise we return -1 and set errno to ENOSPC,
+ unless a device and first char was CTRL-Z */
+ if (dosretval != 0) {
+ /* OS/2 error happened, map error */
+ if (dosretval == ERROR_ACCESS_DENIED) {
+ /* wrong read/write mode should return EBADF, not
+ EACCES */
+ errno = EBADF;
+ _doserrno = dosretval;
+ }
+ else
+ _dosmaperr(dosretval);
+ return -1;
+ }
+ else if ((_osfile[fh] & FDEV) && *(char *)buf == CTRLZ)
+ return 0;
+ else {
+ errno = ENOSPC;
+ _doserrno = 0; /* no OS/2 error */
+ return -1;
+ }
+ }
+ else
+ /* return adjusted bytes written */
+ return charcount - lfcount;
+}