=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/less/ch.c,v retrieving revision 1.10 retrieving revision 1.11 diff -c -r1.10 -r1.11 *** src/usr.bin/less/ch.c 2014/04/25 13:38:21 1.10 --- src/usr.bin/less/ch.c 2015/11/05 22:08:43 1.11 *************** *** 6,13 **** * * For more information, see the README file. */ - /* * Low level character input from the input file. * We use these special purpose routines which optimize moving --- 6,16 ---- * * For more information, see the README file. */ + /* + * Modified for use with illumos. + * Copyright 2014 Garrett D'Amore + */ /* * Low level character input from the input file. * We use these special purpose routines which optimize moving *************** *** 15,34 **** */ #include "less.h" - #if MSDOS_COMPILER==WIN32C - #include - #include - #endif - #if HAVE_STAT_INO #include extern dev_t curr_dev; extern ino_t curr_ino; ! #endif ! typedef POSITION BLOCKNUM; ! public int ignore_eoi; /* * Pool of buffers holding the most recently used blocks of the input file. --- 18,32 ---- */ #include "less.h" #include extern dev_t curr_dev; extern ino_t curr_ino; ! extern int less_is_more; ! typedef off_t BLOCKNUM; ! int ignore_eoi; /* * Pool of buffers holding the most recently used blocks of the input file. *************** *** 48,54 **** unsigned int datasize; unsigned char data[LBUFSIZE]; }; ! #define bufnode_buf(bn) ((struct buf *) bn) /* * The file state is maintained in a filestate structure. --- 46,52 ---- unsigned int datasize; unsigned char data[LBUFSIZE]; }; ! #define bufnode_buf(bn) ((struct buf *)bn) /* * The file state is maintained in a filestate structure. *************** *** 60,70 **** struct bufnode hashtbl[BUFHASH_SIZE]; int file; int flags; ! POSITION fpos; int nbufs; BLOCKNUM block; unsigned int offset; ! POSITION fsize; }; #define ch_bufhead thisfile->buflist.next --- 58,68 ---- struct bufnode hashtbl[BUFHASH_SIZE]; int file; int flags; ! off_t fpos; int nbufs; BLOCKNUM block; unsigned int offset; ! off_t fsize; }; #define ch_bufhead thisfile->buflist.next *************** *** 79,85 **** #define END_OF_CHAIN (&thisfile->buflist) #define END_OF_HCHAIN(h) (&thisfile->hashtbl[h]) ! #define BUFHASH(blk) ((blk) & (BUFHASH_SIZE-1)) /* * Macros to manipulate the list of buffers in thisfile->buflist. --- 77,83 ---- #define END_OF_CHAIN (&thisfile->buflist) #define END_OF_HCHAIN(h) (&thisfile->hashtbl[h]) ! #define BUFHASH(blk) ((blk) & (BUFHASH_SIZE-1)) /* * Macros to manipulate the list of buffers in thisfile->buflist. *************** *** 87,103 **** #define FOR_BUFS(bn) \ for (bn = ch_bufhead; bn != END_OF_CHAIN; bn = bn->next) ! #define BUF_RM(bn) \ (bn)->next->prev = (bn)->prev; \ (bn)->prev->next = (bn)->next; ! #define BUF_INS_HEAD(bn) \ (bn)->next = ch_bufhead; \ (bn)->prev = END_OF_CHAIN; \ ch_bufhead->prev = (bn); \ ch_bufhead = (bn); ! #define BUF_INS_TAIL(bn) \ (bn)->next = END_OF_CHAIN; \ (bn)->prev = ch_buftail; \ ch_buftail->next = (bn); \ --- 85,101 ---- #define FOR_BUFS(bn) \ for (bn = ch_bufhead; bn != END_OF_CHAIN; bn = bn->next) ! #define BUF_RM(bn) \ (bn)->next->prev = (bn)->prev; \ (bn)->prev->next = (bn)->next; ! #define BUF_INS_HEAD(bn) \ (bn)->next = ch_bufhead; \ (bn)->prev = END_OF_CHAIN; \ ch_bufhead->prev = (bn); \ ch_bufhead = (bn); ! #define BUF_INS_TAIL(bn) \ (bn)->next = END_OF_CHAIN; \ (bn)->prev = ch_buftail; \ ch_buftail->next = (bn); \ *************** *** 106,120 **** /* * Macros to manipulate the list of buffers in thisfile->hashtbl[n]. */ ! #define FOR_BUFS_IN_CHAIN(h,bn) \ for (bn = thisfile->hashtbl[h].hnext; \ ! bn != END_OF_HCHAIN(h); bn = bn->hnext) #define BUF_HASH_RM(bn) \ (bn)->hnext->hprev = (bn)->hprev; \ (bn)->hprev->hnext = (bn)->hnext; ! #define BUF_HASH_INS(bn,h) \ (bn)->hnext = thisfile->hashtbl[h].hnext; \ (bn)->hprev = END_OF_HCHAIN(h); \ thisfile->hashtbl[h].hnext->hprev = (bn); \ --- 104,118 ---- /* * Macros to manipulate the list of buffers in thisfile->hashtbl[n]. */ ! #define FOR_BUFS_IN_CHAIN(h, bn) \ for (bn = thisfile->hashtbl[h].hnext; \ ! bn != END_OF_HCHAIN(h); bn = bn->hnext) #define BUF_HASH_RM(bn) \ (bn)->hnext->hprev = (bn)->hprev; \ (bn)->hprev->hnext = (bn)->hnext; ! #define BUF_HASH_INS(bn, h) \ (bn)->hnext = thisfile->hashtbl[h].hnext; \ (bn)->hprev = END_OF_HCHAIN(h); \ thisfile->hashtbl[h].hnext->hprev = (bn); \ *************** *** 130,169 **** extern int screen_trashed; extern int follow_mode; extern IFILE curr_ifile; - #if LOGFILE extern int logfile; extern char *namelogfile; - #endif ! static int ch_addbuf(); /* * Get the character pointed to by the read pointer. */ ! int ! ch_get() { ! register struct buf *bp; ! register struct bufnode *bn; ! register int n; ! register int slept; ! register int h; ! POSITION pos; ! POSITION len; if (thisfile == NULL) return (EOI); /* ! * Quick check for the common case where * the desired char is in the head buffer. */ ! if (ch_bufhead != END_OF_CHAIN) ! { bp = bufnode_buf(ch_bufhead); if (ch_block == bp->block && ch_offset < bp->datasize) ! return bp->data[ch_offset]; } slept = FALSE; --- 128,164 ---- extern int screen_trashed; extern int follow_mode; extern IFILE curr_ifile; extern int logfile; extern char *namelogfile; ! static int ch_addbuf(void); /* * Get the character pointed to by the read pointer. */ ! int ! ch_get(void) { ! struct buf *bp; ! struct bufnode *bn; ! int n; ! int slept; ! int h; ! off_t pos; ! off_t len; if (thisfile == NULL) return (EOI); /* ! * Quick check for the common case where * the desired char is in the head buffer. */ ! if (ch_bufhead != END_OF_CHAIN) { bp = bufnode_buf(ch_bufhead); if (ch_block == bp->block && ch_offset < bp->datasize) ! return (bp->data[ch_offset]); } slept = FALSE; *************** *** 172,182 **** * Look for a buffer holding the desired block. */ h = BUFHASH(ch_block); ! FOR_BUFS_IN_CHAIN(h, bn) ! { bp = bufnode_buf(bn); ! if (bp->block == ch_block) ! { if (ch_offset >= bp->datasize) /* * Need more data in this buffer. --- 167,175 ---- * Look for a buffer holding the desired block. */ h = BUFHASH(ch_block); ! FOR_BUFS_IN_CHAIN(h, bn) { bp = bufnode_buf(bn); ! if (bp->block == ch_block) { if (ch_offset >= bp->datasize) /* * Need more data in this buffer. *************** *** 185,210 **** goto found; } } ! if (bn == END_OF_HCHAIN(h)) ! { /* ! * Block is not in a buffer. ! * Take the least recently used buffer * and read the desired block into it. ! * If the LRU buffer has data in it, * then maybe allocate a new buffer. */ ! if (ch_buftail == END_OF_CHAIN || ! bufnode_buf(ch_buftail)->block != -1) ! { /* * There is no empty buffer to use. * Allocate a new buffer if: ! * 1. We can't seek on this file and -b is not in effect; or ! * 2. We haven't allocated the max buffers for this file yet. */ if ((autobuf && !(ch_flags & CH_CANSEEK)) || ! (maxbufs < 0 || ch_nbufs < maxbufs)) if (ch_addbuf()) /* * Allocation failed: turn off autobuf. --- 178,203 ---- goto found; } } ! if (bn == END_OF_HCHAIN(h)) { /* ! * Block is not in a buffer. ! * Take the least recently used buffer * and read the desired block into it. ! * If the LRU buffer has data in it, * then maybe allocate a new buffer. */ ! if (ch_buftail == END_OF_CHAIN || ! bufnode_buf(ch_buftail)->block != -1) { /* * There is no empty buffer to use. * Allocate a new buffer if: ! * 1. We can't seek on this file and -b is not in ! * effect; or ! * 2. We haven't allocated the max buffers for this ! * file yet. */ if ((autobuf && !(ch_flags & CH_CANSEEK)) || ! (maxbufs < 0 || ch_nbufs < maxbufs)) if (ch_addbuf()) /* * Allocation failed: turn off autobuf. *************** *** 219,234 **** BUF_HASH_INS(bn, h); /* Insert into new hash chain. */ } ! read_more: pos = (ch_block * LBUFSIZE) + bp->datasize; ! if ((len = ch_length()) != NULL_POSITION && pos >= len) /* * At end of file. */ return (EOI); ! if (pos != ch_fpos) ! { /* * Not at the correct position: must seek. * If input is a pipe, we're in trouble (can't seek on a pipe). --- 212,226 ---- BUF_HASH_INS(bn, h); /* Insert into new hash chain. */ } ! read_more: pos = (ch_block * LBUFSIZE) + bp->datasize; ! if ((len = ch_length()) != -1 && pos >= len) /* * At end of file. */ return (EOI); ! if (pos != ch_fpos) { /* * Not at the correct position: must seek. * If input is a pipe, we're in trouble (can't seek on a pipe). *************** *** 236,287 **** */ if (!(ch_flags & CH_CANSEEK)) return ('?'); ! if (lseek(ch_file, (off_t)pos, SEEK_SET) == BAD_LSEEK) ! { ! error("seek error", NULL_PARG); clear_eol(); return (EOI); ! } ! ch_fpos = pos; ! } /* * Read the block. * If we read less than a full block, that's ok. * We use partial block and pick up the rest next time. */ ! if (ch_ungotchar != -1) ! { ! bp->data[bp->datasize] = ch_ungotchar; n = 1; ch_ungotchar = -1; ! } else ! { ! n = iread(ch_file, &bp->data[bp->datasize], ! (unsigned int)(LBUFSIZE - bp->datasize)); } if (n == READ_INTR) return (EOI); ! if (n < 0) ! { ! #if MSDOS_COMPILER==WIN32C ! if (errno != EPIPE) ! #endif ! { ! error("read error", NULL_PARG); ! clear_eol(); ! } n = 0; } - #if LOGFILE /* * If we have a log file, write the new data to it. */ if (!secure && logfile >= 0 && n > 0) ! write(logfile, (char *) &bp->data[bp->datasize], n); ! #endif ch_fpos += n; bp->datasize += n; --- 228,268 ---- */ if (!(ch_flags & CH_CANSEEK)) return ('?'); ! if (lseek(ch_file, (off_t)pos, SEEK_SET) == BAD_LSEEK) { ! error("seek error", NULL_PARG); clear_eol(); return (EOI); ! } ! ch_fpos = pos; ! } /* * Read the block. * If we read less than a full block, that's ok. * We use partial block and pick up the rest next time. */ ! if (ch_ungotchar != -1) { ! bp->data[bp->datasize] = (unsigned char)ch_ungotchar; n = 1; ch_ungotchar = -1; ! } else { ! n = iread(ch_file, &bp->data[bp->datasize], ! (unsigned int)(LBUFSIZE - bp->datasize)); } if (n == READ_INTR) return (EOI); ! if (n < 0) { ! error("read error", NULL_PARG); ! clear_eol(); n = 0; } /* * If we have a log file, write the new data to it. */ if (!secure && logfile >= 0 && n > 0) ! (void) write(logfile, (char *)&bp->data[bp->datasize], n); ch_fpos += n; bp->datasize += n; *************** *** 290,345 **** * If we have read to end of file, set ch_fsize to indicate * the position of the end of file. */ ! if (n == 0) ! { ch_fsize = pos; ! if (ignore_eoi) ! { /* * We are ignoring EOF. * Wait a while, then try again. */ ! if (!slept) ! { PARG parg; parg.p_string = wait_message(); ierror("%s", &parg); } ! #if !MSDOS_COMPILER ! sleep(1); ! #else ! #if MSDOS_COMPILER==WIN32C ! Sleep(1000); ! #endif ! #endif slept = TRUE; ! #if HAVE_STAT_INO ! if (follow_mode == FOLLOW_NAME) ! { ! /* See whether the file's i-number has changed. * If so, force the file to be closed and ! * reopened. */ struct stat st; int r = stat(get_filename(curr_ifile), &st); if (r == 0 && (st.st_ino != curr_ino || ! st.st_dev != curr_dev)) ! { ! /* screen_trashed=2 causes ! * make_display to reopen the file. */ screen_trashed = 2; return (EOI); } } - #endif } if (sigs) return (EOI); } ! found: ! if (ch_bufhead != bn) ! { /* * Move the buffer to the head of the buffer chain. * This orders the buffer chain, most- to least-recently used. --- 271,316 ---- * If we have read to end of file, set ch_fsize to indicate * the position of the end of file. */ ! if (n == 0) { ch_fsize = pos; ! if (ignore_eoi) { /* * We are ignoring EOF. * Wait a while, then try again. */ ! if (!slept) { PARG parg; parg.p_string = wait_message(); ierror("%s", &parg); } ! sleep(1); slept = TRUE; ! if (follow_mode == FOLLOW_NAME) { ! /* ! * See whether the file's i-number has changed. * If so, force the file to be closed and ! * reopened. ! */ struct stat st; int r = stat(get_filename(curr_ifile), &st); if (r == 0 && (st.st_ino != curr_ino || ! st.st_dev != curr_dev)) { ! /* ! * screen_trashed=2 causes ! * make_display to reopen the file. ! */ screen_trashed = 2; return (EOI); } } } if (sigs) return (EOI); } ! found: ! if (ch_bufhead != bn) { /* * Move the buffer to the head of the buffer chain. * This orders the buffer chain, most- to least-recently used. *************** *** 365,396 **** } /* ! * ch_ungetchar is a rather kludgy and limited way to push * a single char onto an input file descriptor. */ ! public void ! ch_ungetchar(c) ! int c; { if (c != -1 && ch_ungotchar != -1) error("ch_ungetchar overrun", NULL_PARG); ch_ungotchar = c; } - #if LOGFILE /* * Close the logfile. * If we haven't read all of standard input into it, do that now. */ ! public void ! end_logfile() { static int tried = FALSE; if (logfile < 0) return; ! if (!tried && ch_fsize == NULL_POSITION) ! { tried = TRUE; ierror("Finishing logfile", NULL_PARG); while (ch_forw_get() != EOI) --- 336,364 ---- } /* ! * ch_ungetchar is a rather kludgy and limited way to push * a single char onto an input file descriptor. */ ! void ! ch_ungetchar(int c) { if (c != -1 && ch_ungotchar != -1) error("ch_ungetchar overrun", NULL_PARG); ch_ungotchar = c; } /* * Close the logfile. * If we haven't read all of standard input into it, do that now. */ ! void ! end_logfile(void) { static int tried = FALSE; if (logfile < 0) return; ! if (!tried && ch_fsize == -1) { tried = TRUE; ierror("Finishing logfile", NULL_PARG); while (ch_forw_get() != EOI) *************** *** 407,460 **** * Invoked from the - command; see toggle_option(). * Write all the existing buffered data to the log file. */ ! public void ! sync_logfile() { ! register struct buf *bp; ! register struct bufnode *bn; int warned = FALSE; BLOCKNUM block; BLOCKNUM nblocks; nblocks = (ch_fpos + LBUFSIZE - 1) / LBUFSIZE; ! for (block = 0; block < nblocks; block++) ! { int wrote = FALSE; ! FOR_BUFS(bn) ! { bp = bufnode_buf(bn); ! if (bp->block == block) ! { ! write(logfile, (char *) bp->data, bp->datasize); wrote = TRUE; break; } } ! if (!wrote && !warned) ! { ! error("Warning: log file is incomplete", ! NULL_PARG); warned = TRUE; } } } - #endif - /* * Determine if a specific block is currently in one of the buffers. */ ! static int ! buffered(block) ! BLOCKNUM block; { register struct buf *bp; register struct bufnode *bn; register int h; h = BUFHASH(block); ! FOR_BUFS_IN_CHAIN(h, bn) ! { bp = bufnode_buf(bn); if (bp->block == block) return (TRUE); --- 375,420 ---- * Invoked from the - command; see toggle_option(). * Write all the existing buffered data to the log file. */ ! void ! sync_logfile(void) { ! struct buf *bp; ! struct bufnode *bn; int warned = FALSE; BLOCKNUM block; BLOCKNUM nblocks; nblocks = (ch_fpos + LBUFSIZE - 1) / LBUFSIZE; ! for (block = 0; block < nblocks; block++) { int wrote = FALSE; ! FOR_BUFS(bn) { bp = bufnode_buf(bn); ! if (bp->block == block) { ! (void) write(logfile, (char *)bp->data, ! bp->datasize); wrote = TRUE; break; } } ! if (!wrote && !warned) { ! error("Warning: log file is incomplete", NULL_PARG); warned = TRUE; } } } /* * Determine if a specific block is currently in one of the buffers. */ ! static int ! buffered(BLOCKNUM block) { register struct buf *bp; register struct bufnode *bn; register int h; h = BUFHASH(block); ! FOR_BUFS_IN_CHAIN(h, bn) { bp = bufnode_buf(bn); if (bp->block == block) return (TRUE); *************** *** 466,492 **** * Seek to a specified position in the file. * Return 0 if successful, non-zero if can't seek there. */ ! public int ! ch_seek(pos) ! register POSITION pos; { BLOCKNUM new_block; ! POSITION len; if (thisfile == NULL) return (0); len = ch_length(); ! if (pos < ch_zero() || (len != NULL_POSITION && pos > len)) return (1); new_block = pos / LBUFSIZE; ! if (!(ch_flags & CH_CANSEEK) && pos != ch_fpos && !buffered(new_block)) ! { if (ch_fpos > pos) return (1); ! while (ch_fpos < pos) ! { if (ch_forw_get() == EOI) return (1); if (ABORT_SIGS()) --- 426,450 ---- * Seek to a specified position in the file. * Return 0 if successful, non-zero if can't seek there. */ ! int ! ch_seek(off_t pos) { BLOCKNUM new_block; ! off_t len; if (thisfile == NULL) return (0); len = ch_length(); ! if (pos < ch_zero() || (len != -1 && pos > len)) return (1); new_block = pos / LBUFSIZE; ! if (!(ch_flags & CH_CANSEEK) && pos != ch_fpos && ! !buffered(new_block)) { if (ch_fpos > pos) return (1); ! while (ch_fpos < pos) { if (ch_forw_get() == EOI) return (1); if (ABORT_SIGS()) *************** *** 505,514 **** /* * Seek to the end of the file. */ ! public int ! ch_end_seek() { ! POSITION len; if (thisfile == NULL) return (0); --- 463,472 ---- /* * Seek to the end of the file. */ ! int ! ch_end_seek(void) { ! off_t len; if (thisfile == NULL) return (0); *************** *** 517,523 **** ch_fsize = filesize(ch_file); len = ch_length(); ! if (len != NULL_POSITION) return (ch_seek(len)); /* --- 475,481 ---- ch_fsize = filesize(ch_file); len = ch_length(); ! if (len != -1) return (ch_seek(len)); /* *************** *** 534,544 **** * We may not be able to seek there if input is a pipe and the * beginning of the pipe is no longer buffered. */ ! public int ! ch_beg_seek() { ! register struct bufnode *bn; ! register struct bufnode *firstbn; /* * Try a plain ch_seek first. --- 492,502 ---- * We may not be able to seek there if input is a pipe and the * beginning of the pipe is no longer buffered. */ ! int ! ch_beg_seek(void) { ! struct bufnode *bn; ! struct bufnode *firstbn; /* * Try a plain ch_seek first. *************** *** 553,560 **** firstbn = ch_bufhead; if (firstbn == END_OF_CHAIN) return (1); ! FOR_BUFS(bn) ! { if (bufnode_buf(bn)->block < bufnode_buf(firstbn)->block) firstbn = bn; } --- 511,517 ---- firstbn = ch_bufhead; if (firstbn == END_OF_CHAIN) return (1); ! FOR_BUFS(bn) { if (bufnode_buf(bn)->block < bufnode_buf(firstbn)->block) firstbn = bn; } *************** *** 566,578 **** /* * Return the length of the file, if known. */ ! public POSITION ! ch_length() { if (thisfile == NULL) ! return (NULL_POSITION); if (ignore_eoi) ! return (NULL_POSITION); if (ch_flags & CH_NODATA) return (0); return (ch_fsize); --- 523,535 ---- /* * Return the length of the file, if known. */ ! off_t ! ch_length(void) { if (thisfile == NULL) ! return (-1); if (ignore_eoi) ! return (-1); if (ch_flags & CH_NODATA) return (0); return (ch_fsize); *************** *** 581,611 **** /* * Return the current position in the file. */ ! public POSITION ! ch_tell() { if (thisfile == NULL) ! return (NULL_POSITION); ! return (ch_block * LBUFSIZE) + ch_offset; } /* * Get the current char and post-increment the read pointer. */ ! public int ! ch_forw_get() { ! register int c; if (thisfile == NULL) return (EOI); c = ch_get(); if (c == EOI) return (EOI); ! if (ch_offset < LBUFSIZE-1) ch_offset++; ! else ! { ch_block ++; ch_offset = 0; } --- 538,567 ---- /* * Return the current position in the file. */ ! off_t ! ch_tell(void) { if (thisfile == NULL) ! return (-1); ! return ((ch_block * LBUFSIZE) + ch_offset); } /* * Get the current char and post-increment the read pointer. */ ! int ! ch_forw_get(void) { ! int c; if (thisfile == NULL) return (EOI); c = ch_get(); if (c == EOI) return (EOI); ! if (ch_offset < LBUFSIZE-1) { ch_offset++; ! } else { ch_block ++; ch_offset = 0; } *************** *** 615,629 **** /* * Pre-decrement the read pointer and get the new current char. */ ! public int ! ch_back_get() { if (thisfile == NULL) return (EOI); ! if (ch_offset > 0) ch_offset --; ! else ! { if (ch_block <= 0) return (EOI); if (!(ch_flags & CH_CANSEEK) && !buffered(ch_block-1)) --- 571,584 ---- /* * Pre-decrement the read pointer and get the new current char. */ ! int ! ch_back_get(void) { if (thisfile == NULL) return (EOI); ! if (ch_offset > 0) { ch_offset --; ! } else { if (ch_block <= 0) return (EOI); if (!(ch_flags & CH_CANSEEK) && !buffered(ch_block-1)) *************** *** 638,651 **** * Set max amount of buffer space. * bufspace is in units of 1024 bytes. -1 mean no limit. */ ! public void ! ch_setbufspace(bufspace) ! int bufspace; { ! if (bufspace < 0) maxbufs = -1; ! else ! { maxbufs = ((bufspace * 1024) + LBUFSIZE-1) / LBUFSIZE; if (maxbufs < 1) maxbufs = 1; --- 593,604 ---- * Set max amount of buffer space. * bufspace is in units of 1024 bytes. -1 mean no limit. */ ! void ! ch_setbufspace(int bufspace) { ! if (bufspace < 0) { maxbufs = -1; ! } else { maxbufs = ((bufspace * 1024) + LBUFSIZE-1) / LBUFSIZE; if (maxbufs < 1) maxbufs = 1; *************** *** 655,683 **** /* * Flush (discard) any saved file state, including buffer contents. */ ! public void ! ch_flush() { ! register struct bufnode *bn; if (thisfile == NULL) return; ! if (!(ch_flags & CH_CANSEEK)) ! { /* * If input is a pipe, we don't flush buffer contents, * since the contents can't be recovered. */ ! ch_fsize = NULL_POSITION; return; } /* * Initialize all the buffers. */ ! FOR_BUFS(bn) ! { bufnode_buf(bn)->block = -1; } --- 608,634 ---- /* * Flush (discard) any saved file state, including buffer contents. */ ! void ! ch_flush(void) { ! struct bufnode *bn; if (thisfile == NULL) return; ! if (!(ch_flags & CH_CANSEEK)) { /* * If input is a pipe, we don't flush buffer contents, * since the contents can't be recovered. */ ! ch_fsize = -1; return; } /* * Initialize all the buffers. */ ! FOR_BUFS(bn) { bufnode_buf(bn)->block = -1; } *************** *** 696,714 **** #if 1 /* * This is a kludge to workaround a Linux kernel bug: files in ! * /proc have a size of 0 according to fstat() but have readable * data. They are sometimes, but not always, seekable. * Force them to be non-seekable here. */ ! if (ch_fsize == 0) ! { ! ch_fsize = NULL_POSITION; ch_flags &= ~CH_CANSEEK; } #endif ! if (lseek(ch_file, (off_t)0, SEEK_SET) == BAD_LSEEK) ! { /* * Warning only; even if the seek fails for some reason, * there's a good chance we're at the beginning anyway. --- 647,663 ---- #if 1 /* * This is a kludge to workaround a Linux kernel bug: files in ! * /proc have a size of 0 according to fstat() but have readable * data. They are sometimes, but not always, seekable. * Force them to be non-seekable here. */ ! if (ch_fsize == 0) { ! ch_fsize = -1; ch_flags &= ~CH_CANSEEK; } #endif ! if (lseek(ch_file, (off_t)0, SEEK_SET) == BAD_LSEEK) { /* * Warning only; even if the seek fails for some reason, * there's a good chance we're at the beginning anyway. *************** *** 722,738 **** * Allocate a new buffer. * The buffer is added to the tail of the buffer chain. */ ! static int ! ch_addbuf() { ! register struct buf *bp; ! register struct bufnode *bn; /* ! * Allocate and initialize a new buffer and link it * onto the tail of the buffer list. */ ! bp = (struct buf *) calloc(1, sizeof(struct buf)); if (bp == NULL) return (1); ch_nbufs++; --- 671,687 ---- * Allocate a new buffer. * The buffer is added to the tail of the buffer chain. */ ! static int ! ch_addbuf(void) { ! struct buf *bp; ! struct bufnode *bn; /* ! * Allocate and initialize a new buffer and link it * onto the tail of the buffer list. */ ! bp = calloc(1, sizeof (struct buf)); if (bp == NULL) return (1); ch_nbufs++; *************** *** 747,759 **** /* * */ ! static void ! init_hashtbl() { ! register int h; ! for (h = 0; h < BUFHASH_SIZE; h++) ! { thisfile->hashtbl[h].hnext = END_OF_HCHAIN(h); thisfile->hashtbl[h].hprev = END_OF_HCHAIN(h); } --- 696,707 ---- /* * */ ! static void ! init_hashtbl(void) { ! int h; ! for (h = 0; h < BUFHASH_SIZE; h++) { thisfile->hashtbl[h].hnext = END_OF_HCHAIN(h); thisfile->hashtbl[h].hprev = END_OF_HCHAIN(h); } *************** *** 762,774 **** /* * Delete all buffers for this file. */ ! static void ! ch_delbufs() { ! register struct bufnode *bn; ! while (ch_bufhead != END_OF_CHAIN) ! { bn = ch_bufhead; BUF_RM(bn); free(bufnode_buf(bn)); --- 710,721 ---- /* * Delete all buffers for this file. */ ! static void ! ch_delbufs(void) { ! struct bufnode *bn; ! while (ch_bufhead != END_OF_CHAIN) { bn = ch_bufhead; BUF_RM(bn); free(bufnode_buf(bn)); *************** *** 780,800 **** /* * Is it possible to seek on a file descriptor? */ ! public int ! seekable(f) ! int f; { - #if MSDOS_COMPILER - extern int fd0; - if (f == fd0 && !isatty(fd0)) - { - /* - * In MS-DOS, pipes are seekable. Check for - * standard input, and pretend it is not seekable. - */ - return (0); - } - #endif return (lseek(f, (off_t)1, SEEK_SET) != BAD_LSEEK); } --- 727,735 ---- /* * Is it possible to seek on a file descriptor? */ ! int ! seekable(int f) { return (lseek(f, (off_t)1, SEEK_SET) != BAD_LSEEK); } *************** *** 802,809 **** * Force EOF to be at the current read position. * This is used after an ignore_eof read, during which the EOF may change. */ ! public void ! ch_set_eof() { ch_fsize = ch_fpos; } --- 737,744 ---- * Force EOF to be at the current read position. * This is used after an ignore_eof read, during which the EOF may change. */ ! void ! ch_set_eof(void) { ch_fsize = ch_fpos; } *************** *** 812,833 **** /* * Initialize file state for a new file. */ ! public void ! ch_init(f, flags) ! int f; ! int flags; { /* * See if we already have a filestate for this file. */ ! thisfile = (struct filestate *) get_filestate(curr_ifile); ! if (thisfile == NULL) ! { /* * Allocate and initialize a new filestate. */ ! thisfile = (struct filestate *) ! calloc(1, sizeof(struct filestate)); thisfile->buflist.next = thisfile->buflist.prev = END_OF_CHAIN; thisfile->nbufs = 0; thisfile->flags = 0; --- 747,764 ---- /* * Initialize file state for a new file. */ ! void ! ch_init(int f, int flags) { /* * See if we already have a filestate for this file. */ ! thisfile = get_filestate(curr_ifile); ! if (thisfile == NULL) { /* * Allocate and initialize a new filestate. */ ! thisfile = calloc(1, sizeof (struct filestate)); thisfile->buflist.next = thisfile->buflist.prev = END_OF_CHAIN; thisfile->nbufs = 0; thisfile->flags = 0; *************** *** 835,841 **** thisfile->block = 0; thisfile->offset = 0; thisfile->file = -1; ! thisfile->fsize = NULL_POSITION; ch_flags = flags; init_hashtbl(); /* --- 766,772 ---- thisfile->block = 0; thisfile->offset = 0; thisfile->file = -1; ! thisfile->fsize = -1; ch_flags = flags; init_hashtbl(); /* *************** *** 853,876 **** /* * Close a filestate. */ ! public void ! ch_close() { int keepstate = FALSE; if (thisfile == NULL) return; ! if (ch_flags & (CH_CANSEEK|CH_POPENED|CH_HELPFILE)) ! { /* * We can seek or re-open, so we don't need to keep buffers. */ ch_delbufs(); ! } else keepstate = TRUE; ! if (!(ch_flags & CH_KEEPOPEN)) ! { /* * We don't need to keep the file descriptor open * (because we can re-open it.) --- 784,806 ---- /* * Close a filestate. */ ! void ! ch_close(void) { int keepstate = FALSE; if (thisfile == NULL) return; ! if (ch_flags & (CH_CANSEEK|CH_POPENED|CH_HELPFILE)) { /* * We can seek or re-open, so we don't need to keep buffers. */ ch_delbufs(); ! } else { keepstate = TRUE; ! } ! if (!(ch_flags & CH_KEEPOPEN)) { /* * We don't need to keep the file descriptor open * (because we can re-open it.) *************** *** 880,937 **** if (!(ch_flags & CH_POPENED)) close(ch_file); ch_file = -1; ! } else keepstate = TRUE; ! if (!keepstate) ! { /* * We don't even need to keep the filestate structure. */ free(thisfile); thisfile = NULL; ! set_filestate(curr_ifile, (void *) NULL); } } /* * Return ch_flags for the current file. */ ! public int ! ch_getflags() { if (thisfile == NULL) return (0); return (ch_flags); } - - #if 0 - public void - ch_dump(struct filestate *fs) - { - struct buf *bp; - struct bufnode *bn; - unsigned char *s; - - if (fs == NULL) - { - printf(" --no filestate\n"); - return; - } - printf(" file %d, flags %x, fpos %x, fsize %x, blk/off %x/%x\n", - fs->file, fs->flags, fs->fpos, - fs->fsize, fs->block, fs->offset); - printf(" %d bufs:\n", fs->nbufs); - for (bn = fs->next; bn != &fs->buflist; bn = bn->next) - { - bp = bufnode_buf(bn); - printf("%x: blk %x, size %x \"", - bp, bp->block, bp->datasize); - for (s = bp->data; s < bp->data + 30; s++) - if (*s >= ' ' && *s < 0x7F) - printf("%c", *s); - else - printf("."); - printf("\"\n"); - } - } - #endif --- 810,835 ---- if (!(ch_flags & CH_POPENED)) close(ch_file); ch_file = -1; ! } else { keepstate = TRUE; ! } ! if (!keepstate) { /* * We don't even need to keep the filestate structure. */ free(thisfile); thisfile = NULL; ! set_filestate(curr_ifile, NULL); } } /* * Return ch_flags for the current file. */ ! int ! ch_getflags(void) { if (thisfile == NULL) return (0); return (ch_flags); }