aboutsummaryrefslogtreecommitdiff
path: root/win32/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'win32/io.c')
-rw-r--r--win32/io.c479
1 files changed, 479 insertions, 0 deletions
diff --git a/win32/io.c b/win32/io.c
new file mode 100644
index 000000000000..0124f1b2a028
--- /dev/null
+++ b/win32/io.c
@@ -0,0 +1,479 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/io.c,v 1.9 2006/04/13 00:59:02 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * io.c
+ * wrapper functions for some i/o routines.
+ * -amol
+ *
+ */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <errno.h>
+#include "sh.h"
+#include "ntport.h"
+#include "signal.h"
+
+
+#pragma warning(disable:4127) //conditional expr is constant
+
+#define CR 0x0d
+
+
+extern void make_err_str(unsigned int ,char *,int ) ;
+extern void generic_handler(int);
+extern int console_write(HANDLE,unsigned char*,int);
+
+int consoleread(HANDLE , unsigned char * ,size_t ) ;
+
+INPUT_RECORD girec[2048];
+
+unsigned short __nt_want_vcode=0,__nt_vcode=0;
+HANDLE __h_con_alarm=0;
+HANDLE __h_con_int=0;
+HANDLE __h_con_hup=0;
+
+extern int NoNLSRebind;
+
+extern int OLDSTD, SHIN;
+/*
+ * force_read: Forces a ReadFile, instead of ReadConsole
+ *
+ */
+int force_read(int fd, unsigned char * buf, size_t howmany) {
+ DWORD numread=0,err=0;
+ HANDLE hRead ;
+
+
+ hRead= (HANDLE)__nt_get_osfhandle(fd);
+ if (hRead == INVALID_HANDLE_VALUE) {
+ return 0;
+ }
+again:
+ if (!ReadFile(hRead, buf,(DWORD)howmany,&numread, NULL ) ){
+ err = GetLastError();
+ switch(err) {
+ case ERROR_IO_PENDING:
+ break;
+ case ERROR_ACCESS_DENIED:
+ case ERROR_INVALID_HANDLE:
+ errno = EBADF;
+ return -1;
+ break;
+ case ERROR_HANDLE_EOF:
+ case ERROR_BROKEN_PIPE:
+ errno = 0;
+ return 0;
+ default:
+ errno = EBADF;
+ return 0;
+ }
+ }
+ if (numread == 1 && buf[0] == CR)
+ goto again;
+ return numread;
+}
+int nt_read(int fd, unsigned char * buf, size_t howmany) {
+
+ DWORD numread=0,err=0;
+ HANDLE hRead ;
+ DWORD ftype;
+ //
+
+ hRead= (HANDLE)__nt_get_osfhandle(fd);
+ if (hRead == INVALID_HANDLE_VALUE) {
+ return 0;
+ }
+
+ ftype = GetFileType(hRead);
+
+
+ if ((ftype == FILE_TYPE_CHAR) /*&& (fd != OLDSTD) && (fd != SHIN)*/)
+ return consoleread(hRead,buf,howmany);
+again:
+ if (!ReadFile(hRead, buf,(DWORD)howmany,&numread, NULL ) ){
+ err = GetLastError();
+ switch(err) {
+ case ERROR_IO_PENDING:
+ break;
+ case ERROR_ACCESS_DENIED:
+ case ERROR_INVALID_HANDLE:
+ errno = EBADF;
+ return -1;
+ break;
+ case ERROR_HANDLE_EOF:
+ case ERROR_BROKEN_PIPE:
+ errno = 0;
+ return 0;
+ default:
+ errno = EBADF;
+ return 0;
+ }
+ }
+ if (numread) {
+ if (buf[numread-1] == CR)
+ numread--;
+ if (numread == 0)
+ goto again;
+ }
+ return numread;
+}
+
+/* color-ls patches from TAGA nayuta (nayuta@is.s.u-tokyo.ac.jp) */
+#ifdef COLOR_LS_F
+
+int nt_write_(int , const unsigned char * , size_t );
+int nt_write(int fd, const unsigned char * buf, size_t howmany) {
+ static unsigned char color_buf[256];
+ static char len = 0;
+
+ ssize_t i;
+ ssize_t start = 0;
+ int rc,wrote = 0;
+
+ if (!isatty(fd) || (varval(STRcolor) == NULL))
+ return nt_write_(fd, buf, howmany);
+
+ for (i = 0; i < howmany; i++) {
+ switch (len) {
+ case 0:
+ if (buf[i] == '\x1b') {
+ color_buf[len++] = buf[i];
+ if (0 < i - start){
+ if ((rc=nt_write_(fd, &(buf[start]), i - start)) <0)
+ return -1;
+ else
+ wrote += rc;
+ }
+ start = -1;
+ }
+ break;
+
+ case 1:
+ if (buf[i] != '[')
+ goto set_color;
+ color_buf[len++] = buf[i];
+ break;
+
+ default:
+ if (buf[i] == 'm' || (!isdigit(buf[i]) && buf[i] != ';'))
+ goto set_color;
+ color_buf[len++] = buf[i];
+ break;
+
+ case sizeof(color_buf) - 1:
+set_color:
+ color_buf[len] = '\0';
+ set_attributes(color_buf);
+ len = 0;
+ start = i + 1;
+ break;
+ }
+ }
+
+ if (0 < i - start && 0 <= start) {
+ if ((rc=nt_write_(fd, &(buf[start]), i - start)) < 0)
+ return -1;
+ else
+ wrote += rc;
+ }
+ return wrote;
+}
+int nt_write_(int fd, const unsigned char * buf, size_t howmany)
+#else /* if !COLOR_LS_F */
+int nt_write(int fd, const unsigned char * buf, size_t howmany)
+#endif /* COLOR_LS_F */
+{
+ int bytes_rtn,err;
+ HANDLE hout;
+
+
+ hout = (HANDLE)__nt_get_osfhandle(fd);
+ /*
+ if (isatty(fd))
+ ;// return console_write(hout,buf,howmany);
+ */
+
+ if(!WriteFile(hout, buf,(DWORD)howmany,(ULONG*)&bytes_rtn,
+ NULL)){
+ err = GetLastError();
+ switch(err) {
+ case ERROR_ACCESS_DENIED:
+ case ERROR_INVALID_HANDLE:
+ errno = EBADF;
+ return -1;
+ break;
+ case ERROR_BROKEN_PIPE:
+ errno = EPIPE;
+ return -1;
+ default:
+ errno = EBADF;
+ return -1;
+ }
+
+ }
+ return bytes_rtn?bytes_rtn:-1;
+
+}
+
+#define IS_CTRL_COMBO(a) ( (a) & ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED) )
+#define IS_ALT_COMBO(a) ( /*(a) &*/ alt_pressed )
+#define IS_SHIFT_COMBO(a) ( (a) & SHIFT_PRESSED)
+
+int consoleread(HANDLE hInput, unsigned char * buf,size_t howmany) {
+
+ INPUT_RECORD *irec = NULL;
+ DWORD numread,controlkey,i;
+ WORD vcode;
+ unsigned char ch;
+ int rc;
+ size_t where=0;
+ int alt_pressed = 0,memfree=0;
+ HANDLE hevents[4];
+ static int pre_ch = -1;
+
+ if (0 <= pre_ch) {
+ buf[0] = (unsigned char)pre_ch;
+ pre_ch = -1;
+ return 1;
+ }
+
+ howmany /= 2; // [ALT + KEY] is expanded ESC KEY, so we need more buffer
+ if (howmany == 0)
+ howmany = 1;
+
+ if (howmany > 2048){
+ irec = heap_alloc(howmany*sizeof(INPUT_RECORD));
+ memfree=1;
+ }
+ else
+ irec = &(girec[0]);
+ if (!irec){
+ errno = ENOMEM;
+ return -1;
+ }
+ while(1) {
+ hevents[0] = __h_con_alarm;
+ hevents[1] = __h_con_int;
+ hevents[2] = __h_con_hup;
+ hevents[3] = hInput;
+ rc = WaitForMultipleObjects(sizeof(hevents)/sizeof(hevents[0]),
+ hevents,FALSE,INFINITE);
+ if (rc == WAIT_OBJECT_0) {
+ generic_handler(SIGALRM);
+ }
+ if (rc == (WAIT_OBJECT_0 +1) ) {
+ errno = EINTR;
+ generic_handler(SIGINT);
+ break;
+ }
+ if (rc == (WAIT_OBJECT_0 +2) ) {
+ errno = EINTR;
+ generic_handler(SIGHUP);
+ break;
+ }
+ rc = ReadConsoleInput(hInput,irec,(DWORD)howmany,&numread);
+ if (!rc) {
+ rc = GetLastError();
+ switch (rc) {
+ case ERROR_INVALID_HANDLE:
+ case ERROR_ACCESS_DENIED:
+ errno = EBADF;
+ break;
+ }
+ if (memfree)
+ heap_free(irec);
+ return -1;
+ }
+ __nt_vcode=0;
+ for(i=0;i<numread;i++) {
+ switch(irec[i].EventType) {
+ case KEY_EVENT:
+ if (irec[i].Event.KeyEvent.bKeyDown) {
+ vcode=(irec[i].Event.KeyEvent.wVirtualKeyCode);
+ ch=(irec[i].Event.KeyEvent.uChar.AsciiChar);
+ controlkey=(irec[i].Event.KeyEvent.dwControlKeyState);
+ if (controlkey & LEFT_ALT_PRESSED)
+ alt_pressed=1;
+ else if (controlkey & RIGHT_ALT_PRESSED){
+ if (NoNLSRebind)
+ alt_pressed=1;
+ }
+
+ if (__nt_want_vcode != 1)
+ goto skippy;
+
+ if (vcode >= VK_F1 && vcode <= VK_F24) {
+
+ __nt_vcode=NT_SPECIFIC_BINDING_OFFSET ;
+ __nt_vcode += (vcode- VK_F1) + SINGLE_KEY_OFFSET;
+
+ if (IS_CTRL_COMBO(controlkey))
+ __nt_vcode += CTRL_KEY_OFFSET;
+
+ else if (IS_ALT_COMBO(controlkey))
+ __nt_vcode += ALT_KEY_OFFSET;
+ else if (IS_SHIFT_COMBO(controlkey))
+ __nt_vcode += SHIFT_KEY_OFFSET;
+
+ __nt_want_vcode=2;
+
+ return 1;
+ }
+ else if (vcode>= VK_PRIOR && vcode <= VK_DOWN) {
+
+ __nt_vcode = NT_SPECIFIC_BINDING_OFFSET ;
+ __nt_vcode += KEYPAD_MAPPING_BEGIN;
+ __nt_vcode += (vcode -VK_PRIOR);
+
+ __nt_vcode += SINGLE_KEY_OFFSET ;
+
+ if (IS_CTRL_COMBO(controlkey))
+ __nt_vcode += CTRL_KEY_OFFSET;
+
+ else if (IS_ALT_COMBO(controlkey))
+ __nt_vcode += ALT_KEY_OFFSET;
+ else if (IS_SHIFT_COMBO(controlkey))
+ __nt_vcode += SHIFT_KEY_OFFSET;
+
+ __nt_want_vcode=2;
+ return 1;
+ }
+ else if (vcode == VK_INSERT) {
+ __nt_vcode = NT_SPECIFIC_BINDING_OFFSET ;
+ __nt_vcode += INS_DEL_MAPPING_BEGIN;
+
+ if (IS_CTRL_COMBO(controlkey))
+ __nt_vcode += CTRL_KEY_OFFSET;
+
+ else if (IS_ALT_COMBO(controlkey))
+ __nt_vcode += ALT_KEY_OFFSET;
+
+ else if (IS_SHIFT_COMBO(controlkey))
+ __nt_vcode += SHIFT_KEY_OFFSET;
+
+ __nt_want_vcode=2;
+ return 1;
+ }
+ else if (vcode == VK_DELETE) {
+ __nt_vcode = NT_SPECIFIC_BINDING_OFFSET ;
+ __nt_vcode += INS_DEL_MAPPING_BEGIN + 1;
+
+ if (IS_CTRL_COMBO(controlkey))
+ __nt_vcode += CTRL_KEY_OFFSET;
+
+ else if (IS_ALT_COMBO(controlkey))
+ __nt_vcode += ALT_KEY_OFFSET;
+
+ else if (IS_SHIFT_COMBO(controlkey))
+ __nt_vcode += SHIFT_KEY_OFFSET;
+
+ __nt_want_vcode=2;
+
+ return 1;
+ }
+skippy:
+ switch(vcode) {
+ case VK_ESCAPE:
+ buf[where++]='\033';
+ break;
+ default:
+ if(ch ){
+ /*
+ * Looks like win95 has a spurious
+ * newline left over
+ */
+ if (gdwPlatform ==
+ VER_PLATFORM_WIN32_WINDOWS &&
+ ch == '\r'){
+ DWORD bread;
+ (void)ReadFile(hInput,&ch,1,&bread,NULL);
+ }
+ /* patch from TAGA nayuta */
+ if ( NoNLSRebind &&
+ (ch == ' ' || ch == '@') &&
+ IS_CTRL_COMBO(controlkey)
+ /*(controlkey & LEFT_CTRL_PRESSED ||
+ controlkey & RIGHT_CTRL_PRESSED)*/
+ )
+ ch = 0;
+ if (alt_pressed) {
+#ifdef DSPMBYTE
+ buf[where++] = '\033';
+ if (howmany == 1)
+ pre_ch = ch;
+ else
+ buf[where++] = ch;
+#else /* !DSPMBYTE */
+ buf[where++] = ch | 0200;
+#endif /* !DSPMBYTE */
+ }
+ else
+ buf[where++] = ch;
+ }
+ break;
+ }
+
+ alt_pressed=0;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (where == 0)
+ continue;
+ if (howmany < where) // avoid trashing memory. -amol 4/16/97
+ buf[where]=0;
+ break;
+ }
+ if (memfree)
+ heap_free(irec);
+ if (!where)
+ return -1;
+ return (int)(where );
+}
+int console_write(HANDLE hout, unsigned char * buf,int howmany) {
+ int bytes,rc;
+
+ bytes = -1;
+
+ rc = WriteConsole(hout,buf,howmany,(DWORD*)&bytes,NULL);
+ if (!rc) {
+ errno = EBADF;
+ bytes = -1;
+ rc = GetLastError();
+ }
+
+ return bytes;
+}