sbrk386.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 191 行
C
191 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Implementation of sbrk() for DOS, OS/2 and Windows.
*
****************************************************************************/
#include "variety.h"
#include <stddef.h>
#include <stdlib.h>
#include <errno.h>
#include <dos.h>
#ifdef __WINDOWS_386__
#include "tinyio.h"
#else
#include "extender.h"
#if defined(__OS2__)
#include <wos2.h>
#else
#include "tinyio.h"
#endif
#endif
extern unsigned _curbrk;
extern unsigned _STACKTOP;
#ifdef __WINDOWS_386__
extern void * pascal DPMIAlloc( unsigned long );
#else
extern int SetBlock( unsigned short selector, int size );
#pragma aux SetBlock = \
"push es" \
"mov es,ax" \
"mov ah,04ah" \
"int 021h" \
"rcl eax,1" \
"ror eax,1" \
"pop es" \
parm caller [ax] [ebx] \
modify [ebx] \
value [eax];
extern int SegInfo( unsigned short selector );
#pragma aux SegInfo = \
"mov ah,0edH" \
"int 021h" \
"shl eax,31" \
"and edi,0000FFFFh" \
"or edi,eax" \
parm caller [ebx] \
value [edi] \
modify exact [eax ecx edx esi ebx edi];
extern int SegmentLimit( void );
#pragma aux SegmentLimit = \
"xor eax,eax" \
"mov ax,ds" \
"lsl eax,ax" \
"inc eax" \
value [eax] \
modify exact [eax];
#endif
extern unsigned short GetDS( void );
#pragma aux GetDS = \
"mov ax,ds" \
value [ax];
_WCRTLINK void _WCNEAR *__brk( unsigned brk_value );
_WCRTLINK void _WCNEAR *sbrk( int increment )
{
#if defined(__OS2__)
if( increment > 0 ) {
PBYTE p;
increment = ( increment + 0x0fff ) & ~0x0fff;
if( !DosAllocMem( &p, increment, PAG_COMMIT|PAG_READ|PAG_WRITE ) ) {
return( p );
}
errno = ENOMEM;
} else {
errno = EINVAL;
}
return( (void _WCNEAR *) -1 );
#elif defined(__WINDOWS_386__) /* 26-may-93 */
increment = ( increment + 0x0fff ) & ~0x0fff;
return DPMIAlloc( increment );
#elif defined(__CALL21__) /* 10-aug-93 */
increment = ( increment + 0x0fff ) & ~0x0fff;
return (void *)TinyMemAlloc( increment );
#else
if( _IsRationalZeroBase() || _IsCodeBuilder() ) {
void _WCNEAR *p;
if( increment > 0 ) {
increment = ( increment + 0x0fff ) & ~0x0fff;
if( _IsRational() ) {
p = TinyDPMIAlloc( increment );
} else {
p = TinyCBAlloc( increment );
}
if( p == NULL ) {
errno = ENOMEM;
p = (void _WCNEAR *) -1;
}
} else {
errno = EINVAL;
p = (void _WCNEAR *) -1;
}
return( p );
} else if( _IsPharLap() ) { /* 17-sep-93 */
_curbrk = SegmentLimit();
}
return( __brk( _curbrk + increment ) );
#endif
}
#if !defined(__OS2__) && !defined(__WINDOWS_386__)
_WCRTLINK void _WCNEAR *__brk( unsigned brk_value )
{
unsigned old_brk_value;
#if !defined(__CALL21__)
unsigned seg;
int parent;
#endif
if( brk_value < _STACKTOP ) {
errno = ENOMEM;
return( (void _WCNEAR *) -1 );
}
#if !defined(__CALL21__)
if( _IsOS386() ) {
seg = ( brk_value + 15U ) / 16U;
if( seg == 0 ) seg = 0x0FFFFFFF; /* 26-sep-89 */
parent = SegInfo( GetDS() );
if( parent < 0 ) {
if( SetBlock( parent & 0xffff, seg ) < 0 ) {
errno = ENOMEM;
return( (void _WCNEAR *) -1 );
}
}
if( SetBlock( GetDS(), seg ) < 0 ) {
errno = ENOMEM;
return( (void _WCNEAR *) -1 );
}
} else { /* _IsPharLap() || IsRationalNonZeroBase() */
seg = ( brk_value + 4095U ) / 4096U;
if( seg == 0 ) seg = 0x000FFFFF; /* 26-sep-89 */
if( _IsRationalNonZeroBase() ) {
// convert from 4k pages to paragraphs
seg = seg * 256U;
}
if( SetBlock( GetDS(), seg ) < 0 ) {
errno = ENOMEM;
return( (void _WCNEAR *) -1 );
}
}
#endif
old_brk_value = _curbrk; /* return old value of _curbrk */
_curbrk = brk_value; /* set new break value */
return( (void _WCNEAR *) old_brk_value );
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?