Esempio n. 1
0
_CODE_ACCESS int fseek(register FILE *_fp, long _offset, int _ptrname)
{
   /*------------------------------------------------------------------------*/
   /* The current thread in a multi-threaded application must protect access */
   /* to the file stream. In this case, _fp may be updated, so we must       */
   /* ensure that the local copy of _fp is flushed to shared memory before   */
   /* leaving the critical section (invalidated if it is not modified).      */
   /*------------------------------------------------------------------------*/
   __TI_file_lock(_fp);

   /*------------------------------------------------------------------------*/
   /* If the current stream is not associated with a file, return an error.  */
   /*------------------------------------------------------------------------*/
   if (_fp->fd == -1) 
   { 
      __TI_data_synch_INV(_fp, sizeof(FILE));
      __TI_file_unlock(_fp);
      return (EOF);
   }

   /*------------------------------------------------------------------------*/
   /* When positioning to a location relative to the current location,       */
   /* adjust for the fact that there may be something in the buffer.         */
   /*------------------------------------------------------------------------*/
   if(_ptrname == SEEK_CUR && _STCHK(_fp, _MODER) && _fp->pos)
      _offset -= (_fp->buff_stop - _fp->pos);

   __TI_doflush(_fp);

   _UNSET(_fp, (_STATEOF | _UNGETC));
   
   if ((lseek(_fp->fd, _offset, _ptrname)) == -1) 
   { 
      __TI_data_synch_WBINV(_fp, sizeof(FILE));
      __TI_file_unlock(_fp);
      return (EOF);
   }
   
   __TI_data_synch_WBINV(_fp, sizeof(FILE));
   __TI_file_unlock(_fp);
   return (0);
}
Esempio n. 2
0
_CODE_ACCESS int __TI_doflush(FILE *_fp)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*                                                                        */
   /*    num_write   -  The number of bytes to be written to the file        */
   /*    errchk      -  An indicator to see if WRITE was successful          */
   /*------------------------------------------------------------------------*/
   unsigned num_write = _fp->pos - _fp->buf;
   int errchk = 0;
 
   /*------------------------------------------------------------------------*/
   /* If the current stream is not associated with a file, return an error.  */
   /*------------------------------------------------------------------------*/
   if (_fp->fd == -1) return (EOF);

   /*------------------------------------------------------------------------*/
   /* If the stream is writable, and it has a buffer, call WRITE, and store  */
   /* its return value in errchk                                             */
   /*------------------------------------------------------------------------*/
   if (_STCHK(_fp, _MODEW) && _fp->buf != NULL && num_write != 0)
      errchk = write(_fp->fd, (char *)_fp->buf, num_write);
 
   /*------------------------------------------------------------------------*/
   /* If WRITE fails, set the error flag in the stream pointer, and return   */
   /* an EOF                                                                 */
   /*------------------------------------------------------------------------*/
   if (errchk < 0)
   {
      _SET(_fp, _STATERR);
      return (EOF);
   }
 
   /*------------------------------------------------------------------------*/
   /* Reset the buffer pointer, make files opened with the "+" flag          */
   /* available for wither reading or writing, and return a 0, indicating    */
   /* a success                                                              */
   /*------------------------------------------------------------------------*/
   _fp->pos = _fp->buff_stop = _fp->buf;
   if (_STCHK(_fp, _MODERW)) _UNSET(_fp, (_MODER | _MODEW));
   return 0;
}
Esempio n. 3
0
_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 the file stream. In this case, _fp may be updated, so we must       */
   /* ensure that the local copy of _fp is flushed to shared memory before   */
   /* leaving the critical section (invalidated if it is not modified).      */
   /*------------------------------------------------------------------------*/
   __TI_file_lock(_fp);

   /*------------------------------------------------------------------------*/
   /* Make sure that the file is readable.                                   */
   /*------------------------------------------------------------------------*/
   if (!__TI_rd_ok(_fp) || _size == 0 || _count == 0) 
   { 
      __TI_data_synch_INV(_fp, sizeof(FILE));
      __TI_file_unlock(_fp);
      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(_fp, sizeof(FILE));
       __TI_file_unlock(_fp);
       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)  __TI_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(_fp, sizeof(FILE));
   __TI_file_unlock(_fp);
 
   return (num_read / _size);
}
Esempio n. 4
0
_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);
   
}
Esempio n. 5
0
_CODE_ACCESS int setvbuf(register FILE *_fp, register char *_buf,
			 register int _type, register size_t _size)
{
   /*------------------------------------------------------------------------*/
   /* The current thread in a multi-threaded application must protect access */
   /* to the file stream. In this case, _fp may be updated, so we must       */
   /* ensure that the local copy of _fp is flushed to shared memory before   */
   /* leaving the critical section (invalidated if it is not modified).      */
   /*------------------------------------------------------------------------*/
   __TI_file_lock(_fp);

   /*------------------------------------------------------------------------*/
   /* If the current stream is not associated with a file, return an error.  */
   /*------------------------------------------------------------------------*/
   if (_fp->fd == -1 || (_type != _IONBF && _size <= 0)) 
   { 
      __TI_data_synch_INV(_fp, sizeof(FILE));
      __TI_file_unlock(_fp);
      return (EOF);
   }

   /*------------------------------------------------------------------------*/
   /* If a buffer already exists, free it if it was malloc'd, and reset all  */
   /* of the stream's buffer pointers.                                       */
   /*------------------------------------------------------------------------*/
   if (_fp->buf)
   {
      if(_STCHK(_fp, _BUFFALOC)) free((_fp->buf)-1);
      _UNSET(_fp, _BUFFALOC);
      _fp->buf = NULL;
      _fp->pos = NULL;
      _fp->bufend = NULL;
      _fp->buff_stop = NULL;
   }

   /*------------------------------------------------------------------------*/
   /* If NULL was used for the buffering mode, default to fully-buffered.    */
   /*------------------------------------------------------------------------*/
   if (!_type) _type = _IOFBF;

   /*------------------------------------------------------------------------*/
   /* Clear any previous buffering flags, and set the new one.               */
   /*------------------------------------------------------------------------*/
   _UNSET(_fp, (_IOLBF | _IOFBF | _IONBF));
   _SET(_fp, _type);

   /*------------------------------------------------------------------------*/
   /* If a buffer was provided, but its size is only one byte, allocate a    */
   /* different one.  Also, do not allow a buffer size greater than BUFSIZ.  */
   /* The buffer will always have one space at the beginning that is         */
   /* for UNGETC, in the event that an UNGETC is performed on an empty file, */
   /* or when the buffer is full, but unread.                                */
  /*------------------------------------------------------------------------*/
   if (_size == 1) _buf = NULL;
   if (_size > BUFSIZ) _size = BUFSIZ;

   if (_buf) _fp->buf = (unsigned char*)_buf+1;
   else
   {
      /*---------------------------------------------------------------------*/
      /* If allocating a buffer, provide _size bytes of usable space by      */
      /* incrementing _size, unless it is greater than BUFSIZ.               */
      /*---------------------------------------------------------------------*/
      if (_size <= BUFSIZ) _size++;
      if (! (_fp->buf = (unsigned char*)malloc(_size))) 
      {
         _SET(_fp, _STATERR);
         __TI_data_synch_WBINV(_fp, sizeof(FILE));
         __TI_file_unlock(_fp);
         return (EOF);
      }
      _fp->buf++;
      _SET(_fp, _BUFFALOC);
   }

   _fp->pos = _fp->buff_stop = _fp->buf;
   _fp->bufend = _fp->buf + _size -1;
   
   __TI_data_synch_WBINV(_fp, sizeof(FILE));
   __TI_file_unlock(_fp);

   /*------------------------------------------------------------------------*/
   /* SETUP _CLEANUP_PTR SO ALL BUFFERS WILL BE FLUSHED AT EXIT.             */
   /*------------------------------------------------------------------------*/
   /* __TI_cleanup_ptr is also a shared resource in multi-threaded           */
   /* applications, so accesses to it are also protected by the              */
   /* __TI_LOCK_FILE_TBL mutex.  The current thread will also invalidate any */
   /* local copy of __TI_cleanup_ptr in the data cache of the core that it   */
   /* is running on before leaving the critical section.                     */
   /*------------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_FILE_TBL);
   __TI_cleanup_ptr = __TI_cleanup;
   __TI_data_synch_WBINV(&__TI_cleanup_ptr, sizeof(__TI_cleanup_ptr));
   __TI_resource_unlock(__TI_LOCK_FILE_TBL);

   return (0);
}