home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / ixemul-45.0-src.tgz / tar.out / contrib / ixemul / library / __read.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  157 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  __read.c,v 1.1.1.1 1994/04/04 04:30:12 amiga Exp
  20.  *
  21.  *  __read.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:30:12  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  *  Revision 1.1  1992/05/14  19:55:40  mwild
  26.  *  Initial revision
  27.  *
  28.  */
  29.  
  30. #define _KERNEL
  31. #include "ixemul.h"
  32. #include "kprintf.h"
  33.  
  34. /*
  35.  * Starting with ixemul 42.0 we switched from asynchronous to synchronous
  36.  * reads.  Apparently the ADOS CON handler uses the mp_SigTask field of the
  37.  * MsgPort struct of an ACTION_READ package to find the Task which it should
  38.  * signal when the user presses Ctrl-C.  However, async reads use a special
  39.  * port where the mp_SigTask field points to an Interrupt struct.  The CON
  40.  * handler seems to either use that address as the new Task pointer (I hope
  41.  * not) or disable Ctrl-C signalling entirely.  I never noticed this until it
  42.  * was pointed out to me, since I always use KingCON. KingCON seems to handle
  43.  * Ctrl-C differently. Just to be sure I also changed the ACTION_WAIT_CHAR
  44.  * to synchronous mode.
  45.  *
  46.  * Starting with 43.1 I no longer use async writes at all. The overhead in
  47.  * handling async writes turned out to be bigger than the gain.
  48.  */
  49.  
  50. int __read(struct file *f, char *buf, int len)
  51. {
  52.   int err = errno, res = 0;
  53.   int omask;
  54.   char *orig_buf;
  55.  
  56.   /* always return EOF */
  57.   if (HANDLER_NIL(f)) return 0;
  58.  
  59.   omask = syscall (SYS_sigsetmask, ~0);
  60.   __get_file (f);
  61.   
  62.   if (f->f_ttyflags & IXTTY_PKT)
  63.     {
  64.       len--;
  65.       *buf++ = 0;
  66.     }
  67.  
  68.   orig_buf = buf;
  69.  
  70.   if (len > 0)
  71.     {
  72.       /* if interactive and don't block */
  73.       if (f->f_fh->fh_Port && f->f_flags & FNDELAY)
  74.     {
  75.       /* shudder.. this is the most inefficient part of the whole
  76.        * library, but I don't know of another way of doing it... */
  77.       while (res < len)
  78.             {
  79.               SendPacket1(f, __srwport, ACTION_WAIT_CHAR, 0);
  80.               __wait_sync_packet(&f->f_sp);
  81.               if (! LastResult(f))
  82.               {
  83.                 if (!res)
  84.                 {
  85.                   res = -1;
  86.                   err = EAGAIN;
  87.                 }
  88.                 break;
  89.               }
  90.           SendPacket3(f, __srwport, ACTION_READ, f->f_fh->fh_Arg1, (long)buf, 1);
  91.           __wait_sync_packet(&f->f_sp);
  92.           if (LastResult(f) != 1) 
  93.         {
  94.           err = __ioerr_to_errno(LastError(f));
  95.           /* if there really was no character to read, we should
  96.            * have escaped already at the 'if WaitForChar' line */
  97.           res = -1;
  98.           break;
  99.         }
  100.           buf++;
  101.           res++;
  102.         }
  103.     }      
  104.       else
  105.     {
  106.       SendPacket3(f, __srwport, ACTION_READ, f->f_fh->fh_Arg1, (long)buf, len);
  107.       __wait_sync_packet(&f->f_sp);
  108.       res = LastResult(f);
  109.       if (res == -1)
  110.         err = __ioerr_to_errno(LastError(f));
  111.     }
  112.    }
  113.  
  114.   LastResult(f) = 0;
  115.   __release_file (f);
  116.   syscall (SYS_sigsetmask, omask);
  117.   errno = err;
  118.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  119.   
  120.   /*  If we read something from a file, and the file is opened RAW (e.g., a stdin
  121.    *  stream in RAW mode), then we replace all '\r' characters with '\n' characters.
  122.    *  This is a courtesy for those programs that turn off ECHO for the input of a
  123.    *  password. Turning off ECHO sets the input mode to RAW, and in RAW mode the
  124.    *  Enter key inserts a '\r' into the stream. However, the stdio functions expect
  125.    *  a '\n' to end a line, so we patch the input buffer.
  126.    *
  127.    * Actually, the application sets the CR->NL or NL->CR translation
  128.    * through the termios interface. Amiga cooked mode already performs the
  129.    * normal CR->NL conversion, so we only do that transformation when in
  130.    * raw mode.
  131.    */
  132.   if (res > 0 && 
  133.       ((f->f_ttyflags & IXTTY_INLCR) ||
  134.        ((f->f_ttyflags & IXTTY_RAW) && (f->f_ttyflags & IXTTY_ICRNL))))
  135.     {
  136.       int i;
  137.       char match, subst;
  138.  
  139.       if (f->f_ttyflags & IXTTY_INLCR)
  140.         {
  141.           match = '\n';
  142.       subst = '\r';
  143.         }
  144.       else
  145.         {
  146.           match = '\r';
  147.       subst = '\n';
  148.         }
  149.       for (i = 0; i < res; i++)
  150.         if (orig_buf[i] == match)
  151.           orig_buf[i] = subst;
  152.     }
  153.   if (res > 0 && f->f_ttyflags & IXTTY_PKT)
  154.     res++;
  155.   return res;
  156. }
  157.