/* * _read: like read, but takes a long instead of an int. Written by * Eric R. Smith and placed in the public domain. */ #include #include #include #include #include #include #include "lib.h" #define CTRL(x) (x & 0x1f) #define UNDEF -1 struct tchars __tchars = { CTRL('C'), /* interrupt */ CTRL('\\'), /* quit */ CTRL('Q'), /* start */ CTRL('S'), /* stop */ CTRL('D'), /* EOF */ '\r' /* alternate end of line */ }; struct ltchars __ltchars = { CTRL('Z'), /* suspend */ CTRL('Y'), /* suspend after read */ CTRL('R'), /* reprint */ UNDEF, /* flush output */ UNDEF, /* erase word */ UNDEF /* quote next char */ }; /* * BUGS: in tos, turning ECHO off but leaving RAW and CBREAK alone doesn't * work properly */ long _read(fd, buf, size) int fd; void *buf; long size; { char *foo; long r; extern int __mint; int indx; int flags; if (isatty(fd)) { /* work around a bug in TOS; 4096 bytes should be plenty for terminal reads */ if (size > 4096) size = 4096; indx = __OPEN_INDEX(fd); if (indx < 0 || indx >= __NHANDLES) indx = __NHANDLES - 1; flags = __open_stat[indx].flags; } else flags = -1; if ( (__mint > 0) || (flags == -1) || ( ((flags & (RAW|CBREAK)) == 0) && (flags & ECHO) ) ) { r = Fread(fd, size, buf); if (r < 0) { errno = -r; return -1; } /* watch out for TTYs */ if (__mint == 0 && isatty(fd)) { foo = (char *)buf; if (*foo == 4) /* ^D for EOF?? */ return 0; foo[r] = '\n'; /* %!#@ TOS doesn't put in the LF */ Cconout('\n'); /* not quite right if fd != 0 */ r++; } } else { again: r = _console_read_byte(fd) & 0x00ff; if (flags & ECHO) { _console_write_byte(fd, (int)r); } if (flags & CRMOD) { if (r == '\r') r = '\n'; } if (!(flags & RAW)) { if (r == __tchars.t_intrc) { raise(SIGINT); goto again; } else if (r == __tchars.t_quitc) { raise(SIGQUIT); goto again; } } *((char *)buf) = r; r = 1; } return r; } int read(fd, buf, size) int fd; void *buf; unsigned size; { return _read(fd, buf, (long)size); }