void __ioalloc( FILE *fp ) { __chktty( fp ); /* JBS 28-aug-90 */ if( fp->_bufsize == 0 ) { if( fp->_flag & _IOLBF ) { fp->_bufsize = 134; } else if( fp->_flag & _IONBF ) { /* Use small but reasonably sized buffer; otherwise we will end * up calling into the OS for every character, completely killing * performance on unbuffered stream output through printf() etc., * especially in extended DOS because of mode switches. */ fp->_bufsize = 64; } else { fp->_bufsize = BUFSIZ; } } _FP_BASE( fp ) = lib_malloc( fp->_bufsize ); if( _FP_BASE( fp ) == NULL ) { fp->_flag &= ~(_IONBF | _IOLBF | _IOFBF); fp->_flag |= _IONBF; /* can't get big buffer */ _FP_BASE( fp ) = (unsigned char *)&(fp->_ungotten); fp->_bufsize = 1; } else { fp->_flag |= _BIGBUF; /* got big buffer */ } fp->_ptr = _FP_BASE( fp ); fp->_cnt = 0; }
int __doclose( FILE *fp, int close_handle ) { int ret; if( (fp->_flag & (_READ | _WRITE)) == 0 ) { return( -1 ); /* file already closed */ } ret = 0; if( fp->_flag & _DIRTY ) { if( __flush( fp ) ) { ret = -1; } } _AccessFile( fp ); /* * 02-nov-92 G.Turcotte Syncronize buffer pointer with the file pointer * IEEE Std 1003.1-1988 B.8.2.3.2 * 03-nov-03 B.Oldeman Inlined ftell; we already know the buffer isn't * dirty (because of the flush), so only a "get" applies */ if( fp->_cnt != 0 ) { /* if something in buffer */ __lseek( fileno( fp ), -fp->_cnt, SEEK_CUR ); } if( close_handle ) { #if defined( __UNIX__ ) || defined( __NETWARE__ ) || defined( __RDOS__ ) || defined( __RDOSDEV__ ) // we don't get to implement the close function on these systems ret |= close( fileno( fp ) ); #else ret |= __close( fileno( fp ) ); #endif } if( fp->_flag & _BIGBUF ) { /* if we allocated the buffer */ lib_free( _FP_BASE( fp ) ); _FP_BASE( fp ) = NULL; } #ifndef __UNIX__ /* this never happens under UNIX */ if( fp->_flag & _TMPFIL ) { /* if this is a temporary file */ __RmTmpFileFn( fp ); } #endif fp->_flag &= _DYNAMIC; _ReleaseFile( fp ); return( ret ); }
int __fill_buffer( FILE *fp ) { if( _FP_BASE( fp ) == NULL ) { __ioalloc( fp ); } if( fp->_flag & _ISTTY ) { /* 20-aug-90 */ if( fp->_flag & (_IONBF | _IOLBF) ) { __flushall( _ISTTY ); /* flush all TTY output */ } } fp->_flag &= ~_UNGET; /* 10-mar-90 */ fp->_ptr = _FP_BASE( fp ); #ifdef __UNIX__ fp->_cnt = __qread( fileno( fp ), fp->_ptr, (fp->_flag & _IONBF) ? 1 : fp->_bufsize ); #else if(( fp->_flag & (_IONBF | _ISTTY)) == (_IONBF | _ISTTY) && ( fileno( fp ) == STDIN_FILENO )) { int c; /* JBS 31-may-91 */ fp->_cnt = 0; c = getche(); if( c != EOF ) { *fp->_ptr = c; fp->_cnt = 1; } } else { fp->_cnt = __qread( fileno( fp ), fp->_ptr, (fp->_flag & _IONBF) ? 1 : fp->_bufsize ); } #endif if( fp->_cnt <= 0 ) { if( fp->_cnt == 0 ) { fp->_flag |= _EOF; } else { fp->_flag |= _SFERR; fp->_cnt = 0; } } return( fp->_cnt ); }
_WCRTLINK int __F_NAME(fputs,fputws)( const CHAR_TYPE *s, FILE *fp ) { const CHAR_TYPE *start; int c; int not_buffered; int rc; _ValidFile( fp, __F_NAME(EOF,WEOF) ); _AccessFile( fp ); if( _FP_BASE(fp) == NULL ) { __ioalloc( fp ); /* allocate buffer */ } not_buffered = 0; if( fp->_flag & _IONBF ) { not_buffered = 1; fp->_flag &= ~_IONBF; fp->_flag |= _IOLBF; } rc = 0; start = s; while( c = *s ) { s++; #ifndef __WIDECHAR__ if( (fputc)( c, fp ) == EOF ) { /* 23-oct-91 */ rc = EOF; break; } #else if( (fputwc)( c, fp ) == WEOF ) { /* 23-oct-91 */ rc = -1; break; } #endif } if( not_buffered ) { fp->_flag &= ~_IOLBF; fp->_flag |= _IONBF; if( rc == 0 ) { rc = __flush( fp ); /* 23-oct-91 */ } } if( rc == 0 ) { /* return the number of items written */ /* this is ok by ANSI which says that success is */ /* indicated by a non-negative return value */ rc = s - start; } _ReleaseFile( fp ); return( rc ); }
_WCRTLINK FILE *__F_NAME(fdopen,_wfdopen)( int handle, const CHAR_TYPE *access_mode ) { unsigned flags; FILE * fp; #if !defined(__NETWARE__) int extflags; #endif if( handle == -1 ) { __set_errno( EBADF ); /* 5-dec-90 */ return( NULL ); /* 19-apr-90 */ } #ifdef __NETWARE__ flags = __F_NAME(__open_flags,__wopen_flags)( access_mode ); #else flags = __F_NAME(__open_flags,__wopen_flags)( access_mode, &extflags ); #endif if( flags == 0 ) return( NULL ); #if !defined(__NETWARE__) /* make sure the handle has the same text/binary mode */ if( __iomode( handle, flags ) == -1 ) { return( NULL ); } #endif fp = __allocfp( handle ); /* JBS 30-aug-91 */ if( fp ) { fp->_flag &= ~(_READ | _WRITE); /* 2-dec-90 */ fp->_flag |= flags; fp->_cnt = 0; _FP_BASE(fp) = NULL; fp->_bufsize = 0; /* was BUFSIZ JBS 91/05/31 */ #ifndef __NETWARE__ _FP_ORIENTATION(fp) = _NOT_ORIENTED; /* initial orientation */ _FP_EXTFLAGS(fp) = extflags; #endif #if defined(__NT__) || defined(__OS2__) _FP_PIPEDATA(fp).isPipe = 0; /* not a pipe */ #endif fp->_handle = handle; /* BJS 91-07-23 */ if( __F_NAME(tolower,towlower)( *access_mode ) == 'a' ) { fseek( fp, 0L, SEEK_END ); } __chktty( fp ); /* JBS 31-may-91 */ #if !defined(__UNIX__) && !defined(__NETWARE__) __SetIOMode( handle, flags ); #endif } return( fp ); }
int __doclose( FILE *fp, int close_handle ) { int ret; if( fp->_flag == 0 ) { return( -1 ); /* file already closed */ } ret = 0; if( fp->_flag & _DIRTY ) { ret = __flush( fp ); } _AccessFile( fp ); if( fp->_cnt != 0 ) { /* if something in buffer */ __lseek( fileno( fp ), -fp->_cnt, SEEK_CUR ); } if( close_handle ) { #if defined(__UNIX__) || defined(__NETWARE__) // we don't get to implement the close function on these systems ret |= close( fileno( fp ) ); #else ret |= __close( fileno( fp ) ); #endif } if( fp->_flag & _BIGBUF ) { /* if we allocated the buffer */ lib_free( _FP_BASE(fp) ); _FP_BASE(fp) = NULL; } #ifndef __UNIX__ /* this never happens under UNIX */ if( fp->_flag & _TMPFIL ) { /* if this is a temporary file */ __RmTmpFileFn( fp ); } #endif _ReleaseFile( fp ); return( ret ); }
static int __update_buffer( long diff, FILE *fp ) #endif { /* diff is relative to fp->_ptr if diff is within the buffer update the pointers and return 0 otherwise update the pointers and return 1 */ if( diff <= fp->_cnt && diff >= (_FP_BASE( fp ) - fp->_ptr) ) { fp->_flag &= ~(_EOF); fp->_ptr += diff; fp->_cnt -= diff; return( 0 ); } return( 1 ); }
_WCRTLINK FILE *__F_NAME(fdopen,_wfdopen)( int handle, const CHAR_TYPE *access_mode ) { int file_flags; FILE *fp; int extflags; if( handle == -1 ) { _RWD_errno = EBADF; return( NULL ); } file_flags = __F_NAME(__open_flags,__wopen_flags)( access_mode, &extflags ); if( file_flags == 0 ) return( NULL ); #ifndef __NETWARE__ /* make sure the handle has the same text/binary mode */ if( __iomode( handle, file_flags ) == -1 ) { return( NULL ); } #endif fp = __allocfp(); if( fp != NULL ) { fp->_flag |= file_flags; fp->_cnt = 0; _FP_BASE( fp ) = NULL; fp->_bufsize = 0; /* was BUFSIZ JBS 91/05/31 */ #ifndef __NETWARE__ _FP_ORIENTATION(fp) = _NOT_ORIENTED; /* initial orientation */ _FP_EXTFLAGS(fp) = extflags; #endif #if defined( __NT__ ) || defined( __OS2__ ) || defined(__UNIX__) _FP_PIPEDATA(fp).isPipe = 0; /* not a pipe */ #endif fp->_handle = handle; /* BJS 91-07-23 */ if( __F_NAME(tolower,towlower)( (UCHAR_TYPE)*access_mode ) == STRING( 'a' ) ) { fseek( fp, 0, SEEK_END ); } __chktty( fp ); /* JBS 31-may-91 */ #if !defined( __UNIX__ ) && !defined( __NETWARE__ ) __SetIOMode( handle, file_flags ); #endif } return( fp ); }
static FILE *__F_NAME(__doopen,__wdoopen)( const CHAR_TYPE *name, CHAR_TYPE mode, int file_flags, int extflags, int shflag, /* sharing flag */ FILE * fp ) { int open_mode; int p_mode; SetupTGCSandNCS( RETURN_ARG( FILE *, 0 ) ); /* for NW386 */ fp->_flag &= ~(_READ | _WRITE); fp->_flag |= file_flags; /* we need the mode character to indicate if the original */ /* intention is to open for read or for write */ mode = __F_NAME(tolower,towlower)( mode ); if( mode == 'r' ) { open_mode = O_RDONLY; if( file_flags & _WRITE ) { /* if "r+" mode */ open_mode = O_RDWR; } #if defined( __NETWARE__ ) open_mode |= O_BINARY; #elif defined( __UNIX__ ) #else if( file_flags & _BINARY ) { open_mode |= O_BINARY; } else { open_mode |= O_TEXT; } #endif p_mode = 0; } else { /* mode == 'w' || mode == 'a' */ if( file_flags & _READ ) { /* if "a+" or "w+" mode */ open_mode = O_RDWR | O_CREAT; } else { open_mode = O_WRONLY | O_CREAT; } if( file_flags & _APPEND ) { open_mode |= O_APPEND; } else { /* mode == 'w' */ open_mode |= O_TRUNC; } #if defined( __NETWARE__ ) open_mode |= O_BINARY; #elif defined( __UNIX__ ) #else if( file_flags & _BINARY ) { open_mode |= O_BINARY; } else { open_mode |= O_TEXT; } #endif p_mode = PMODE; } fp->_handle = __F_NAME(sopen,_wsopen)( name, open_mode, shflag, p_mode ); if( fp->_handle == -1 ) { // since we couldn't open the file, release the FILE struct __freefp( fp ); return( NULL ); } fp->_cnt = 0; fp->_bufsize = 0; /* was BUFSIZ JBS 31-may-91 */ #ifndef __NETWARE__ _FP_ORIENTATION(fp) = _NOT_ORIENTED; /* initial orientation */ _FP_EXTFLAGS(fp) = extflags; #endif #if defined( __NT__ ) || defined( __OS2__ ) _FP_PIPEDATA(fp).isPipe = 0; /* not a pipe */ #endif _FP_BASE(fp) = NULL; if( file_flags & _APPEND ) { fseek( fp, 0L, SEEK_END ); } __chktty( fp ); /* JBS 28-aug-90 */ return( fp ); }
_WCRTLINK int fseek( FILE *fp, long offset, int origin ) #endif { _ValidFile( fp, -1 ); _AccessFile( fp ); /* if the file is open for any sort of writing we must ensure that the buffer is flushed when dirty so that the integrity of the data is preserved. if there is an ungotten character in the buffer then the data must be discarded to ensure the integrity of the data */ if( fp->_flag & (_WRITE | _UNGET) ) { if( fp->_flag & _DIRTY ) { /* the __flush routine aligns the DOS file pointer with the start of the resulting cleared buffer, as such, the SEEK_CUR code used for the non-_DIRTY buffer case is not required */ if( __flush( fp ) ) { // assume __flush set the errno value // if erroneous input, override errno value if( origin == SEEK_SET && offset < 0 ) { _RWD_errno = EINVAL; } _ReleaseFile( fp ); return( -1 ); } } else { if( origin == SEEK_CUR ) { offset -= fp->_cnt; } fp->_ptr = _FP_BASE( fp ); fp->_cnt = 0; } fp->_flag &= ~(_EOF|_UNGET); #ifdef __INT64__ if( _lseeki64( fileno( fp ), offset, origin ) == -1 ) { #else if( lseek( fileno( fp ), offset, origin ) == -1 ) { #endif _ReleaseFile( fp ); return( -1 ); } } else { // file is open for read only, // no characters have been ungotten // the OS file pointer is at fp->_ptr + fp->_cnt relative to the // FILE* buffer switch( origin ) { case SEEK_CUR: { long ptr_delta = fp->_cnt; if( __update_buffer( offset, fp ) ) { offset -= ptr_delta; #ifdef __INT64__ if( _lseeki64( fileno( fp ), offset, origin ) == -1 ) { #else if( lseek( fileno( fp ), offset, origin ) == -1 ) { #endif _ReleaseFile( fp ); return( -1 ); } __reset_buffer(fp); } } break; case SEEK_SET: { #ifdef __INT64__ long long file_ptr = _telli64( fileno( fp ) ); #else long file_ptr = tell( fileno( fp ) ); #endif file_ptr -= fp->_cnt; if( __update_buffer( offset - file_ptr, fp ) ) { #ifdef __INT64__ if( _lseeki64( fileno( fp ), offset, origin ) == -1 ) { #else if( lseek( fileno( fp ), offset, origin ) == -1 ) { #endif _ReleaseFile( fp ); return( -1 ); } __reset_buffer(fp); } } break; case SEEK_END: __reset_buffer(fp); #ifdef __INT64__ if( _lseeki64( fileno( fp ), offset, origin ) == -1 ) { #else if( lseek( fileno( fp ), offset, origin ) == -1 ) { #endif _ReleaseFile( fp ); return( -1 ); } break; default: _RWD_errno = EINVAL; _ReleaseFile( fp ); return( -1 ); } } _ReleaseFile( fp ); return( 0 ); /* indicate success */ }
/* * This used to be in __update_buffer(), but we don't want to do this until * AFTER we've made certain that lseek() will be a successful one. */ static void __reset_buffer( FILE *fp ) { fp->_flag &= ~(_EOF); fp->_ptr = _FP_BASE( fp ); fp->_cnt = 0; }
_WCRTLINK wint_t (ungetwc)( wint_t c, FILE *fp ) #endif { if( c == __F_NAME(EOF,WEOF) ) { /* cannot push EOF */ return( c ); } _ValidFile( fp, __F_NAME(EOF,WEOF) ); _AccessFile( fp ); /*** Deal with stream orientation ***/ #ifndef __NETWARE__ #ifdef __WIDECHAR__ if( _FP_ORIENTATION(fp) != _WIDE_ORIENTED ) { if( _FP_ORIENTATION(fp) == _NOT_ORIENTED ) { _FP_ORIENTATION(fp) = _WIDE_ORIENTED; } else { _ReleaseFile( fp ); return( WEOF ); } } #else if( _FP_ORIENTATION(fp) != _BYTE_ORIENTED ) { if( _FP_ORIENTATION(fp) == _NOT_ORIENTED ) { _FP_ORIENTATION(fp) = _BYTE_ORIENTED; } else { _ReleaseFile( fp ); return( EOF ); } } #endif #endif if( fp->_flag & _DIRTY ) { /* cannot unget after a put */ _ReleaseFile( fp ); return( __F_NAME(EOF,WEOF) ); } if(( fp->_flag & _READ ) == 0 ) { /* not open for input */ _ReleaseFile( fp ); return( __F_NAME(EOF,WEOF) ); } if( _FP_BASE(fp) == NULL ) { /* no buffer allocated */ __ioalloc( fp ); } #ifdef __WIDECHAR__ if( fp->_flag & _BINARY ) { /*** Leave the character in wide form ***/ if( fp->_cnt == 0 ) { /* read buffer is empty */ fp->_cnt = sizeof(wchar_t); fp->_ptr = _FP_BASE(fp) + fp->_bufsize - sizeof(wchar_t); fp->_flag |= _UNGET; /* 10-mar-90 */ memcpy( fp->_ptr, &c, sizeof(wchar_t) ); } else if( fp->_ptr != _FP_BASE(fp) ) { fp->_cnt += sizeof(wchar_t); fp->_ptr -= sizeof(wchar_t); fp->_flag |= _UNGET; memcpy( fp->_ptr, &c, sizeof(wchar_t) ); } else { /* read buffer is full */ _ReleaseFile( fp ); return( WEOF ); } } else { char mbc[MB_CUR_MAX]; int mbcLen; /*** Convert the character to multibyte form ***/ if( wctomb( mbc, c ) == -1 ) { __set_errno( EILSEQ ); return( WEOF ); } mbcLen = _mbclen( mbc ); /*** Store the converted character ***/ if( fp->_cnt == 0 ) { /* read buffer is empty */ fp->_cnt = mbcLen; fp->_ptr = _FP_BASE(fp) + fp->_bufsize - mbcLen; fp->_flag |= _UNGET; /* 10-mar-90 */ _mbccpy( fp->_ptr, mbc ); } else if( fp->_ptr != _FP_BASE(fp) ) { fp->_cnt += mbcLen; fp->_ptr -= mbcLen; fp->_flag |= _UNGET; _mbccpy( fp->_ptr, mbc ); } else { /* read buffer is full */ _ReleaseFile( fp ); return( WEOF ); } } #else if( fp->_cnt == 0 ) { /* read buffer is empty */ fp->_cnt = CHARSIZE; fp->_ptr = _FP_BASE(fp) + fp->_bufsize - CHARSIZE; fp->_flag |= _UNGET; /* 10-mar-90 */ *(CHAR_TYPE*)(fp->_ptr) = c; } else if( fp->_ptr != _FP_BASE(fp) ) { fp->_cnt += CHARSIZE; fp->_ptr -= CHARSIZE; if( *(CHAR_TYPE*)(fp->_ptr) != c ) fp->_flag |= _UNGET; /* 10-mar-90 */ *(CHAR_TYPE*)(fp->_ptr) = c; } else { /* read buffer is full */ _ReleaseFile( fp ); return( EOF ); } #endif fp->_flag &= ~ _EOF; _ReleaseFile( fp ); return( (UCHAR_TYPE) c ); }
_WCRTLINK INTCHAR_TYPE __F_NAME(ungetc,ungetwc)( INTCHAR_TYPE c, FILE *fp ) { if( c == INTCHAR_EOF ) { /* cannot push EOF */ return( c ); } _ValidFile( fp, INTCHAR_EOF ); _AccessFile( fp ); /*** Deal with stream orientation ***/ ORIENT_STREAM( fp, INTCHAR_EOF ); if( fp->_flag & _DIRTY ) { /* cannot unget after a put */ _ReleaseFile( fp ); return( INTCHAR_EOF ); } if(( fp->_flag & _READ ) == 0 ) { /* not open for input */ _ReleaseFile( fp ); return( INTCHAR_EOF ); } if( _FP_BASE( fp ) == NULL ) { /* no buffer allocated */ __ioalloc( fp ); } #ifdef __WIDECHAR__ if( fp->_flag & _BINARY ) { /*** Leave the character in wide form ***/ if( fp->_cnt == 0 ) { /* read buffer is empty */ fp->_cnt = sizeof( wchar_t ); fp->_ptr = _FP_BASE( fp ) + fp->_bufsize - sizeof( wchar_t ); fp->_flag |= _UNGET; /* 10-mar-90 */ memcpy( fp->_ptr, &c, sizeof( wchar_t ) ); } else if( fp->_ptr != _FP_BASE( fp ) ) { fp->_cnt += sizeof( wchar_t ); fp->_ptr -= sizeof( wchar_t ); fp->_flag |= _UNGET; memcpy( fp->_ptr, &c, sizeof( wchar_t ) ); } else { /* read buffer is full */ _ReleaseFile( fp ); return( WEOF ); } } else { unsigned char mbc[MB_CUR_MAX]; int mbcLen; /*** Convert the character to multibyte form ***/ if( wctomb( (char *)mbc, c ) == -1 ) { _RWD_errno = EILSEQ; return( WEOF ); } mbcLen = _mbclen( mbc ); /*** Store the converted character ***/ if( fp->_cnt == 0 ) { /* read buffer is empty */ fp->_cnt = mbcLen; fp->_ptr = _FP_BASE( fp ) + fp->_bufsize - mbcLen; fp->_flag |= _UNGET; /* 10-mar-90 */ _mbccpy( fp->_ptr, mbc ); } else if( fp->_ptr != _FP_BASE( fp ) ) { fp->_cnt += mbcLen; fp->_ptr -= mbcLen; fp->_flag |= _UNGET; _mbccpy( fp->_ptr, mbc ); } else { /* read buffer is full */ _ReleaseFile( fp ); return( WEOF ); } } #else if( fp->_cnt == 0 ) { /* read buffer is empty */ fp->_cnt = 1; fp->_ptr = _FP_BASE( fp ) + fp->_bufsize - 1; fp->_flag |= _UNGET; /* 10-mar-90 */ *fp->_ptr = c; } else if( fp->_ptr != _FP_BASE( fp ) ) { fp->_cnt++; fp->_ptr--; if( *fp->_ptr != c ) { fp->_flag |= _UNGET; /* 10-mar-90 */ } *fp->_ptr = c; } else { /* read buffer is full */ _ReleaseFile( fp ); return( EOF ); } #endif fp->_flag &= ~ _EOF; _ReleaseFile( fp ); return( (UCHAR_TYPE)c ); }