Пример #1
0
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 );
}
Пример #2
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
}
Пример #3
0
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 );
}