1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
* This file is part of the Linux-8086 C library and is distributed
* under the GNU Library General Public License.
*/
#include <errno.h>
/****************************************************************************/
#ifdef L_errno
int errno = 0; /* libc error value */
#endif
/****************************************************************************/
#ifdef __AS386_16__
#ifdef L___brk_addr
#asm
.data
export brk_addr
brk_addr: .word __end ! This holds the current return for sbrk(0)
.text
#endasm
#endif
/****************************************************************************/
#ifdef L_sbrk
int sbrk(brk_off)
int brk_off;
{
#asm
mov bx,sp
#if !__FIRST_ARG_IN_AX__
mov ax,[bx+2] ! Fetch the requested value
#endif
test ax,ax
jnz has_change
mov ax,[brk_addr] ! Simple one, read current - can`t fail.
jmp eof
has_change:
js go_down
add ax,[brk_addr] ! Goin up!
jc Enomem
sub bx,#511 ! Safety space 512 bytes
cmp bx,ax ! Too close ?
jb Enomem
sbrk_ok:
#if !defined(__MSDOS__) && !defined(__STANDALONE__)
push ax ! MSDOS `kernel` doesn`t care
call ___brk ! Tell the kernel
test ax,ax
pop ax ! ASSUME ___brk doesn`t alter stack!
jnz Enomem ! Ugh! kernel didn`t like the idea!
#endif
xchg [brk_addr],ax ! Save away new val
jmp eof ! Return it
go_down:
add ax,[brk_addr]
jnc Enomem
cmp ax,#__end
jae sbrk_ok
Enomem:
mov ax,#12 ! This should be ENOMEM not a magic.
mov [_errno],ax
mov ax,#-1
eof:
#endasm
}
#endif
/****************************************************************************/
#ifdef L_brk
int
brk(new_brk)
char * new_brk;
{
#asm
mov bx,sp
#if !__FIRST_ARG_IN_AX__
mov ax,[bx+2] ! Fetch the requested value
#endif
sub bx,#512 ! Safety space 512 bytes
cmp bx,ax ! Too close ?
jb Enomem
cmp ax,#__end
jae brk_ok
Enomem:
mov ax,#12 ! This should be ENOMEM not a magic.
mov [_errno],ax
mov ax,#-1
ret
brk_ok:
#if !defined(__MSDOS__) && !defined(__STANDALONE__)
push ax
call ___brk ! Tell the kernel
test ax,ax
pop bx ! ASSUME ___brk doesn`t alter stack!
jnz Enomem ! Ugh! kernel didn`t like the idea!
mov [brk_addr],bx ! Save away new val
#else
mov [brk_addr],ax ! MSDOS `kernel` doesn`t care
mov ax,#0
#endif
#endasm
}
#endif
#endif
/****************************************************************************/
#ifdef __AS386_32__
extern char * __brk_addr;
extern char * __brk();
#ifdef L___brk_addr
char * __brk_addr = 0; /* This holds the current return for sbrk(0) */
char *
__brk(val)
{
#asm
#if __FIRST_ARG_IN_AX__
mov ebx,eax
#else
mov ebx,[esp+4]
#endif
mov eax,#45
int $80
#endasm
}
__brk_addr_init()
{
if( __brk_addr == 0 && (__brk_addr = __brk(0)) == 0 )
{
errno = ENOMEM;
return -1;
}
return 0;
}
#endif
#ifdef L_sbrk
char *
sbrk(brk_off)
int brk_off;
{
char * new_brk;
if( __brk_addr_init() ) return (char*)-1;
if( brk_off == 0 ) return __brk_addr;
new_brk = __brk_addr + brk_off;
__brk_addr = __brk(new_brk);
if( __brk_addr != new_brk )
{
errno = ENOMEM;
return (char*)-1;
}
return __brk_addr - brk_off;
}
#endif
#ifdef L_brk
int
brk(new_brk)
char * new_brk;
{
if( __brk_addr_init() ) return -1;
__brk_addr = __brk(new_brk);
if( __brk_addr == new_brk ) return 0;
errno = ENOMEM;
return -1;
}
#endif
#endif
|