_CODE_ACCESS int fgetc(register FILE *_fp) { int retval = EOF; /*------------------------------------------------------------------------*/ /* The current thread in a multi-threaded application must protect access */ /* to __TI_LOCK_FILE_TBL shared resources (_ftable[], _ft_end, and */ /* _tmpnams[]). In this case, _ftable[] may be updated, so we must ensure */ /* that the local copy of _ftable[] is flushed to shared memory before */ /* leaving the critical section (invalidated if it is not modified). */ /*------------------------------------------------------------------------*/ __TI_resource_lock(__TI_LOCK_FILE_TBL); /*------------------------------------------------------------------------*/ /* Make sure that it is OK to read from this stream. */ /*------------------------------------------------------------------------*/ if (!_rd_ok(_fp)) goto fgetc_exit; /*------------------------------------------------------------------------*/ /* For non-buffered streams, call the lowlevel READ function. */ /*------------------------------------------------------------------------*/ if (_BUFFMODE(_fp) == _IONBF) { int errchk; char result; if (_STCHK(_fp, _UNGETC)) { _UNSET(_fp, _UNGETC); retval = (int)*(_fp->pos++); goto fgetc_exit; } errchk = read(_fp->fd, &result, 1); if (errchk <= 0) { _SET(_fp, (errchk == 0) ? _STATEOF : _STATERR); goto fgetc_exit; } retval = (int)result; goto fgetc_exit; } /*------------------------------------------------------------------------*/ /* If the buffer has been entirely read, or is empty, call _BUFF_READ to */ /* fill the buffer. */ /*------------------------------------------------------------------------*/ if (_fp->pos == _fp->buff_stop) _buff_read(_fp); /*------------------------------------------------------------------------*/ /* If the buffer read was unsuccessful, return an EOF. Otherwise, clear */ /* the _UNGETC flag in the stream, and return the next character. */ /*------------------------------------------------------------------------*/ if (_STCHK(_fp, (_STATERR | _STATEOF))) goto fgetc_exit; _UNSET(_fp, _UNGETC); retval = *(_fp->pos++); fgetc_exit: __TI_data_synch_WBINV(&_ftable, sizeof(_ftable)); __TI_resource_unlock(__TI_LOCK_FILE_TBL); return (retval); }
_CODE_ACCESS size_t fread(void *_ptr, size_t _size, size_t _count, FILE *_fp) { /*------------------------------------------------------------------------*/ /* Local variables */ /*------------------------------------------------------------------------*/ unsigned char *fpos = (unsigned char *)_ptr; size_t num_left = _size * _count, num_read = 0, num_to_read = 0; /*------------------------------------------------------------------------*/ /* The current thread in a multi-threaded application must protect access */ /* to __TI_LOCK_FILE_TBL shared resources (_ftable[], _ft_end, and */ /* _tmpnams[]). In this case, _ftable[] may be updated, so we must ensure */ /* that the local copy of _ftable[] is flushed to shared memory before */ /* leaving the critical section (invalidated if it is not modified). */ /*------------------------------------------------------------------------*/ __TI_resource_lock(__TI_LOCK_FILE_TBL); /*------------------------------------------------------------------------*/ /* Make sure that the file is readable. */ /*------------------------------------------------------------------------*/ if (!_rd_ok(_fp) || _size == 0 || _count == 0) { __TI_data_synch_INV(&_ftable, sizeof(_ftable)); __TI_resource_unlock(__TI_LOCK_FILE_TBL); return (0); } /*------------------------------------------------------------------------*/ /* If the stream is non-buffered, call the lowlevel READ function. */ /*------------------------------------------------------------------------*/ if (_BUFFMODE(_fp) == _IONBF) { int num_read = 0; while (num_left > 0) { int read_return; if (_STCHK(_fp, _UNGETC)) { *fpos = *(_fp->pos++); _UNSET(_fp, _UNGETC); read_return = 1; } else read_return = (size_t)(read(_fp->fd, (char *)fpos + num_read, num_left)); if (read_return < 0) { _SET(_fp, _STATERR); break; } else if (read_return == 0) { _SET(_fp, _STATEOF); break; } else { num_read += read_return; num_left -= read_return; } } __TI_data_synch_WBINV(&_ftable, sizeof(_ftable)); __TI_resource_unlock(__TI_LOCK_FILE_TBL); return (num_read / _size); } while (num_left > 0) { /*---------------------------------------------------------------------*/ /* If the buffer has been completely read, fill it up. Exit the loop */ /* if an I/O error occurs, or the end of the file is reached. */ /*---------------------------------------------------------------------*/ if(_fp->pos == _fp->buff_stop) _buff_read(_fp); if(_STCHK(_fp, (_STATERR | _STATEOF))) break; /*---------------------------------------------------------------------*/ /* Determine how many characters can fit in the buffer, and read them */ /* in. */ /*---------------------------------------------------------------------*/ num_to_read = (num_left < (_fp->buff_stop - _fp->pos)) ? num_left : (_fp->buff_stop - _fp->pos); memcpy(fpos, _fp->pos, num_to_read); /*---------------------------------------------------------------------*/ /* Update pointers and counters. */ /*---------------------------------------------------------------------*/ fpos += num_to_read; _fp->pos += num_to_read; num_read += num_to_read; num_left -= num_to_read; } /*------------------------------------------------------------------------*/ /* Clear the _UNGETC flag in the stream, and return the number of blocks */ /* read. */ /*------------------------------------------------------------------------*/ _UNSET(_fp, _UNGETC); __TI_data_synch_WBINV(&_ftable, sizeof(_ftable)); __TI_resource_unlock(__TI_LOCK_FILE_TBL); return (num_read / _size); }