diff options
Diffstat (limited to 'byterun/io.c')
-rw-r--r-- | byterun/io.c | 393 |
1 files changed, 0 insertions, 393 deletions
diff --git a/byterun/io.c b/byterun/io.c deleted file mode 100644 index 67bc961f78..0000000000 --- a/byterun/io.c +++ /dev/null @@ -1,393 +0,0 @@ -/* Buffered input/output. */ - -#include <errno.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include "alloc.h" -#include "fail.h" -#include "io.h" -#include "memory.h" -#include "misc.h" -#include "mlvalues.h" -#include "signals.h" -#include "sys.h" -#ifdef HAS_UI -#include "ui.h" -#endif - -/* Common functions. */ - -struct channel * open_descr(fd) - int fd; -{ - struct channel * channel; - - channel = (struct channel *) stat_alloc(sizeof(struct channel)); - channel->fd = fd; - channel->offset = 0; - channel->curr = channel->max = channel->buff; - channel->end = channel->buff + IO_BUFFER_SIZE; - return channel; -} - -value open_descriptor(fd) /* ML */ - value fd; -{ - return (value) open_descr(Int_val(fd)); -} - -value channel_descriptor(channel) /* ML */ - struct channel * channel; -{ - return Val_long(channel->fd); -} - -value channel_size(channel) /* ML */ - struct channel * channel; -{ - long end; - - end = lseek(channel->fd, 0, 2); - if (end == -1) sys_error(NULL); - if (lseek(channel->fd, channel->offset, 0) != channel->offset) - sys_error(NULL); - return Val_long(end); -} - -/* Output */ - -static void really_write(fd, p, n) - int fd; - char * p; - int n; -{ - int retcode; - while (n > 0) { -#ifdef HAS_UI - retcode = ui_write(fd, p, n); -#else -#ifdef EINTR - do { retcode = write(fd, p, n); } while (retcode == -1 && errno == EINTR); -#else - retcode = write(fd, p, n); -#endif -#endif - if (retcode == -1) sys_error(NULL); - p += retcode; - n -= retcode; - } -} - -value flush(channel) /* ML */ - struct channel * channel; -{ - int n; - n = channel->max - channel->buff; - if (n > 0) { - really_write(channel->fd, channel->buff, n); - channel->offset += n; - channel->curr = channel->buff; - channel->max = channel->buff; - } - return Atom(0); -} - -value output_char(channel, ch) /* ML */ - struct channel * channel; - value ch; -{ - putch(channel, Long_val(ch)); - return Atom(0); -} - -void putword(channel, w) - struct channel * channel; - uint32 w; -{ - putch(channel, w >> 24); - putch(channel, w >> 16); - putch(channel, w >> 8); - putch(channel, w); -} - -value output_int(channel, w) /* ML */ - struct channel * channel; - value w; -{ - putword(channel, Long_val(w)); - return Atom(0); -} - -void putblock(channel, p, n) - struct channel * channel; - char * p; - unsigned n; -{ - unsigned m; - - m = channel->end - channel->curr; - if (channel->curr == channel->buff && n >= m) { - really_write(channel->fd, p, n); - channel->offset += n; - } else if (n <= m) { - bcopy(p, channel->curr, n); - channel->curr += n; - if (channel->curr > channel->max) channel->max = channel->curr; - } else { - bcopy(p, channel->curr, m); - p += m; - n -= m; - m = channel->end - channel->buff; - really_write(channel->fd, channel->buff, m); - channel->offset += m; - if (n <= m) { - bcopy(p, channel->buff, n); - channel->curr = channel->max = channel->buff + n; - } else { - really_write(channel->fd, p, n); - channel->offset += n; - channel->curr = channel->max = channel->buff; - } - } -} - -value output(channel, buff, start, length) /* ML */ - value channel, buff, start, length; -{ - putblock((struct channel *) channel, - &Byte(buff, Long_val(start)), - (unsigned) Long_val(length)); - return Atom(0); -} - -value seek_out(channel, pos) /* ML */ - struct channel * channel; - value pos; -{ - long dest; - - dest = Long_val(pos); - if (dest >= channel->offset && - dest <= channel->offset + channel->max - channel->buff) { - channel->curr = channel->buff + dest - channel->offset; - } else { - flush(channel); - if (lseek(channel->fd, dest, 0) != dest) sys_error(NULL); - channel->offset = dest; - } - return Atom(0); -} - -value pos_out(channel) /* ML */ - struct channel * channel; -{ - return Val_long(channel->offset + channel->curr - channel->buff); -} - -value close_out(channel) /* ML */ - struct channel * channel; -{ - flush(channel); - close(channel->fd); - stat_free((char *) channel); - return Atom(0); -} - -/* Input */ - -static int really_read(fd, p, n) - int fd; - char * p; - unsigned n; -{ - int retcode; - - enter_blocking_section(); -#ifdef HAS_UI - retcode = ui_read(fd, p, n); -#else -#ifdef EINTR - do { retcode = read(fd, p, n); } while (retcode == -1 && errno == EINTR); -#else - retcode = read(fd, p, n); -#endif -#endif - leave_blocking_section(); - if (retcode == -1) sys_error(NULL); - return retcode; -} - -unsigned char refill(channel) - struct channel * channel; -{ - int n; - - n = really_read(channel->fd, channel->buff, IO_BUFFER_SIZE); - if (n == 0) raise_end_of_file(); - channel->offset += n; - channel->max = channel->buff + n; - channel->curr = channel->buff + 1; - return (unsigned char)(channel->buff[0]); -} - -value input_char(channel) /* ML */ - struct channel * channel; -{ - unsigned char c; - c = getch(channel); - return Val_long(c); -} - -uint32 getword(channel) - struct channel * channel; -{ - int i; - uint32 res; - - res = 0; - for(i = 0; i < 4; i++) { - res = (res << 8) + getch(channel); - } - return res; -} - -value input_int(channel) /* ML */ - struct channel * channel; -{ - long i; - i = getword(channel); -#ifdef SIXTYFOUR - i = (i << 32) >> 32; /* Force sign extension */ -#endif - return Val_long(i); -} - -unsigned getblock(channel, p, n) - struct channel * channel; - char * p; - unsigned n; -{ - unsigned m, l; - - m = channel->max - channel->curr; - if (n <= m) { - bcopy(channel->curr, p, n); - channel->curr += n; - return n; - } else if (m > 0) { - bcopy(channel->curr, p, m); - channel->curr += m; - return m; - } else if (n < IO_BUFFER_SIZE) { - l = really_read(channel->fd, channel->buff, IO_BUFFER_SIZE); - channel->offset += l; - channel->max = channel->buff + l; - if (n > l) n = l; - bcopy(channel->buff, p, n); - channel->curr = channel->buff + n; - return n; - } else { - channel->curr = channel->buff; - channel->max = channel->buff; - l = really_read(channel->fd, p, n); - channel->offset += l; - return l; - } -} - -int really_getblock(chan, p, n) - struct channel * chan; - char * p; - unsigned long n; -{ - unsigned r; - while (n > 0) { - r = getblock(chan, p, (unsigned) n); - if (r == 0) return 0; - p += r; - n -= r; - } - return 1; -} - -value input(channel, buff, start, length) /* ML */ - value channel, buff, start, length; -{ - return Val_long(getblock((struct channel *) channel, - &Byte(buff, Long_val(start)), - (unsigned) Long_val(length))); -} - -value seek_in(channel, pos) /* ML */ - struct channel * channel; - value pos; -{ - long dest; - - dest = Long_val(pos); - if (dest >= channel->offset - (channel->max - channel->buff) && - dest <= channel->offset) { - channel->curr = channel->max - (channel->offset - dest); - } else { - if (lseek(channel->fd, dest, 0) != dest) sys_error(NULL); - channel->offset = dest; - channel->curr = channel->max = channel->buff; - } - return Atom(0); -} - -value pos_in(channel) /* ML */ - struct channel * channel; -{ - return Val_long(channel->offset - (channel->max - channel->curr)); -} - -value close_in(channel) /* ML */ - struct channel * channel; -{ - close(channel->fd); - stat_free((char *) channel); - return Atom(0); -} - -value input_scan_line(channel) /* ML */ - struct channel * channel; -{ - char * p; - int n; - - p = channel->curr; - do { - if (p >= channel->max) { - /* No more characters available in the buffer */ - if (channel->curr > channel->buff) { - /* Try to make some room in the buffer by shifting the unread - portion at the beginning */ - bcopy(channel->curr, channel->buff, channel->max - channel->curr); - n = channel->curr - channel->buff; - channel->curr -= n; - channel->max -= n; - p -= n; - } - if (channel->max >= channel->end) { - /* Buffer is full, no room to read more characters from the input. - Return the number of characters in the buffer, with negative - sign to indicate that no newline was encountered. */ - return Val_long(-(channel->max - channel->curr)); - } - /* Fill the buffer as much as possible */ - n = really_read(channel->fd, channel->max, channel->end - channel->max); - if (n == 0) { - /* End-of-file encountered. Return the number of characters in the - buffer, with negative sign since we haven't encountered - a newline. */ - return Val_long(-(channel->max - channel->curr)); - } - channel->offset += n; - channel->max += n; - } - } while (*p++ != '\n'); - /* Found a newline. Return the length of the line, newline included. */ - return Val_long(p - channel->curr); -} |