コード例 #1
0
ファイル: _bufread.c プロジェクト: dannf/ti-cgt-c6x
_CODE_ACCESS void __TI_buff_read(FILE *_fp)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   int   errchk,
         j,
         buffer_size    = _fp->bufend - _fp->buf;

   /*------------------------------------------------------------------------*/
   /* If this is a line buffered stream, flush all line buffered streams.    */
   /* The current thread in a multi-threaded application must protect access */
   /* to __TI_LOCK_FILE_TBL shared resources (_ftable[] and __TI_ft_end) and */
   /* each file stream that is flushed. Ensure that the local copy of        */
   /* _ftable[] is flushed to shared memory and the local copy of            */
   /* __TI_ft_end is invalidated before leaving the critical section.        */
   /*------------------------------------------------------------------------*/
   if (_BUFFMODE(_fp) == _IOLBF)
   {
      __TI_resource_lock(__TI_LOCK_FILE_TBL);
      for (j=0; j < __TI_ft_end; j++)
	 if (_BUFFMODE(&_ftable[j]) == _IOLBF)
         {
            __TI_file_lock(&_ftable[j]);
	    __TI_doflush(&_ftable[j]);
            __TI_data_synch_WBINV(&_ftable[j], sizeof(FILE));
            __TI_file_unlock(&_ftable[j]);
         }
      __TI_data_synch_WBINV(&_ftable, sizeof(_ftable));
      __TI_data_synch_INV(&__TI_ft_end, sizeof(__TI_ft_end));
      __TI_resource_unlock(__TI_LOCK_FILE_TBL);
   }

   /*------------------------------------------------------------------------*/
   /* Read in the next characters from the file.                             */
   /*------------------------------------------------------------------------*/
   errchk = read(_fp->fd, (char *)_fp->buf, buffer_size);

   /*------------------------------------------------------------------------*/
   /* Adjust the buffer pointers.                                            */
   /*------------------------------------------------------------------------*/
   _fp->buff_stop = _fp->buf + errchk;
   _fp->pos = _fp->buf;

   /*------------------------------------------------------------------------*/
   /* Set any error flags if necessary.                                      */
   /*------------------------------------------------------------------------*/
   switch (errchk)
   {
      case -1 : _SET(_fp, _STATERR);
                break;
 
      case 0  : _SET(_fp, _STATEOF);
                break;
   }

   return;
 
}
コード例 #2
0
_CODE_ACCESS FILE *tmpfile(void)
{
   char tfname[L_tmpnam];
   FILE *_fp = NULL;
   
   if (tmpnam(tfname)) _fp = fopen(tfname, "wb+");

   /*------------------------------------------------------------------------*/
   /* A non-NULL _fp returned from fopen() is assumed to be a pointer to a   */
   /* file stream which is a shared resource.                                */
   /*------------------------------------------------------------------------*/
   /* The current thread in a multi-threaded application must protect access */
   /* to the file stream and __TI_tmpnams[]. In this case, _fp will be       */
   /* updated, so we must ensure that the local copy of _fp and _tmpnams[]   */
   /* are flushed to shared memory before leaving the critical section       */
   /* (invalidated if it is not modified).                                   */
   /*------------------------------------------------------------------------*/
   if (_fp)
   {
      __TI_file_lock(_fp);
      _SET(_fp, _TMPFILE);
      
      __TI_resource_lock(__TI_LOCK_TMPNAMS);
      
      strcpy(__TI_tmpnams[_fp->fd], tfname);
      
      __TI_data_synch_WBINV(&__TI_tmpnams[_fp->fd], L_tmpnam);
      __TI_data_synch_WBINV(_fp, sizeof(FILE));
      __TI_resource_unlock(__TI_LOCK_TMPNAMS);
      __TI_file_unlock(_fp);
   }


   return (_fp);
}
コード例 #3
0
ファイル: _io_perm.c プロジェクト: gary-simmons/PRU-SDK
_CODE_ACCESS int __TI_wrt_ok(FILE *_fp)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   int   result   = 0;
 
   /*------------------------------------------------------------------------*/
   /* If the current stream is not associated with a file, return an error.  */
   /*------------------------------------------------------------------------*/
   if(_fp->fd == -1) return (0);

   /*------------------------------------------------------------------------*/
   /* If this stream is currently being read return a 0.                     */
   /*------------------------------------------------------------------------*/
   if(_STCHK(_fp, _MODER)) 
   {
      _SET(_fp, _STATERR);
      return (0);
   } 

   /*------------------------------------------------------------------------*/
   /* If the stream is in append mode, move the file pointer to the end of   */
   /* the file.                                                              */
   /*------------------------------------------------------------------------*/
   if(_STCHK(_fp, _MODEA)) fseek(_fp, 0L, SEEK_END);
 
   /*------------------------------------------------------------------------*/
   /* If this stream was opened in update mode, and is able to either read   */
   /* or write currently, put it in write mode.                              */
   /*------------------------------------------------------------------------*/
   if(!_STCHK(_fp, _MODEW) && _STCHK(_fp, _MODERW)) _SET(_fp, _MODEW);
 
   /*------------------------------------------------------------------------*/
   /* Allocate a buffer for the stream if needed, and none exist.            */
   /*------------------------------------------------------------------------*/
   if(_fp->buf == NULL && !_STCHK(_fp, _IONBF))
      result |= setvbuf(_fp, NULL, _BUFFMODE(_fp), BUFSIZ);

   /*------------------------------------------------------------------------*/
   /* In writing mode, buff_stop is used to mark the end of the buffer.      */
   /*------------------------------------------------------------------------*/
   _fp->buff_stop = _fp->bufend;
 
   return (! result);
}
コード例 #4
0
ファイル: Pulse.cpp プロジェクト: LandyTang/2AFC_master5
inline static void t1_init(){
	t_TCCRnB = TCCR1B;
	_CLEAR(t_TCCRnB, CS10); _CLEAR(t_TCCRnB, CS11); _CLEAR(t_TCCRnB, CS12); //Close clock source.
	_SET(t_TCCRnB, WGM12); _CLEAR(t_TCCRnB, WGM13); //CTC mode, TOP: OCR1A;
	TCCR1B = t_TCCRnB;
	TCCR1A = 0;
	TCCR1C = 0;
	TCNT1H = 0; //set TCNT1 to 0   
	TCNT1L = 0; //set TCNT1 to 0
	TIMSK1 |= _BV(OCIE1A); // Output Compare A Match Interrupt Enable
}
コード例 #5
0
ファイル: _io_perm.c プロジェクト: gary-simmons/PRU-SDK
_CODE_ACCESS int __TI_rd_ok(FILE *_fp)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   int   result   =  0;

   /*------------------------------------------------------------------------*/
   /* If the current stream is not associated with a file, return an error.  */
   /*------------------------------------------------------------------------*/
   if(_fp->fd == -1) return (0);

   /*------------------------------------------------------------------------*/
   /* If this stream is currently being written to, return a 0.              */
   /*------------------------------------------------------------------------*/
   if(_STCHK(_fp, _MODEW)) 
   { 
      _SET(_fp, _STATERR); 
      return (0);
   }
 
   /*------------------------------------------------------------------------*/
   /* If this stream was opened in update mode, and is able to either read   */
   /* or write currently, put it in read mode.                               */
   /*------------------------------------------------------------------------*/
   if(!_STCHK(_fp, _MODER) && _STCHK(_fp, _MODERW)) _SET(_fp, _MODER);
 
   /*------------------------------------------------------------------------*/
   /* Allocate a buffer for the stream if needed, and none exist.            */
   /*------------------------------------------------------------------------*/
   if(_fp->buf == NULL && !_STCHK(_fp, _IONBF))
      result |= setvbuf(_fp, NULL, _BUFFMODE(_fp), BUFSIZ);
 
   return (! result);
 
}
コード例 #6
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;
}
コード例 #7
0
_CODE_ACCESS int fputs(const char *_ptr, register FILE *_fp)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   size_t   num_left, ptr_strlen;
   char     *fpos          = (char *)_ptr;
   int      room_left,
            flush_flag     = 0,
            num_to_write;

   /*------------------------------------------------------------------------*/
   /* 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 stream is writeable.                                */
   /*------------------------------------------------------------------------*/
   if (!__TI_wrt_ok(_fp)) 
   { 
      __TI_data_synch_INV(_fp, sizeof(FILE));
      __TI_file_unlock(_fp);
      return (EOF);
   }
 
   room_left = (int)(_fp->bufend - _fp->pos);
   ptr_strlen = num_left = strlen(_ptr);

   /*------------------------------------------------------------------------*/
   /* If the stream is non-buffered, call the lowlevel WRITE function.       */
   /*------------------------------------------------------------------------*/
   if (_BUFFMODE(_fp) == _IONBF) 
   {
       int num_written = 0;

       while (num_left > 0)
       {
	   int write_return = write(_fp->fd, _ptr + num_written, num_left);
	   if (write_return < 0) 
	   { 
	       _SET(_fp, _STATERR); 
               __TI_data_synch_WBINV(_fp, sizeof(FILE));
               __TI_file_unlock(_fp);
	       return (EOF);
	   }
	   else
	   {
	       num_written += write_return;
	       num_left    -= write_return;
	   }
       }

       __TI_data_synch_WBINV(_fp, sizeof(FILE));
       __TI_file_unlock(_fp);
       return ptr_strlen;
   }
 
   /*------------------------------------------------------------------------*/
   /* Write the string into the buffer, flushing it when full.               */
   /*------------------------------------------------------------------------*/
   while (num_left > 0)
   {
      num_to_write = (num_left > room_left) ? room_left : num_left;
      if ((_BUFFMODE(_fp) == _IOLBF) && memchr(fpos, '\n', num_to_write))
      { 
         num_to_write = (char *)memchr(fpos, '\n', num_to_write) - fpos + 1;
         flush_flag = 1;
      }
      memcpy(_fp->pos, fpos, num_to_write);

      /*---------------------------------------------------------------------*/
      /* Update pointers and counters.                                       */
      /*---------------------------------------------------------------------*/
      _fp->pos  += num_to_write;
      fpos      += num_to_write;
      num_left  -= num_to_write;
      room_left -= num_to_write;

      /*---------------------------------------------------------------------*/
      /* If the buffer is full, flush it.  Any I/O errors cause this         */
      /* function to exit, returning an EOF.                                 */
      /*---------------------------------------------------------------------*/
      if (room_left == 0 || flush_flag)
      {
         if (__TI_doflush(_fp))
         {
            _SET(_fp, _STATERR);
            __TI_data_synch_WBINV(_fp, sizeof(FILE));
            __TI_file_unlock(_fp);
            return (EOF);
         }
         room_left = (int)(_fp->bufend - _fp->pos);
         _SET(_fp, _MODEW);
         flush_flag = 0;
      }
   }

   __TI_data_synch_WBINV(_fp, sizeof(FILE));
   __TI_file_unlock(_fp);
   return ptr_strlen;
}
コード例 #8
0
ファイル: fputc.c プロジェクト: dannf/ti-cgt-c6x
_CODE_ACCESS int fputc(int _c, register FILE *_fp)
{
   /*------------------------------------------------------------------------*/
   /* 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 stream is writeable.                                */
   /*------------------------------------------------------------------------*/
   if (!__TI_wrt_ok(_fp)) 
   { 
      __TI_data_synch_INV(_fp, sizeof(FILE));
      __TI_file_unlock(_fp);
      return EOF; 
   }

   /*------------------------------------------------------------------------*/
   /* If the stream is non-buffered, call the lowlevel WRITE function.       */
   /*------------------------------------------------------------------------*/
   if(_BUFFMODE(_fp) == _IONBF)
   {
      char cbuf = (char)_c;

      if ((write(_fp->fd, &cbuf, 1)) == -1)
      {
         _SET(_fp, _STATERR);
         __TI_data_synch_WBINV(_fp, sizeof(FILE));
         __TI_file_unlock(_fp);
         return (EOF);
      }

      else 
      { 
         __TI_data_synch_WBINV(_fp, sizeof(FILE));
         __TI_file_unlock(_fp);
	 return ((unsigned char)_c);
      }
   }

   /*------------------------------------------------------------------------*/
   /* Check for room in the buffer. If room, add the character. Must         */
   /* check before writing because C++ library fills the buffer to           */
   /* capacity, then calls fputc() from overflow() (CQXXXXX).                */
   /*------------------------------------------------------------------------*/
   if ((_fp->pos >= _fp->bufend) && __TI_doflush(_fp))
   {
      _SET(_fp, _STATERR);
      __TI_data_synch_WBINV(_fp, sizeof(FILE));
      __TI_file_unlock(_fp);
      return (EOF);
   }

   *(_fp->pos++) = (unsigned char)_c;

   /*------------------------------------------------------------------------*/
   /* If a line-buffered stream reached a newline character, flush it.       */
   /*------------------------------------------------------------------------*/
   if ((_STCHK(_fp, _IOLBF) && _c == '\n') && __TI_doflush(_fp))
   {
      _SET(_fp, _STATERR);
      __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 ((unsigned char)_c);
}
コード例 #9
0
ファイル: fread.c プロジェクト: dannf/ti-cgt-c6x
_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);
}
コード例 #10
0
static FILE *_openfile(const char *_fname, register FILE *_fp, const char 
                       *_mode)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   int         wr, 
               bin = 0, 
               plus = 0;
   unsigned    lflags = 0;

   if (!_fp) return (NULL);
 
   /*------------------------------------------------------------------------*/
   /* SETUP _CLEANUP_PTR SO THAT ALL OPENED FILES WILL BE CLOSED AT EXIT.    */
   /*------------------------------------------------------------------------*/
   /* _cleanup_ptr is considered a shared resource for multi-threaded        */
   /* applications. Access to it is also protected by the __TI_LOCK_FILE_TBL */
   /* mutex which encloses each call to _openfile. The local copy of         */
   /* _cleanup_ptr is flushed to shared memory as soon as it is updated.     */
   /*------------------------------------------------------------------------*/
   _cleanup_ptr = _cleanup;
   __TI_data_synch_WBINV(&_cleanup_ptr, sizeof(_cleanup_ptr));
   
   /*------------------------------------------------------------------------*/
   /* Set the flags in the stream to reflect to I/O mode of the stream to be */
   /* opened.                                                                */
   /*------------------------------------------------------------------------*/
   wr    = _mode[0];
   if (_mode[1])
   {
      bin  = ((_mode[1] == 'b') || (_mode[2] == 'b'));
      plus = ((_mode[1] == '+') || (_mode[2] == '+'));
   }

   _fp->flags = 0;

   if (!plus)
      _SET(_fp, (wr == 'r') ? _MODER : 
                (wr == 'w' || wr == 'a') ? _MODEW : 0);

   _SET(_fp, (wr == 'a') ? _MODEA : 0);
   _SET(_fp, (bin)  ? _MODEBIN : 0);
   _SET(_fp, (plus) ? _MODERW  : 0);
 
   if (bin) lflags |= (O_BINARY);

   /*------------------------------------------------------------------------*/
   /* Set the flags in LFLAGS to reflect the flags that will be necessary to */
   /* call the lowlevel OPEN function properly for this stream.              */
   /*------------------------------------------------------------------------*/
   switch (wr)
   {
      case 'r' : lflags |= (plus) ? O_RDWR : O_RDONLY;
                 break;
 
      case 'a' : lflags |= (plus) ? O_RDWR : O_WRONLY;
                 lflags |= (O_APPEND | O_CREAT);
                 break;
 
      case 'w' : lflags |= (plus) ? O_RDWR : O_WRONLY;
                 lflags |= (O_TRUNC | O_CREAT);
                 break;
   }

   /*------------------------------------------------------------------------*/
   /* Call the lowlevel OPEN function, and store the returned file           */
   /* descriptor into the stream.  If the OPEN function fails, return NULL.  */
   /*------------------------------------------------------------------------*/
   if ((_fp->fd = open(_fname, lflags, 0666)) < 0) return (NULL);

   /*------------------------------------------------------------------------*/
   /* Workaround for defect SDSCM00030215.                                   */
   /* Use of ftell and fseek on opened DOS formatted files is not supported  */
   /* in text mode, with buffered I/O.  The run-time library code will       */
   /* adjust the return value from the host ftell call.  This adjustment is  */
   /* not in-sync with an MS C runtime ftell value in the interpretation of  */
   /* carriage-return/line feed pairs.  Use of ftell/fseek on DOS formatted  */
   /* files requires one of the following changes:                           */
   /*  1. Rebuild the rts library with the following macro,                  */
   /*     _TI_FORCE_UNBUFFERED_TEXT_IO, defined.  This will prevent any rts  */
   /*     adjustment of ftell values.                                        */
   /*  2. Open the DOS file in binary mode.                                  */
   /*  3. Use one of many DOS-to-Unix file converters to strip               */
   /*     carriage-returns from the input file.                              */
   /*------------------------------------------------------------------------*/
