diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
commit | fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch) | |
tree | bdda434976bc09c864f2e4fa6f16ba1952b1e555 /sys/fio/ffault.x | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'sys/fio/ffault.x')
-rw-r--r-- | sys/fio/ffault.x | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/sys/fio/ffault.x b/sys/fio/ffault.x new file mode 100644 index 00000000..76f43f4a --- /dev/null +++ b/sys/fio/ffault.x @@ -0,0 +1,127 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <syserr.h> +include <error.h> +include <config.h> +include <fio.h> + +# FFAULT -- Read a file block into the file buffer (pick up file buffer and +# put it down on another part of the file). Although in this implementation +# there is only a single, local, file buffer for each file, in the future +# a variable number of either global or local buffers will be supported, as +# well as read ahead and write behind (see Fio.doc). + +int procedure ffault (fd, file_offset, nreserve, rwflag) + +int fd +long file_offset # char offset to be faulted in +int nreserve # size of transfer pending +int rwflag # next access is a read or a write + +pointer bp +long buffer_offset, fboff +int bufsize, nchars_read +bool block_write, stream, at_eof + +int and() +errchk ffilbf, fflsbf, fwatio +define ioerror_ 91 +include <fio.com> + +begin + # assert (file open, buffer already created) + # assert (iop does not point into buffer) + + fp = fiodes[fd] + bp = bufptr[fd] + bufsize = FBUFSIZE(fp) + fboff = FIRSTBUFOFF(fp) + stream = (FBLKSIZE(fp) == 0) + + # Calculate buffer_offset (modulus file buffer size). If the output + # device is a pipe or terminal (stream device), which does not permit + # rewriting of data and seeking, empty buffer. + + if (stream) { + buffer_offset = file_offset + } else if (file_offset <= 0) { + iferr (call filerr (FNAME(fp), SYS_FSEEK)) + goto ioerror_ + } else + buffer_offset = (file_offset-fboff) / bufsize * bufsize + fboff + + # Update i/o pointers (if an empty or partially full buffer has been + # written into, determine the top of the valid part of the buffer). + + UPDATE_IOP(fd) + + # Flush buffer if it has been written into. Write out only as much + # of the buffer as has been filled. + + if (BUF_MODIFIED(fd)) { + iferr (call fflsbf (fd, bp, otop[fd]-bp, boffset[fd])) + goto ioerror_ + + # We need to do this wait here since we immediately use this buffer + # without doing a wait. Which screws up the data going out to disk. + # This can be done away with when multi-buffering is done. (FJR). + + call fwatio (fd) + } + + # Fill buffer from file only if the file was opened with read + # permission, and if the fault was not caused by a WRITE which will + # immediately overwrite the entire contents of the buffer. + + if (rwflag == FF_WRITE) { + block_write = (stream || + (file_offset == buffer_offset && nreserve >= bufsize)) + } else + block_write = false + + if (block_write) { + itop[fd] = bp + otop[fd] = bp + + } else if (and(FF_READ,fflags[fd]) == 0) { + # Read is disabled. Zero-fill buffer; if inside existing + # random access file, set ITOP to end of buffer so that the + # entire buffer will be written when flushed. + + at_eof = (FILSIZE(fp) >= 0 && buffer_offset > FILSIZE(fp)) + otop[fd] = bp + + if (at_eof) + itop[fd] = bp + else + itop[fd] = bp + bufsize + + # Zero-fill the buffer. + call aclrc (Memc[bp], bufsize) + + } else { + iferr { + # Initialize buffer from file. + call ffilbf (fd, bp, bufsize, buffer_offset) + call fwatio (fd) + } then + goto ioerror_ + } + + boffset[fd] = buffer_offset + LSEEK (fd, file_offset) # set i/o pointer + + nchars_read = itop[fd] - iop[fd] + if (nchars_read <= 0) + return (EOF) + else + return (nchars_read) # only valid for a read + + # If an i/o error occurs, mark the buffer empty and pass the error + # back to our caller. + +ioerror_ + itop[fd] = bp + otop[fd] = bp + call erract (EA_ERROR) +end |