_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; }
_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); }
_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); }
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 }
_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); }
_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; }
_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; }
_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); }
_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); }
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); }
_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); }
_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 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); }