Exemplo n.º 1
0
int __cdecl _flush (
        FILE *str
        )
{
        REG1 FILE *stream;
        REG2 int rc = 0; /* assume good return */
        REG3 int nchar;

        /* Init pointer to stream */
        stream = str;

        if ((stream->_flag & (_IOREAD | _IOWRT)) == _IOWRT && bigbuf(stream)
                && (nchar = stream->_ptr - stream->_base) > 0)
        {
                if ( _write(_fileno(stream), stream->_base, nchar) == nchar ) {
                        /* if this is a read/write file, clear _IOWRT so that
                         * next operation can be a read
                         */
                        if ( _IORW & stream->_flag )
                                stream->_flag &= ~_IOWRT;
                }
                else {
                        stream->_flag |= _IOERR;
                        rc = EOF;
                }
        }

        stream->_ptr = stream->_base;
        stream->_cnt = 0;

        return(rc);
}
Exemplo n.º 2
0
Arquivo: stdio.c Projeto: HarryR/sanos
int fflush(FILE *stream) {
  int rc = 0;
  int count;
  int written;

  if (!stream) stream = stdout;
  if ((stream->flag & (_IORD | _IOWR)) == _IOWR && 
      bigbuf(stream) && 
      (count = stream->ptr - stream->base) > 0) {
    if (stream->flag & _IOCRLF) {
      written = write_translated(fileno(stream), stream->base, count);
    } else {
      written = write(fileno(stream), stream->base, count);
    }

    if (written == count)  {
      // If this is a read/write file, clear _IOWR so that next operation can be a read
      if (stream->flag & _IORW) stream->flag &= ~_IOWR;
    } else {
      stream->flag |= _IOERR;
      rc = EOF;
    }
  }

  stream->ptr = stream->base;
  stream->cnt = 0;

  return rc;
}
Exemplo n.º 3
0
Arquivo: stdio.c Projeto: HarryR/sanos
long ftell(FILE *stream) {
  long filepos;

  if (stream->cnt < 0) stream->cnt = 0;    
  if ((filepos = tell(fileno(stream))) < 0L) return -1;
  if (!bigbuf(stream)) return filepos - stream->cnt;

  if (stream->flag & _IORD) {
    filepos -= stream->cnt;
  } else if (stream->flag & _IOWR) {
    filepos += (stream->ptr - stream->base);
  }

  return filepos;
}
Exemplo n.º 4
0
Arquivo: stdio.c Projeto: HarryR/sanos
size_t fwrite(const void *buffer, size_t size, size_t num, FILE *stream) {
  const char *data;               // Point to where data comes from next
  unsigned total;                 // Total bytes to write
  unsigned count;                 // Num bytes left to write
  unsigned bufsize;               // Size of stream buffer
  unsigned nbytes;                // Number of bytes to write now
  unsigned nwritten;              // Number of bytes written
  int c;                          // A temp char

  // Initialize local vars
  data = buffer;
  count = total = size * num;
  if (count == 0) return 0;

  if (anybuf(stream)) {
    // Already has buffer, use its size
    bufsize = stream->bufsiz;
  } else {
    // Assume will get BUFSIZ buffer
    bufsize = BUFSIZ;
  }

  // Here is the main loop -- we go through here until we're done
  while (count != 0) {
    // If the buffer is big and has room, copy data to buffer
    if (bigbuf(stream) && stream->cnt != 0) {
      // How much do we want?
      nbytes = (count < (unsigned) stream->cnt) ? count : stream->cnt;
      memcpy(stream->ptr, data, nbytes);

      // Update stream and amount of data written
      count -= nbytes;
      stream->cnt -= nbytes;
      stream->ptr += nbytes;
      data += nbytes;
    } else if (count >= bufsize) {
      // If we have more than bufsize chars to write, write
      // data by calling write with an integral number of
      // bufsiz blocks.  If we reach here and we have a big
      // buffer, it must be full so flush it.

      if (bigbuf(stream)) {
        if (fflush(stream)) {
          // Error, stream flags set -- we're out of here
          return (total - count) / size;
        }
      }

      // Calc chars to write -- (count / bufsize) * bufsize
      nbytes = bufsize ? (count - count % bufsize) : count;

      if (stream->flag & _IOCRLF) {
        nwritten = write_translated(fileno(stream), (char *) data, nbytes);
      } else {
        nwritten = write(fileno(stream), data, nbytes);
      }

      if ((int) nwritten < 0) {
        // Error -- out of here
        stream->flag |= _IOERR;
        return (total - count) / size;
      }

      // Update count and data to reflect write
      count -= nwritten;
      data += nwritten;

      if (nwritten < nbytes) {
        // Error -- out of here
        stream->flag |= _IOERR;
        return (total - count) / size;
      }
    } else {
      // Buffer full and not enough chars to do direct write, so do a flsbuf.
      c = *data;  
      if (flsbuf(c, stream) == EOF) {
        // Error or eof, stream flags set by _flsbuf
        return (total - count) / size;
      }

      // flsbuf wrote a char -- update count
      ++data;
      --count;

      // Update buffer size
      bufsize = stream->bufsiz > 0 ? stream->bufsiz : 1;
    }
  }

  // We finished successfully, so just return num
  return num;
}
Exemplo n.º 5
0
Arquivo: stdio.c Projeto: HarryR/sanos
int flsbuf(int ch, FILE *stream) {
  int count;
  int written;
  int fh;
  char chbuf;

  fh = fileno(stream);

  if (!(stream->flag & (_IOWR | _IORW)) || (stream->flag & _IOSTR)) {
    stream->flag |= _IOERR;
    return -1;
  }

  if (stream->flag & _IORD) {
    stream->cnt = 0;
    if (stream->flag & _IOEOF) {
      stream->ptr = stream->base;
      stream->flag &= ~_IORD;
    } else {
      stream->flag |= _IOERR;
      return -1;
    }
  }

  stream->flag |= _IOWR;
  stream->flag &= ~_IOEOF;
  written = count = stream->cnt = 0;

  // Get a buffer for this stream, if necessary
  if (!anybuf(stream)) getbuf(stream);

  // If big buffer is assigned to stream
  if (bigbuf(stream)) {
    count = stream->ptr - stream->base;
    stream->ptr = stream->base + 1;
    stream->cnt = stream->bufsiz - 1;

    if (count > 0) {
      if (stream->flag & _IOCRLF) {
        written = write_translated(fh, stream->base, count);
      } else {
        written = write(fh, stream->base, count);
      }
    }

    *stream->base = (char) ch;
  } else {
    // Perform single character output (either _IONBF or no buffering)
    count = 1;
    chbuf = (char) ch;
    if (stream->flag & _IOCRLF) {
      written = write_translated(fh, &chbuf, count);
    } else {
      written = write(fh, &chbuf, count);
    }
  }

  // See if the write was successful.
  if (written != count) {
    stream->flag |= _IOERR;
    return -1;
  }

  return ch & 0xff;
}
Exemplo n.º 6
0
int __cdecl _flswbuf (
        int ch,
        FILE *str
        )

