1 /*$Header: /p/tcsh/cvsroot/tcsh/win32/io.c,v 1.9 2006/04/13 00:59:02 amold Exp $*/
3 * Copyright (c) 1980, 1991 The Regents of the University of California.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * wrapper functions for some i/o routines.
37 #define WIN32_LEAN_AND_MEAN
48 #pragma warning(disable:4127) //conditional expr is constant
53 extern void make_err_str(unsigned int ,char *,int ) ;
54 extern void generic_handler(int);
55 extern int console_write(HANDLE,unsigned char*,int);
57 int consoleread(HANDLE , unsigned char * ,size_t ) ;
59 INPUT_RECORD girec[2048];
61 unsigned short __nt_want_vcode=0,__nt_vcode=0;
62 HANDLE __h_con_alarm=0;
66 extern int NoNLSRebind;
68 extern int OLDSTD, SHIN;
70 * force_read: Forces a ReadFile, instead of ReadConsole
73 int force_read(int fd, unsigned char * buf, size_t howmany) {
74 DWORD numread=0,err=0;
78 hRead= (HANDLE)__nt_get_osfhandle(fd);
79 if (hRead == INVALID_HANDLE_VALUE) {
83 if (!ReadFile(hRead, buf,(DWORD)howmany,&numread, NULL ) ){
86 case ERROR_IO_PENDING:
88 case ERROR_ACCESS_DENIED:
89 case ERROR_INVALID_HANDLE:
93 case ERROR_HANDLE_EOF:
94 case ERROR_BROKEN_PIPE:
102 if (numread == 1 && buf[0] == CR)
106 int nt_read(int fd, unsigned char * buf, size_t howmany) {
108 DWORD numread=0,err=0;
113 hRead= (HANDLE)__nt_get_osfhandle(fd);
114 if (hRead == INVALID_HANDLE_VALUE) {
118 ftype = GetFileType(hRead);
121 if ((ftype == FILE_TYPE_CHAR) /*&& (fd != OLDSTD) && (fd != SHIN)*/)
122 return consoleread(hRead,buf,howmany);
124 if (!ReadFile(hRead, buf,(DWORD)howmany,&numread, NULL ) ){
125 err = GetLastError();
127 case ERROR_IO_PENDING:
129 case ERROR_ACCESS_DENIED:
130 case ERROR_INVALID_HANDLE:
134 case ERROR_HANDLE_EOF:
135 case ERROR_BROKEN_PIPE:
144 if (buf[numread-1] == CR)
152 /* color-ls patches from TAGA nayuta (nayuta@is.s.u-tokyo.ac.jp) */
155 int nt_write_(int , const unsigned char * , size_t );
156 int nt_write(int fd, const unsigned char * buf, size_t howmany) {
157 static unsigned char color_buf[256];
164 if (!isatty(fd) || (varval(STRcolor) == NULL))
165 return nt_write_(fd, buf, howmany);
167 for (i = 0; i < howmany; i++) {
170 if (buf[i] == '\x1b') {
171 color_buf[len++] = buf[i];
173 if ((rc=nt_write_(fd, &(buf[start]), i - start)) <0)
185 color_buf[len++] = buf[i];
189 if (buf[i] == 'm' || (!isdigit(buf[i]) && buf[i] != ';'))
191 color_buf[len++] = buf[i];
194 case sizeof(color_buf) - 1:
196 color_buf[len] = '\0';
197 set_attributes(color_buf);
204 if (0 < i - start && 0 <= start) {
205 if ((rc=nt_write_(fd, &(buf[start]), i - start)) < 0)
212 int nt_write_(int fd, const unsigned char * buf, size_t howmany)
213 #else /* if !COLOR_LS_F */
214 int nt_write(int fd, const unsigned char * buf, size_t howmany)
215 #endif /* COLOR_LS_F */
221 hout = (HANDLE)__nt_get_osfhandle(fd);
224 ;// return console_write(hout,buf,howmany);
227 if(!WriteFile(hout, buf,(DWORD)howmany,(ULONG*)&bytes_rtn,
229 err = GetLastError();
231 case ERROR_ACCESS_DENIED:
232 case ERROR_INVALID_HANDLE:
236 case ERROR_BROKEN_PIPE:
245 return bytes_rtn?bytes_rtn:-1;
249 #define IS_CTRL_COMBO(a) ( (a) & ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED) )
250 #define IS_ALT_COMBO(a) ( /*(a) &*/ alt_pressed )
251 #define IS_SHIFT_COMBO(a) ( (a) & SHIFT_PRESSED)
253 int consoleread(HANDLE hInput, unsigned char * buf,size_t howmany) {
255 INPUT_RECORD *irec = NULL;
256 DWORD numread,controlkey,i;
261 int alt_pressed = 0,memfree=0;
263 static int pre_ch = -1;
266 buf[0] = (unsigned char)pre_ch;
271 howmany /= 2; // [ALT + KEY] is expanded ESC KEY, so we need more buffer
276 irec = heap_alloc(howmany*sizeof(INPUT_RECORD));
286 hevents[0] = __h_con_alarm;
287 hevents[1] = __h_con_int;
288 hevents[2] = __h_con_hup;
290 rc = WaitForMultipleObjects(sizeof(hevents)/sizeof(hevents[0]),
291 hevents,FALSE,INFINITE);
292 if (rc == WAIT_OBJECT_0) {
293 generic_handler(SIGALRM);
295 if (rc == (WAIT_OBJECT_0 +1) ) {
297 generic_handler(SIGINT);
300 if (rc == (WAIT_OBJECT_0 +2) ) {
302 generic_handler(SIGHUP);
305 rc = ReadConsoleInput(hInput,irec,(DWORD)howmany,&numread);
309 case ERROR_INVALID_HANDLE:
310 case ERROR_ACCESS_DENIED:
319 for(i=0;i<numread;i++) {
320 switch(irec[i].EventType) {
322 if (irec[i].Event.KeyEvent.bKeyDown) {
323 vcode=(irec[i].Event.KeyEvent.wVirtualKeyCode);
324 ch=(irec[i].Event.KeyEvent.uChar.AsciiChar);
325 controlkey=(irec[i].Event.KeyEvent.dwControlKeyState);
326 if (controlkey & LEFT_ALT_PRESSED)
328 else if (controlkey & RIGHT_ALT_PRESSED){
333 if (__nt_want_vcode != 1)
336 if (vcode >= VK_F1 && vcode <= VK_F24) {
338 __nt_vcode=NT_SPECIFIC_BINDING_OFFSET ;
339 __nt_vcode += (vcode- VK_F1) + SINGLE_KEY_OFFSET;
341 if (IS_CTRL_COMBO(controlkey))
342 __nt_vcode += CTRL_KEY_OFFSET;
344 else if (IS_ALT_COMBO(controlkey))
345 __nt_vcode += ALT_KEY_OFFSET;
346 else if (IS_SHIFT_COMBO(controlkey))
347 __nt_vcode += SHIFT_KEY_OFFSET;
353 else if (vcode>= VK_PRIOR && vcode <= VK_DOWN) {
355 __nt_vcode = NT_SPECIFIC_BINDING_OFFSET ;
356 __nt_vcode += KEYPAD_MAPPING_BEGIN;
357 __nt_vcode += (vcode -VK_PRIOR);
359 __nt_vcode += SINGLE_KEY_OFFSET ;
361 if (IS_CTRL_COMBO(controlkey))
362 __nt_vcode += CTRL_KEY_OFFSET;
364 else if (IS_ALT_COMBO(controlkey))
365 __nt_vcode += ALT_KEY_OFFSET;
366 else if (IS_SHIFT_COMBO(controlkey))
367 __nt_vcode += SHIFT_KEY_OFFSET;
372 else if (vcode == VK_INSERT) {
373 __nt_vcode = NT_SPECIFIC_BINDING_OFFSET ;
374 __nt_vcode += INS_DEL_MAPPING_BEGIN;
376 if (IS_CTRL_COMBO(controlkey))
377 __nt_vcode += CTRL_KEY_OFFSET;
379 else if (IS_ALT_COMBO(controlkey))
380 __nt_vcode += ALT_KEY_OFFSET;
382 else if (IS_SHIFT_COMBO(controlkey))
383 __nt_vcode += SHIFT_KEY_OFFSET;
388 else if (vcode == VK_DELETE) {
389 __nt_vcode = NT_SPECIFIC_BINDING_OFFSET ;
390 __nt_vcode += INS_DEL_MAPPING_BEGIN + 1;
392 if (IS_CTRL_COMBO(controlkey))
393 __nt_vcode += CTRL_KEY_OFFSET;
395 else if (IS_ALT_COMBO(controlkey))
396 __nt_vcode += ALT_KEY_OFFSET;
398 else if (IS_SHIFT_COMBO(controlkey))
399 __nt_vcode += SHIFT_KEY_OFFSET;
413 * Looks like win95 has a spurious
417 VER_PLATFORM_WIN32_WINDOWS &&
420 (void)ReadFile(hInput,&ch,1,&bread,NULL);
422 /* patch from TAGA nayuta */
424 (ch == ' ' || ch == '@') &&
425 IS_CTRL_COMBO(controlkey)
426 /*(controlkey & LEFT_CTRL_PRESSED ||
427 controlkey & RIGHT_CTRL_PRESSED)*/
432 buf[where++] = '\033';
437 #else /* !DSPMBYTE */
438 buf[where++] = ch | 0200;
439 #endif /* !DSPMBYTE */
456 if (howmany < where) // avoid trashing memory. -amol 4/16/97
464 return (int)(where );
466 int console_write(HANDLE hout, unsigned char * buf,int howmany) {
471 rc = WriteConsole(hout,buf,howmany,(DWORD*)&bytes,NULL);