#ifdef _TI_FORCE_UNBUFFERED_TEXT_IO
   if ((wr == 'r') && (!bin))
       setbuf(_fp, 0);
#endif

   return (_fp);
}
コード例 #11
0
_CODE_ACCESS size_t fwrite(const void *_ptr, size_t _size, size_t _count,
                           register FILE *_fp)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   unsigned char    *fpos       = (unsigned char *)_ptr;
   unsigned char    *nl_pos;
            size_t   buffer_size,
                     next_nl,
                     room_left;
            size_t   num_left    = _size * _count,
                     num_to_write,
                     num_written  = 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 stream is writeable.                                */
   /*------------------------------------------------------------------------*/
   buffer_size = (_fp->bufend - _fp->buf);
   if (!__TI_wrt_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 WRITE function.       */
   /*------------------------------------------------------------------------*/
   if(_BUFFMODE(_fp) == _IONBF) 
   {
       int num_written = 0;

       while (num_left > 0)
       {
	   int write_return = write(_fp->fd, 
				    (char *)fpos + num_written, num_left);
	   if (write_return <= 0) 
	   { 
	       _SET(_fp, _STATERR); 
	       break;
	   }
	   else
	   {
	       num_written += write_return;
	       num_left    -= write_return;
	   }
       }

       __TI_data_synch_WBINV(_fp, sizeof(FILE));
       __TI_file_unlock(_fp);
       return (num_written / _size);
   }
 
   room_left   = (_fp->bufend - _fp->pos);
   if (_STCHK(_fp, _IOLBF))
       next_nl = (char *)memchr(fpos, '\n', num_left) - (char *)fpos + 1;
 
   while (num_left > 0)
   {
      /*---------------------------------------------------------------------*/
      /* Determine how many characters should be written based on buffering  */
      /* mode.  For non-buffered streams, call the lowlevel WRITE function.  */
      /* For fully buffered streams, put as many characters in the buffer as */
      /* possible.  For line buffered streams, put characters into the       */
      /* util the buffer is full, the last character is reached, or a        */
      /* newline character is reached.                                       */
      /*---------------------------------------------------------------------*/
      switch (_BUFFMODE(_fp))
      {
         case _IOFBF : num_to_write = (room_left > num_left) ? 
                       num_left : room_left;
                       break;
 
         case _IOLBF : num_to_write = (room_left > next_nl) ? next_nl :
                       (room_left > num_left) ? num_left : room_left;
                       break;
 
	 /*------------------------------------------------------------------*/
	 /* The only other available _BUFFMODE for _fp is _IONBF which has   */
	 /* already been accounted for above. We should never get here.      */
	 /*------------------------------------------------------------------*/
         default     : return (0);
      }
 
      /*---------------------------------------------------------------------*/
      /* Write the data to the buffer, and update the buffer pointer and the */
      /* ROOM_LEFT coutner.                                                  */
      /*---------------------------------------------------------------------*/
      memcpy(_fp->pos, fpos, num_to_write);
      _fp->pos += num_to_write;
      room_left = (_fp->bufend - _fp->pos);

      /*---------------------------------------------------------------------*/
      /* If the buffer is full, or a newline character has been encountered  */
      /* on a line-buffered stream, flush it.                                */
      /*---------------------------------------------------------------------*/
      if (room_left == 0 || (_STCHK(_fp, _IOLBF) && num_to_write == next_nl))
      {
         if (__TI_doflush(_fp))
         {
            _SET(_fp, _STATERR); 
            __TI_data_synch_WBINV(_fp, sizeof(FILE));
            __TI_file_unlock(_fp);
            return (num_written / _size);
         }
         room_left = buffer_size;

         /*------------------------------------------------------------------*/
         /* The _DOFLUSH function clears the write flag on streams opened in */
         /* update mode.  Make sure that the write flag is still set here.   */
         /*------------------------------------------------------------------*/
         _SET(_fp, _MODEW);
      }

      /*---------------------------------------------------------------------*/
      /* Update pointers and counters.                                       */
      /*---------------------------------------------------------------------*/
      num_written += num_to_write;
      fpos += num_to_write;
      num_left -= num_to_write;
 
      /*---------------------------------------------------------------------*/
      /* For line-buffered streams, find the next occurance of a newline     */
      /* character.  If there are no more, and the remaining data will fit   */
      /* in the buffer, exit the loop where the remaining data will be moved */
      /* there.  Otherwise loop until this condition is true.                */
      /*---------------------------------------------------------------------*/
      if (_STCHK(_fp, _IOLBF))
      {
         nl_pos = (unsigned char *)memchr((fpos + 1), '\n', 
					  (num_left > 0) ? (num_left-1) : 0);
         if (! nl_pos)
         {
            if (num_left < room_left) break;
            else next_nl = buffer_size + 1;
         }
         else next_nl = (nl_pos - fpos) + 1;
      }
   }

   /*------------------------------------------------------------------------*/
   /* Copy the rest of the characters into the buffer for line-buffered      */
   /* streams.                                                               */
   /*------------------------------------------------------------------------*/
   if (_STCHK(_fp, _IOLBF))
   {
      memcpy(_fp->pos, fpos, num_left);
      num_written += num_left;
      _fp->pos += num_left;
   }
 
   __TI_data_synch_WBINV(_fp, sizeof(FILE));
   __TI_file_unlock(_fp);
   return (num_written / _size);
}
コード例 #12
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);
   
}
コード例 #13
0
ファイル: setvbuf.c プロジェクト: vorlonofportland/ti-cgt-c6x
_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);
}