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 >
Wrap
C/C++ Source or Header
|
1996-09-28
|
5KB
|
157 lines
/*
* This file is part of ixemul.library for the Amiga.
* Copyright (C) 1991, 1992 Markus M. Wild
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* __read.c,v 1.1.1.1 1994/04/04 04:30:12 amiga Exp
*
* __read.c,v
* Revision 1.1.1.1 1994/04/04 04:30:12 amiga
* Initial CVS check in.
*
* Revision 1.1 1992/05/14 19:55:40 mwild
* Initial revision
*
*/
#define _KERNEL
#include "ixemul.h"
#include "kprintf.h"
/*
* Starting with ixemul 42.0 we switched from asynchronous to synchronous
* reads. Apparently the ADOS CON handler uses the mp_SigTask field of the
* MsgPort struct of an ACTION_READ package to find the Task which it should
* signal when the user presses Ctrl-C. However, async reads use a special
* port where the mp_SigTask field points to an Interrupt struct. The CON
* handler seems to either use that address as the new Task pointer (I hope
* not) or disable Ctrl-C signalling entirely. I never noticed this until it
* was pointed out to me, since I always use KingCON. KingCON seems to handle
* Ctrl-C differently. Just to be sure I also changed the ACTION_WAIT_CHAR
* to synchronous mode.
*
* Starting with 43.1 I no longer use async writes at all. The overhead in
* handling async writes turned out to be bigger than the gain.
*/
int __read(struct file *f, char *buf, int len)
{
int err = errno, res = 0;
int omask;
char *orig_buf;
/* always return EOF */
if (HANDLER_NIL(f)) return 0;
omask = syscall (SYS_sigsetmask, ~0);
__get_file (f);
if (f->f_ttyflags & IXTTY_PKT)
{
len--;
*buf++ = 0;
}
orig_buf = buf;
if (len > 0)
{
/* if interactive and don't block */
if (f->f_fh->fh_Port && f->f_flags & FNDELAY)
{
/* shudder.. this is the most inefficient part of the whole
* library, but I don't know of another way of doing it... */
while (res < len)
{
SendPacket1(f, __srwport, ACTION_WAIT_CHAR, 0);
__wait_sync_packet(&f->f_sp);
if (! LastResult(f))
{
if (!res)
{
res = -1;
err = EAGAIN;
}
break;
}
SendPacket3(f, __srwport, ACTION_READ, f->f_fh->fh_Arg1, (long)buf, 1);
__wait_sync_packet(&f->f_sp);
if (LastResult(f) != 1)
{
err = __ioerr_to_errno(LastError(f));
/* if there really was no character to read, we should
* have escaped already at the 'if WaitForChar' line */
res = -1;
break;
}
buf++;
res++;
}
}
else
{
SendPacket3(f, __srwport, ACTION_READ, f->f_fh->fh_Arg1, (long)buf, len);
__wait_sync_packet(&f->f_sp);
res = LastResult(f);
if (res == -1)
err = __ioerr_to_errno(LastError(f));
}
}
LastResult(f) = 0;
__release_file (f);
syscall (SYS_sigsetmask, omask);
errno = err;
KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
/* If we read something from a file, and the file is opened RAW (e.g., a stdin
* stream in RAW mode), then we replace all '\r' characters with '\n' characters.
* This is a courtesy for those programs that turn off ECHO for the input of a
* password. Turning off ECHO sets the input mode to RAW, and in RAW mode the
* Enter key inserts a '\r' into the stream. However, the stdio functions expect
* a '\n' to end a line, so we patch the input buffer.
*
* Actually, the application sets the CR->NL or NL->CR translation
* through the termios interface. Amiga cooked mode already performs the
* normal CR->NL conversion, so we only do that transformation when in
* raw mode.
*/
if (res > 0 &&
((f->f_ttyflags & IXTTY_INLCR) ||
((f->f_ttyflags & IXTTY_RAW) && (f->f_ttyflags & IXTTY_ICRNL))))
{
int i;
char match, subst;
if (f->f_ttyflags & IXTTY_INLCR)
{
match = '\n';
subst = '\r';
}
else
{
match = '\r';
subst = '\n';
}
for (i = 0; i < res; i++)
if (orig_buf[i] == match)
orig_buf[i] = subst;
}
if (res > 0 && f->f_ttyflags & IXTTY_PKT)
res++;
return res;
}