size_t __LastFree( void ) /* used by nheapgrow to know about adjustment */ { frlptr p1; unsigned brk_value; if( __nheapbeg == NULL ) { /* no heap? can't have free blocks */ return( 0 ); } p1 = __nheapbeg->freehead.prev; /* point to last free block */ brk_value = (unsigned)((PTR)p1 + p1->len + TAG_SIZE ); #if defined(__DOS_EXT__) if( _IsPharLap() && !_IsFlashTek() ) _curbrk = SegmentLimit(); #endif if( brk_value == _curbrk ) { /* if last free block is at the end */ return( p1->len ); } return( 0 ); }
int __ExpandDGROUP( unsigned amount ) { #if defined(__WINDOWS__) || defined(__WARP__) || defined(__NT__) \ || defined(__CALL21__) || defined(__RDOS__) // first try to free any available storage _nheapshrink(); return( __CreateNewNHeap( amount ) ); #else mheapptr p1; frlptr flp; unsigned brk_value; tag *last_tag; unsigned new_brk_value; void _WCNEAR *brk_ret; #if defined(__DOS_EXT__) if( !__IsCtsNHeap() ) { return( __CreateNewNHeap( amount ) ); // Won't slice either } // Rational non-zero based system should go through. #endif if( !__heap_enabled ) return( 0 ); if( _curbrk == ~1u ) return( 0 ); if( __AdjustAmount( &amount ) == 0 ) return( 0 ); #if defined(__DOS_EXT__) if( _IsPharLap() && !_IsFlashTek() ) { _curbrk = SegmentLimit(); } #endif new_brk_value = amount + _curbrk; if( new_brk_value < _curbrk ) { new_brk_value = ~1u; } brk_ret = __brk( new_brk_value ); if( brk_ret == (void _WCNEAR *)-1 ) { return( 0 ); } brk_value = (unsigned)brk_ret; if( brk_value > /*0xfff8*/ ~7u ) { return( 0 ); } if( new_brk_value <= brk_value ) { return( 0 ); } amount = new_brk_value - brk_value; if( amount - TAG_SIZE > amount ) { return( 0 ); } else { amount -= TAG_SIZE; } for( p1 = __nheapbeg; p1 != NULL; p1 = p1->next ) { if( p1->next == NULL ) break; if( (unsigned)p1 <= brk_value && ((unsigned)p1) + p1->len + TAG_SIZE >= brk_value ) { break; } } if( (p1 != NULL) && ((brk_value - TAG_SIZE) == (unsigned)( (PTR)p1 + p1->len) ) ) { /* we are extending the previous heap block (slicing) */ /* nb. account for the end-of-heap tag */ brk_value -= TAG_SIZE; amount += TAG_SIZE; flp = (frlptr) brk_value; /* adjust current entry in heap list */ p1->len += amount; /* fix up end of heap links */ last_tag = (tag *) ( (PTR)flp + amount ); last_tag[0] = END_TAG; } else { if( amount < sizeof( miniheapblkp ) + sizeof( frl ) ) { /* there isn't enough for a heap block (struct miniheapblkp) and one free block (frl) */ return( 0 ); } // Initializing the near heap if __nheapbeg == NULL, // otherwise, a new mini-heap is getting linked up p1 = (mheapptr)brk_value; p1->len = amount; flp = __LinkUpNewMHeap( p1 ); amount = flp->len; } /* build a block for _nfree() */ SET_MEMBLK_SIZE_USED( flp, amount ); ++p1->numalloc; /* 28-dec-90 */ p1->largest_blk = ~0; /* set to largest value to be safe */ _nfree( (PTR)flp + TAG_SIZE ); return( 1 ); #endif }
static int __F_NAME(__sopen,__wsopen)( const CHAR_TYPE *name, int mode, int shflag, va_list args ) { int rwmode; int handle; int attr; int permission; unsigned iomode_flags; tiny_ret_t rc; char dummy; #ifdef __WIDECHAR__ char mbName[MB_CUR_MAX * _MAX_PATH]; /* single-byte char */ #endif handle = -1; rc = 0; while( *name == STRING( ' ' ) ) ++name; #ifdef __WIDECHAR__ /*** If necessary, convert the wide filename to multibyte form ***/ if( wcstombs( mbName, name, sizeof( mbName ) ) == -1 ) { mbName[0] = '\0'; } #endif rwmode = mode & ( O_RDONLY | O_WRONLY | O_RDWR | O_NOINHERIT ); if( _dos_open( __F_NAME(name,mbName), rwmode | shflag, &handle ) == 0 ) { if( handle >= __NFiles ) { TinyClose( handle ); __set_errno( EMFILE ); return( -1 ); } } /* 17-apr-90 05-sep-91 */ if( (mode & (O_RDONLY | O_WRONLY | O_RDWR)) != O_RDONLY ) { if( handle != -1 ) { if( ! isatty( handle ) ) { /* if not a device */ #if 0 rc = TinyAccess( name, 0 ); /* check for existence */ if( TINY_ERROR( rc ) ) { /* file does not exist */ TinyClose( handle ); /* close whatever file we got */ handle = -1; } else if( mode & O_EXCL ) { /* must not exist */ #else /* Don't need to do the access check, since the file was opened and therefore must exist (TinyOpen can't create a file). We don't want to do the check because there are classes of items in the file system namespace that are not devices, but the TinyAccess will fail on (e.g. named pipes). */ /* must not exist if O_CREAT specified */ if( (mode & O_EXCL) && (mode & O_CREAT) ) { #endif TinyClose( handle ); __set_errno( EEXIST ); return( -1 ); } else if( mode & O_TRUNC ) { /* truncate file */ rc = TinyWrite( handle, &dummy, 0 ); if( TINY_ERROR( rc ) ) { TinyClose( handle ); return( __set_errno_dos( TINY_INFO( rc ) ) ); } } } } } if( handle == -1 ) { /* could not open */ if( (mode & O_CREAT) == 0 || _RWD_doserrno != E_nofile ) { return( -1 ); } /* creating the file */ permission = va_arg( args, int ); va_end( args ); if( permission == 0 ) permission = S_IWRITE | S_IREAD; permission &= ~_RWD_umaskval; /* 05-jan-95 */ attr = 0; if(( permission & S_IWRITE) == 0 ) attr = _A_RDONLY; #if 0 /* remove this support because it is not consistently available */ if( _RWD_osmajor >= 5 #ifdef __DOS_EXT__ && !_IsFlashTek() && !_IsRational() #endif ) { /* this function is only available in version DOS 5 and up */ /* this new way was added to handle the case of creating a */ /* new file with read-only access, but with a writeable */ /* file handle */ #ifdef __WIDECHAR__ rc = TinyCreateEx( mbName, rwmode|shflag, attr, TIO_OPEN ); #else rc = TinyCreateEx( name, rwmode|shflag, attr, TIO_OPEN ); #endif if( TINY_ERROR( rc ) ) { return( __set_errno_dos( TINY_INFO( rc ) ) ); } handle = TINY_INFO( rc ); } else #endif { /* do it the old way */ if( _dos_creat( __F_NAME(name,mbName), attr, &handle ) ) { return( -1 ); } if( handle >= __NFiles ) { TinyClose( handle ); __set_errno( EMFILE ); return( -1 ); } /* 21-nov-90 AFS: the file is created so now the file must be */ /* opened with the correct share permissions */ if( shflag != 0 ) { rc = TinyClose( handle ); if( TINY_ERROR( rc ) ) { return( __set_errno_dos( TINY_INFO( rc ) ) ); } if( _dos_open( __F_NAME(name,mbName), rwmode | shflag, &handle ) ) { return( -1 ); } /* handle does not equal -1 now */ } } } iomode_flags = __GetIOMode( handle ); iomode_flags &= ~(_READ|_WRITE|_APPEND|_BINARY); /* 11-aug-88 */ if( isatty( handle ) ) iomode_flags |= _ISTTY; rwmode &= ~O_NOINHERIT; if( rwmode == O_RDWR ) iomode_flags |= _READ | _WRITE; if( rwmode == O_RDONLY) iomode_flags |= _READ; if( rwmode == O_WRONLY) iomode_flags |= _WRITE; if( mode & O_APPEND ) iomode_flags |= _APPEND; if( mode & (O_BINARY|O_TEXT) ) { if( mode & O_BINARY ) iomode_flags |= _BINARY; } else { if( _RWD_fmode == O_BINARY ) iomode_flags |= _BINARY; } __SetIOMode( handle, iomode_flags ); #ifdef DEFAULT_WINDOWING if( _WindowsNewWindow != 0 ) { if( !__F_NAME(stricmp,wcscmp)( name, STRING( "con" ) ) ) { _WindowsNewWindow( NULL, handle, -1 ); } } #endif return( handle ); } #if 0 /* couldn't find any user; please re-enable if it's necessary */ #ifndef __WIDECHAR__ /* compile one version only */ int __set_binary( int handle ) { unsigned iomode_flags; __ChkTTYIOMode( handle ); iomode_flags = __GetIOMode( handle ); iomode_flags |= _BINARY; __SetIOMode( handle, iomode_flags ); if( iomode_flags & _ISTTY ) { tiny_ret_t rc; rc = TinyGetDeviceInfo( handle ); if( TINY_ERROR( rc ) ) { return( __set_errno_dos( TINY_INFO( rc ) ) ); } rc = TinySetDeviceInfo( handle, TINY_INFO(rc) | TIO_CTL_RAW ); if( TINY_ERROR( rc ) ) { return( __set_errno_dos( TINY_INFO( rc ) ) ); } } return( 0 ); }