#endif  /* _UNICODE */

{

        REG1 FILE *stream;
        REG2 int charcount;
        REG3 int written;
        int fh;

        _ASSERTE(str != NULL);

        /* Init file handle and pointers */
        stream = str;
        fh = _fileno(stream);

        if (!(stream->_flag & (_IOWRT|_IORW))) {
                errno = EBADF;
                stream->_flag |= _IOERR;
                return(_TEOF);
        } else if ((stream->_flag & _IOSTRG)) {
                errno = ERANGE;
                stream->_flag |= _IOERR;
                return(_TEOF);
        }

        /* Check that _IOREAD is not set or, if it is, then so is _IOEOF. Note
           that _IOREAD and IOEOF both being set implies switching from read to
           write at end-of-file, which is allowed by ANSI. Note that resetting
           the _cnt and _ptr fields amounts to doing an fflush() on the stream
           in this case. Note also that the _cnt field has to be reset to 0 for
           the error path as well (i.e., _IOREAD set but _IOEOF not set) as
           well as the non-error path. */

        if (stream->_flag & _IOREAD) {
                stream->_cnt = 0;
                if (stream->_flag & _IOEOF) {
                        stream->_ptr = stream->_base;
                        stream->_flag &= ~_IOREAD;
                }
                else {
                        stream->_flag |= _IOERR;
                        return(_TEOF);
                }
        }

        stream->_flag |= _IOWRT;
        stream->_flag &= ~_IOEOF;
        written = charcount = stream->_cnt = 0;

        /* Get a buffer for this stream, if necessary. */
        if (!anybuf(stream)) {

                /* Do NOT get a buffer if (1) stream is stdout/stderr, and
                   (2) stream is NOT a tty.
                   [If stdout/stderr is a tty, we do NOT set up single char
                   buffering. This is so that later temporary buffering will
                   not be thwarted by the _IONBF bit being set (see
                   _stbuf/_ftbuf usage).]
                */
                if (!( ((stream==stdout) || (stream==stderr))
                && (_isatty(fh)) ))

                        _getbuf(stream);

        } /* end !anybuf() */

        /* If big buffer is assigned to stream... */
        if (bigbuf(stream)) {

                _ASSERTE(("inconsistent IOB fields", stream->_ptr - stream->_base >= 0));

                charcount = (int)(stream->_ptr - stream->_base);
                stream->_ptr = stream->_base + sizeof(TCHAR);
                stream->_cnt = stream->_bufsiz - (int)sizeof(TCHAR);

                if (charcount > 0)
                        written = _write(fh, stream->_base, charcount);
                else
                        if (_osfile_safe(fh) & FAPPEND)
                                                {
                                                        if( _lseeki64(fh,0L,SEEK_END)==-1)
                                                        {
                                                                stream->_flag |= _IOERR;
                                                                return(_TEOF);
                                                        }
                                                }

#ifndef _UNICODE
                *stream->_base = (char)ch;
#else  /* _UNICODE */
                *(wchar_t *)(stream->_base) = (wchar_t)(ch & 0xffff);
#endif  /* _UNICODE */
        }

    /* Perform single character output (either _IONBF or no buffering) */
        else {
                charcount = sizeof(TCHAR);
#ifndef _UNICODE
                written = _write(fh, &ch, charcount);
#else  /* _UNICODE */
                {
                        char mbc[4];

                        *(wchar_t *)mbc = (wchar_t)(ch & 0xffff);
                        written = _write(fh, mbc, charcount);
                }
#endif  /* _UNICODE */
        }

        /* See if the _write() was successful. */
        if (written != charcount) {
                stream->_flag |= _IOERR;
                return(_TEOF);
        }

#ifndef _UNICODE
        return(ch & 0xff);
#else  /* _UNICODE */
        return(ch & 0xffff);
#endif  /* _UNICODE */

}
Exemplo n.º 7
0
int __cdecl _fflush_lk (
        REG1 FILE *str
        )
{

#else  /* _MT */

int __cdecl fflush (
        REG1 FILE *str
        )
{

        /* if stream is NULL, flush all streams */
        if ( str == NULL ) {
                return(flsall(FFLUSHNULL));
        }

#endif  /* _MT */

        if (_flush(str) != 0) {
                /* _flush failed, don't attempt to commit */
                return(EOF);
        }

        /* lowio commit to ensure data is written to disk */
        if (str->_flag & _IOCOMMIT) {
                return (_commit(_fileno(str)) ? EOF : 0);
        }
        return 0;
}


/***
*int _flush(stream) - flush the buffer on a single stream
*
*Purpose:
*       If file open for writing and buffered, flush the buffer.  If
*       problems flushing the buffer, set the stream flag to error.
*       Multi-thread version assumes stream lock is held by caller.
*
*Entry:
*       FILE* stream - stream to flush
*
*Exit:
*       Returns 0 if flushed successfully, or if no buffer to flush.,
*       Returns EOF and sets file error flag if fails.
*       File struct entries affected: _ptr, _cnt, _flag.
*
*Exceptions:
*
*******************************************************************************/

int __cdecl _flush (
        FILE *str
        )
{
        REG1 FILE *stream;
        REG2 int rc = 0; /* assume good return */
        REG3 int nchar;

        /* Init pointer to stream */
        stream = str;


        if ((stream->_flag & (_IOREAD | _IOWRT)) == _IOWRT && bigbuf(stream)
                && (nchar = stream->_ptr - stream->_base) > 0)
        {
                if ( _write(_fileno(stream), stream->_base, nchar) == nchar ) {
                        /* if this is a read/write file, clear _IOWRT so that
                         * next operation can be a read
                         */
                        if ( _IORW & stream->_flag )
                                stream->_flag &= ~_IOWRT;
                }
                else {
                        stream->_flag |= _IOERR;
                        rc = EOF;
                }
        }

        stream->_ptr = stream->_base;
        stream->_cnt = 0;

        return(rc);
}
Exemplo n.º 8
0
/* define the normal version */
#ifdef _MT
size_t __cdecl _fwrite_lk (
#else  /* _MT */
size_t __cdecl fwrite (
#endif  /* _MT */
        const void *buffer,
        size_t size,
        size_t num,
        FILE *stream
        )
{
        const char *data;               /* point to where data comes from next */
        unsigned total;                 /* total bytes to write */
        unsigned count;                 /* num bytes left to write */
        unsigned bufsize;               /* size of stream buffer */
        unsigned nbytes;                /* number of bytes to write now */
        unsigned nwritten;              /* number of bytes written */
        int c;                          /* a temp char */

        /* initialize local vars */
        data = buffer;
        count = total = size * num;
        if (0 == count)
            return 0;

        if (anybuf(stream))
                /* already has buffer, use its size */
                bufsize = stream->_bufsiz;
        else
#if defined (_M_M68K) || defined (_M_MPPC)
                /* assume will get BUFSIZ buffer */
                bufsize = BUFSIZ;
#else  /* defined (_M_M68K) || defined (_M_MPPC) */
                /* assume will get _INTERNAL_BUFSIZ buffer */
                bufsize = _INTERNAL_BUFSIZ;
#endif  /* defined (_M_M68K) || defined (_M_MPPC) */

        /* here is the main loop -- we go through here until we're done */
        while (count != 0) {
                /* if the buffer is big and has room, copy data to buffer */
                if (bigbuf(stream) && stream->_cnt != 0) {
                        /* how much do we want? */
                        nbytes = (count < (unsigned)stream->_cnt) ? count : stream->_cnt;
                        memcpy(stream->_ptr, data, nbytes);

                        /* update stream and amt of data written */
                        count -= nbytes;
                        stream->_cnt -= nbytes;
                        stream->_ptr += nbytes;
                        data += nbytes;
                }
                else if (count >= bufsize) {
                        /* If we have more than bufsize chars to write, write
                           data by calling write with an integral number of
                           bufsiz blocks.  If we reach here and we have a big
                           buffer, it must be full so _flush it. */

                        if (bigbuf(stream)) {
                                if (_flush(stream)) {
                                        /* error, stream flags set -- we're out
                                           of here */
                                        return (total - count) / size;
                                }
                        }

                        /* calc chars to read -- (count/bufsize) * bufsize */
                        nbytes = ( bufsize ? (count - count % bufsize) :
                                   count );

                        nwritten = _write(_fileno(stream), data, nbytes);
                        if (nwritten == (unsigned)EOF) {
                                /* error -- out of here */
                                stream->_flag |= _IOERR;
                                return (total - count) / size;
                        }

                        /* update count and data to reflect write */

                        count -= nwritten;
                        data += nwritten;

                        if (nwritten < nbytes) {
                                /* error -- out of here */
                                stream->_flag |= _IOERR;
                                return (total - count) / size;
                        }
                }
                else {
                        /* buffer full and not enough chars to do direct write,
                           so do a _flsbuf. */
                        c = *data;  /* _flsbuf write one char, this is it */
                        if (_flsbuf(c, stream) == EOF) {
                                /* error or eof, stream flags set by _flsbuf */
                                return (total - count) / size;
                        }

                        /* _flsbuf wrote a char -- update count */
                        ++data;
                        --count;

                        /* update buffer size */
                        bufsize = stream->_bufsiz > 0 ? stream->_bufsiz : 1;
                }
        }

        /* we finished successfully, so just return num */
        return num;
}
Exemplo n.º 9
0
long __cdecl _ftell_nolock(


    FILE* str
) {
    REG1 FILE* stream;
    unsigned int offset;
    long filepos;
    REG2 char* p;
    char* max;
    int fd;
    unsigned int rdcnt;
    _VALIDATE_RETURN((str != NULL), EINVAL, (-1L));
    /* Init stream pointer and file descriptor */
    stream = str;
    fd = _fileno(stream);

    if (stream->_cnt < 0) {
        stream->_cnt = 0;
    }

    if ((filepos = _lseek(fd, 0L, SEEK_CUR)) < 0L) {
        return (-1L);
    }

    if (!bigbuf(stream)) {          /* _IONBF or no buffering designated */
        return (filepos - stream->_cnt);
    }

    offset = (unsigned)(stream->_ptr - stream->_base);

    if (stream->_flag & (_IOWRT | _IOREAD)) {
        if (_osfile(fd) & FTEXT)
            for (p = stream->_base; p < stream->_ptr; p++)
                if (*p == '\n') { /* adjust for '\r' */
                    offset++;
                }
    } else if (!(stream->_flag & _IORW)) {
        errno = EINVAL;
        return (-1L);
    }

    if (filepos == 0L) {
        return ((long)offset);
    }

    if (stream->_flag & _IOREAD)    /* go to preceding sector */
        if (stream->_cnt == 0) { /* filepos holds correct location */
            offset = 0;
        } else {
            /* Subtract out the number of unread bytes left in the buffer.
               [We can't simply use _iob[]._bufsiz because the last read
               may have hit EOF and, thus, the buffer was not completely
               filled.] */
            rdcnt = stream->_cnt + (unsigned)(stream->_ptr - stream->_base);

            /* If text mode, adjust for the cr/lf substitution. If binary
               mode, we're outta here. */
            if (_osfile(fd) & FTEXT) {
                /* (1) If we're not at eof, simply copy _bufsiz onto rdcnt
                   to get the # of untranslated chars read. (2) If we're at
                   eof, we must look through the buffer expanding the '\n'
                   chars one at a time. */

                /* [NOTE: Performance issue -- it is faster to do the two
                   _lseek() calls than to blindly go through and expand the
                   '\n' chars regardless of whether we're at eof or not.] */
                if (_lseek(fd, 0L, SEEK_END) == filepos) {
                    max = stream->_base + rdcnt;

                    for (p = stream->_base; p < max; p++)
                        if (*p == '\n')
                            /* adjust for '\r' */
                        {
                            rdcnt++;
                        }

                    /* If last byte was ^Z, the lowio read didn't tell us
                       about it. Check flag and bump count, if necessary. */

                    if (stream->_flag & _IOCTRLZ) {
                        ++rdcnt;
                    }
                } else {
                    if (_lseek(fd, filepos, SEEK_SET) < 0) {
                        return (-1);
                    }

                    /* We want to set rdcnt to the number of bytes
                       originally read into the stream buffer (before
                       crlf->lf translation). In most cases, this will
                       just be _bufsiz. However, the buffer size may have
                       been changed, due to fseek optimization, at the
                       END of the last _filbuf call. */

                    if ((rdcnt <= _SMALL_BUFSIZ) &&
                            (stream->_flag & _IOMYBUF) &&
                            !(stream->_flag & _IOSETVBUF)) {
                        /* The translated contents of the buffer is small
                           and we are not at eof. The buffer size must have
                           been set to _SMALL_BUFSIZ during the last
                           _filbuf call. */
                        rdcnt = _SMALL_BUFSIZ;
                    } else {
                        rdcnt = stream->_bufsiz;
                    }

                    /* If first byte in untranslated buffer was a '\n',
                       assume it was preceeded by a '\r' which was
                       discarded by the previous read operation and count
                       the '\n'. */
                    if (_osfile(fd) & FCRLF) {
                        ++rdcnt;
                    }
                }
            } /* end if FTEXT */

            filepos -= (long)rdcnt;
        } /* end else stream->_cnt != 0 */

    return (filepos + (long)offset);
}