1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*3e14f97fSRoger A. Faulkner * Copyright (c) 1985-2010 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6da2e3ebdSchin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt *
11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> *
18da2e3ebdSchin * David Korn <dgk@research.att.com> *
19da2e3ebdSchin * Phong Vo <kpv@research.att.com> *
20da2e3ebdSchin * *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #if defined(_UWIN) && defined(_BLD_ast)
23da2e3ebdSchin
_STUB_malloc()24da2e3ebdSchin void _STUB_malloc(){}
25da2e3ebdSchin
26da2e3ebdSchin #else
27da2e3ebdSchin
28da2e3ebdSchin #if _UWIN
29da2e3ebdSchin
30da2e3ebdSchin #define calloc ______calloc
31da2e3ebdSchin #define _ast_free ______free
32da2e3ebdSchin #define malloc ______malloc
33da2e3ebdSchin #define mallinfo ______mallinfo
34da2e3ebdSchin #define mallopt ______mallopt
35da2e3ebdSchin #define mstats ______mstats
36da2e3ebdSchin #define realloc ______realloc
37da2e3ebdSchin
38da2e3ebdSchin #define _STDLIB_H_ 1
39da2e3ebdSchin
40da2e3ebdSchin extern int atexit(void(*)(void));
41da2e3ebdSchin extern char* getenv(const char*);
42da2e3ebdSchin
43da2e3ebdSchin #endif
44da2e3ebdSchin
45da2e3ebdSchin #include "vmhdr.h"
4634f9b3eeSRoland Mainz #include <errno.h>
47da2e3ebdSchin
48da2e3ebdSchin #if _UWIN
49da2e3ebdSchin
50da2e3ebdSchin #include <malloc.h>
51da2e3ebdSchin
52da2e3ebdSchin #define _map_malloc 1
53da2e3ebdSchin #define _mal_alloca 1
54da2e3ebdSchin
55da2e3ebdSchin #undef calloc
56da2e3ebdSchin #define calloc _ast_calloc
57da2e3ebdSchin #undef _ast_free
58da2e3ebdSchin #define free _ast_free
59da2e3ebdSchin #undef malloc
60da2e3ebdSchin #define malloc _ast_malloc
61da2e3ebdSchin #undef mallinfo
62da2e3ebdSchin typedef struct ______mallinfo Mallinfo_t;
63da2e3ebdSchin #undef mallopt
64da2e3ebdSchin #undef mstats
65da2e3ebdSchin typedef struct ______mstats Mstats_t;
66da2e3ebdSchin #undef realloc
67da2e3ebdSchin #define realloc _ast_realloc
68da2e3ebdSchin
69da2e3ebdSchin #endif
70da2e3ebdSchin
71da2e3ebdSchin #if __STD_C
72da2e3ebdSchin #define F0(f,t0) f(t0)
73da2e3ebdSchin #define F1(f,t1,a1) f(t1 a1)
74da2e3ebdSchin #define F2(f,t1,a1,t2,a2) f(t1 a1, t2 a2)
75da2e3ebdSchin #else
76da2e3ebdSchin #define F0(f,t0) f()
77da2e3ebdSchin #define F1(f,t1,a1) f(a1) t1 a1;
78da2e3ebdSchin #define F2(f,t1,a1,t2,a2) f(a1, a2) t1 a1; t2 a2;
79da2e3ebdSchin #endif
80da2e3ebdSchin
81da2e3ebdSchin /*
82da2e3ebdSchin * define _AST_std_malloc=1 to force the standard malloc
83da2e3ebdSchin * if _map_malloc is also defined then _ast_malloc etc.
84da2e3ebdSchin * will simply call malloc etc.
85da2e3ebdSchin */
86da2e3ebdSchin
87da2e3ebdSchin #if !defined(_AST_std_malloc) && __CYGWIN__
88da2e3ebdSchin #define _AST_std_malloc 1
89da2e3ebdSchin #endif
90da2e3ebdSchin
91*3e14f97fSRoger A. Faulkner /* malloc compatibility functions
92da2e3ebdSchin **
93*3e14f97fSRoger A. Faulkner ** These are aware of debugging/profiling and are driven by the
94*3e14f97fSRoger A. Faulkner ** VMALLOC_OPTIONS environment variable which is a space-separated
95*3e14f97fSRoger A. Faulkner ** list of [no]name[=value] options:
96da2e3ebdSchin **
97*3e14f97fSRoger A. Faulkner ** abort if Vmregion==Vmdebug then VM_DBABORT is set,
98*3e14f97fSRoger A. Faulkner ** otherwise _BLD_debug enabled assertions abort()
99*3e14f97fSRoger A. Faulkner ** on failure
100*3e14f97fSRoger A. Faulkner ** check if Vmregion==Vmbest then the region is checked every op
101*3e14f97fSRoger A. Faulkner ** method=m sets Vmregion=m if not defined, m (Vm prefix optional)
102*3e14f97fSRoger A. Faulkner ** may be one of { best debug last profile }
103*3e14f97fSRoger A. Faulkner ** mmap prefer mmap() over brk() for region allocation
104*3e14f97fSRoger A. Faulkner ** period=n sets Vmregion=Vmdebug if not defined, if
105*3e14f97fSRoger A. Faulkner ** Vmregion==Vmdebug the region is checked every n ops
106*3e14f97fSRoger A. Faulkner ** profile=f sets Vmregion=Vmprofile if not set, if
107*3e14f97fSRoger A. Faulkner ** Vmregion==Vmprofile then profile info printed to file f
108*3e14f97fSRoger A. Faulkner ** region if Vmregion==Vmbest then block free verifies
109*3e14f97fSRoger A. Faulkner ** that the block belongs to the region
110*3e14f97fSRoger A. Faulkner ** start=n sets Vmregion=Vmdebug if not defined, if
111*3e14f97fSRoger A. Faulkner ** Vmregion==Vmdebug region checking starts after n ops
112*3e14f97fSRoger A. Faulkner ** trace=f enables tracing to file f
113*3e14f97fSRoger A. Faulkner ** warn=f sets Vmregion=Vmdebug if not defined, if
114*3e14f97fSRoger A. Faulkner ** Vmregion==Vmdebug then warnings printed to file f
115*3e14f97fSRoger A. Faulkner ** watch=a sets Vmregion=Vmdebug if not defined, if
116*3e14f97fSRoger A. Faulkner ** Vmregion==Vmdebug then address a is watched
117*3e14f97fSRoger A. Faulkner **
118*3e14f97fSRoger A. Faulkner ** Output files are created if they don't exist. &n and /dev/fd/n name
119*3e14f97fSRoger A. Faulkner ** the file descriptor n which must be open for writing. The pattern %p
120*3e14f97fSRoger A. Faulkner ** in a file name is replaced by the process ID.
121*3e14f97fSRoger A. Faulkner **
122*3e14f97fSRoger A. Faulkner ** VMALLOC_OPTIONS combines the features of these previously used env vars:
123*3e14f97fSRoger A. Faulkner ** { VMDEBUG VMETHOD VMPROFILE VMTRACE }
124da2e3ebdSchin **
125da2e3ebdSchin ** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
126da2e3ebdSchin */
127da2e3ebdSchin
128da2e3ebdSchin #if _sys_stat
129da2e3ebdSchin #include <sys/stat.h>
130da2e3ebdSchin #endif
131da2e3ebdSchin #include <fcntl.h>
132da2e3ebdSchin
133da2e3ebdSchin #ifdef S_IRUSR
134da2e3ebdSchin #define CREAT_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
135da2e3ebdSchin #else
136da2e3ebdSchin #define CREAT_MODE 0644
137da2e3ebdSchin #endif
138da2e3ebdSchin
139*3e14f97fSRoger A. Faulkner static Vmulong_t _Vmdbstart = 0;
140*3e14f97fSRoger A. Faulkner static Vmulong_t _Vmdbcheck = 0;
141*3e14f97fSRoger A. Faulkner static Vmulong_t _Vmdbtime = 0;
142*3e14f97fSRoger A. Faulkner static int _Vmpffd = -1;
143*3e14f97fSRoger A. Faulkner
144*3e14f97fSRoger A. Faulkner #if ( !_std_malloc || !_BLD_ast ) && !_AST_std_malloc
145*3e14f97fSRoger A. Faulkner
146da2e3ebdSchin #if !_map_malloc
147da2e3ebdSchin #undef calloc
148da2e3ebdSchin #undef cfree
149da2e3ebdSchin #undef free
150da2e3ebdSchin #undef mallinfo
151da2e3ebdSchin #undef malloc
152da2e3ebdSchin #undef mallopt
153da2e3ebdSchin #undef memalign
154da2e3ebdSchin #undef mstats
155da2e3ebdSchin #undef realloc
156da2e3ebdSchin #undef valloc
157da2e3ebdSchin #endif
158da2e3ebdSchin
159da2e3ebdSchin #if _WINIX
160da2e3ebdSchin
161da2e3ebdSchin #include <ast_windows.h>
162da2e3ebdSchin
163da2e3ebdSchin #if _UWIN
164da2e3ebdSchin
165da2e3ebdSchin #define VMRECORD(p) _vmrecord(p)
166da2e3ebdSchin #define VMBLOCK { int _vmblock = _sigblock();
167da2e3ebdSchin #define VMUNBLOCK _sigunblock(_vmblock); }
168da2e3ebdSchin
169da2e3ebdSchin extern int _sigblock(void);
170da2e3ebdSchin extern void _sigunblock(int);
171da2e3ebdSchin extern unsigned long _record[2048];
172da2e3ebdSchin
_vmrecord(Void_t * p)173da2e3ebdSchin __inline Void_t* _vmrecord(Void_t* p)
174da2e3ebdSchin {
175da2e3ebdSchin register unsigned long v = ((unsigned long)p)>>16;
176da2e3ebdSchin
177da2e3ebdSchin _record[v>>5] |= 1<<((v&0x1f));
178da2e3ebdSchin return p;
179da2e3ebdSchin }
180da2e3ebdSchin
181da2e3ebdSchin #else
182da2e3ebdSchin
183da2e3ebdSchin #define getenv(s) lcl_getenv(s)
184da2e3ebdSchin
185da2e3ebdSchin static char*
lcl_getenv(const char * s)186da2e3ebdSchin lcl_getenv(const char* s)
187da2e3ebdSchin {
188da2e3ebdSchin int n;
189da2e3ebdSchin static char buf[512];
190da2e3ebdSchin
191da2e3ebdSchin if (!(n = GetEnvironmentVariable(s, buf, sizeof(buf))) || n > sizeof(buf))
192da2e3ebdSchin return 0;
193da2e3ebdSchin return buf;
194da2e3ebdSchin }
195da2e3ebdSchin
196da2e3ebdSchin #endif /* _UWIN */
197da2e3ebdSchin
198da2e3ebdSchin #endif /* _WINIX */
199da2e3ebdSchin
200da2e3ebdSchin #ifndef VMRECORD
201da2e3ebdSchin #define VMRECORD(p) (p)
202da2e3ebdSchin #define VMBLOCK
203da2e3ebdSchin #define VMUNBLOCK
204da2e3ebdSchin #endif
205da2e3ebdSchin
206da2e3ebdSchin #if defined(__EXPORT__)
207da2e3ebdSchin #define extern extern __EXPORT__
208da2e3ebdSchin #endif
209da2e3ebdSchin
210da2e3ebdSchin static int _Vmflinit = 0;
211da2e3ebdSchin #define VMFLINIT() \
212da2e3ebdSchin { if(!_Vmflinit) vmflinit(); \
213da2e3ebdSchin if(_Vmdbcheck) \
214da2e3ebdSchin { if(_Vmdbtime < _Vmdbstart) _Vmdbtime += 1; \
215da2e3ebdSchin else if((_Vmdbtime += 1) < _Vmdbstart) _Vmdbtime = _Vmdbstart; \
216da2e3ebdSchin if(_Vmdbtime >= _Vmdbstart && (_Vmdbtime % _Vmdbcheck) == 0 && \
217da2e3ebdSchin Vmregion->meth.meth == VM_MTDEBUG) \
218da2e3ebdSchin vmdbcheck(Vmregion); \
219da2e3ebdSchin } \
220da2e3ebdSchin }
221da2e3ebdSchin
222da2e3ebdSchin #if __STD_C
vmflinit(void)223da2e3ebdSchin static int vmflinit(void)
224da2e3ebdSchin #else
225da2e3ebdSchin static int vmflinit()
226da2e3ebdSchin #endif
227da2e3ebdSchin {
228da2e3ebdSchin char* file;
229da2e3ebdSchin int line;
230da2e3ebdSchin Void_t* func;
231da2e3ebdSchin
232da2e3ebdSchin /* this must be done now to avoid any inadvertent recursion (more below) */
233da2e3ebdSchin _Vmflinit = 1;
234da2e3ebdSchin VMFLF(Vmregion,file,line,func);
235da2e3ebdSchin
236*3e14f97fSRoger A. Faulkner /* if getenv() calls malloc(), the options may not affect the eventual region */
237*3e14f97fSRoger A. Faulkner VMOPTIONS();
238da2e3ebdSchin
239da2e3ebdSchin /* reset file and line number to correct values for the call */
240da2e3ebdSchin Vmregion->file = file;
241da2e3ebdSchin Vmregion->line = line;
242da2e3ebdSchin Vmregion->func = func;
243da2e3ebdSchin
244da2e3ebdSchin return 0;
245da2e3ebdSchin }
246da2e3ebdSchin
247da2e3ebdSchin #if __STD_C
calloc(reg size_t n_obj,reg size_t s_obj)248da2e3ebdSchin extern Void_t* calloc(reg size_t n_obj, reg size_t s_obj)
249da2e3ebdSchin #else
250da2e3ebdSchin extern Void_t* calloc(n_obj, s_obj)
251da2e3ebdSchin reg size_t n_obj;
252da2e3ebdSchin reg size_t s_obj;
253da2e3ebdSchin #endif
254da2e3ebdSchin {
255da2e3ebdSchin VMFLINIT();
256da2e3ebdSchin return VMRECORD((*Vmregion->meth.resizef)(Vmregion,NIL(Void_t*),n_obj*s_obj,VM_RSZERO));
257da2e3ebdSchin }
258da2e3ebdSchin
259da2e3ebdSchin #if __STD_C
malloc(reg size_t size)260da2e3ebdSchin extern Void_t* malloc(reg size_t size)
261da2e3ebdSchin #else
262da2e3ebdSchin extern Void_t* malloc(size)
263da2e3ebdSchin reg size_t size;
264da2e3ebdSchin #endif
265da2e3ebdSchin {
266da2e3ebdSchin VMFLINIT();
267da2e3ebdSchin return VMRECORD((*Vmregion->meth.allocf)(Vmregion,size));
268da2e3ebdSchin }
269da2e3ebdSchin
270da2e3ebdSchin #if __STD_C
realloc(reg Void_t * data,reg size_t size)271da2e3ebdSchin extern Void_t* realloc(reg Void_t* data, reg size_t size)
272da2e3ebdSchin #else
273da2e3ebdSchin extern Void_t* realloc(data,size)
274da2e3ebdSchin reg Void_t* data; /* block to be reallocated */
275da2e3ebdSchin reg size_t size; /* new size */
276da2e3ebdSchin #endif
277da2e3ebdSchin {
278da2e3ebdSchin #if USE_NATIVE
279da2e3ebdSchin #undef realloc
280da2e3ebdSchin #if __STD_C
281da2e3ebdSchin extern Void_t* realloc(Void_t*, size_t);
282da2e3ebdSchin #else
283da2e3ebdSchin extern Void_t* realloc();
284da2e3ebdSchin #endif
285da2e3ebdSchin #endif
286da2e3ebdSchin
287da2e3ebdSchin VMFLINIT();
288da2e3ebdSchin
289da2e3ebdSchin #if _PACKAGE_ast
290da2e3ebdSchin if(data && Vmregion->meth.meth != VM_MTDEBUG &&
291da2e3ebdSchin #if !USE_NATIVE
292da2e3ebdSchin !(Vmregion->data->mode&VM_TRUST) &&
293da2e3ebdSchin #endif
294da2e3ebdSchin (*Vmregion->meth.addrf)(Vmregion,data) != 0 )
295da2e3ebdSchin {
296da2e3ebdSchin #if USE_NATIVE
297da2e3ebdSchin return realloc(data, size);
298da2e3ebdSchin #else
299da2e3ebdSchin Void_t* newdata;
300da2e3ebdSchin if((newdata = (*Vmregion->meth.allocf)(Vmregion,size)) )
301da2e3ebdSchin memcpy(newdata,data,size);
302da2e3ebdSchin return VMRECORD(newdata);
303da2e3ebdSchin #endif
304da2e3ebdSchin }
305da2e3ebdSchin #endif
306da2e3ebdSchin
307da2e3ebdSchin #if USE_NATIVE
308da2e3ebdSchin { Void_t* newdata;
309da2e3ebdSchin if (newdata = (*Vmregion->meth.resizef)(Vmregion,data,size,VM_RSCOPY|VM_RSMOVE))
310da2e3ebdSchin return newdata;
311da2e3ebdSchin return VMRECORD(realloc(data, size));
312da2e3ebdSchin }
313da2e3ebdSchin #else
314da2e3ebdSchin return VMRECORD((*Vmregion->meth.resizef)(Vmregion,data,size,VM_RSCOPY|VM_RSMOVE));
315da2e3ebdSchin #endif
316da2e3ebdSchin }
317da2e3ebdSchin
318da2e3ebdSchin #if __STD_C
free(reg Void_t * data)319da2e3ebdSchin extern void free(reg Void_t* data)
320da2e3ebdSchin #else
321da2e3ebdSchin extern void free(data)
322da2e3ebdSchin reg Void_t* data;
323da2e3ebdSchin #endif
324da2e3ebdSchin {
325da2e3ebdSchin #if USE_NATIVE
326da2e3ebdSchin #undef free
327da2e3ebdSchin #if __STD_C
328da2e3ebdSchin extern void free(Void_t*);
329da2e3ebdSchin #else
330da2e3ebdSchin extern void free();
331da2e3ebdSchin #endif
332da2e3ebdSchin #endif
333da2e3ebdSchin
334da2e3ebdSchin VMFLINIT();
335da2e3ebdSchin
336da2e3ebdSchin #if _PACKAGE_ast
337da2e3ebdSchin if(data && Vmregion->meth.meth != VM_MTDEBUG &&
338da2e3ebdSchin #if !USE_NATIVE
339da2e3ebdSchin !(Vmregion->data->mode&VM_TRUST) &&
340da2e3ebdSchin #endif
341da2e3ebdSchin (*Vmregion->meth.addrf)(Vmregion,data) != 0)
342da2e3ebdSchin {
343da2e3ebdSchin #if USE_NATIVE
344da2e3ebdSchin free(data);
345da2e3ebdSchin #endif
346da2e3ebdSchin return;
347da2e3ebdSchin }
348da2e3ebdSchin #endif
349da2e3ebdSchin
350da2e3ebdSchin #if USE_NATIVE
351da2e3ebdSchin if ((*Vmregion->meth.freef)(Vmregion,data) != 0)
352da2e3ebdSchin free(data);
353da2e3ebdSchin #else
354da2e3ebdSchin (void)(*Vmregion->meth.freef)(Vmregion,data);
355da2e3ebdSchin #endif
356da2e3ebdSchin }
357da2e3ebdSchin
358da2e3ebdSchin #if __STD_C
cfree(reg Void_t * data)359da2e3ebdSchin extern void cfree(reg Void_t* data)
360da2e3ebdSchin #else
361da2e3ebdSchin extern void cfree(data)
362da2e3ebdSchin reg Void_t* data;
363da2e3ebdSchin #endif
364da2e3ebdSchin {
365da2e3ebdSchin free(data);
366da2e3ebdSchin }
367da2e3ebdSchin
368da2e3ebdSchin #if __STD_C
memalign(reg size_t align,reg size_t size)369da2e3ebdSchin extern Void_t* memalign(reg size_t align, reg size_t size)
370da2e3ebdSchin #else
371da2e3ebdSchin extern Void_t* memalign(align, size)
372da2e3ebdSchin reg size_t align;
373da2e3ebdSchin reg size_t size;
374da2e3ebdSchin #endif
375da2e3ebdSchin {
376da2e3ebdSchin Void_t* addr;
377da2e3ebdSchin
378da2e3ebdSchin VMFLINIT();
379da2e3ebdSchin VMBLOCK
380da2e3ebdSchin addr = VMRECORD((*Vmregion->meth.alignf)(Vmregion,size,align));
381da2e3ebdSchin VMUNBLOCK
382da2e3ebdSchin return addr;
383da2e3ebdSchin }
384da2e3ebdSchin
385da2e3ebdSchin #if __STD_C
posix_memalign(reg Void_t ** memptr,reg size_t align,reg size_t size)38634f9b3eeSRoland Mainz extern int posix_memalign(reg Void_t **memptr, reg size_t align, reg size_t size)
38734f9b3eeSRoland Mainz #else
38834f9b3eeSRoland Mainz extern int posix_memalign(memptr, align, size)
38934f9b3eeSRoland Mainz reg Void_t** memptr;
39034f9b3eeSRoland Mainz reg size_t align;
39134f9b3eeSRoland Mainz reg size_t size;
39234f9b3eeSRoland Mainz #endif
39334f9b3eeSRoland Mainz {
39434f9b3eeSRoland Mainz Void_t *mem;
39534f9b3eeSRoland Mainz
39634f9b3eeSRoland Mainz if(align == 0 || (align%sizeof(Void_t*)) != 0 || ((align-1)&align) != 0 )
39734f9b3eeSRoland Mainz return EINVAL;
39834f9b3eeSRoland Mainz
39934f9b3eeSRoland Mainz if(!(mem = memalign(align, size)) )
40034f9b3eeSRoland Mainz return ENOMEM;
40134f9b3eeSRoland Mainz
40234f9b3eeSRoland Mainz *memptr = mem;
40334f9b3eeSRoland Mainz return 0;
40434f9b3eeSRoland Mainz }
40534f9b3eeSRoland Mainz
40634f9b3eeSRoland Mainz #if __STD_C
valloc(reg size_t size)407da2e3ebdSchin extern Void_t* valloc(reg size_t size)
408da2e3ebdSchin #else
409da2e3ebdSchin extern Void_t* valloc(size)
410da2e3ebdSchin reg size_t size;
411da2e3ebdSchin #endif
412da2e3ebdSchin {
413da2e3ebdSchin VMFLINIT();
414da2e3ebdSchin GETPAGESIZE(_Vmpagesize);
415da2e3ebdSchin return VMRECORD((*Vmregion->meth.alignf)(Vmregion,size,_Vmpagesize));
416da2e3ebdSchin }
417da2e3ebdSchin
418da2e3ebdSchin #if __STD_C
pvalloc(reg size_t size)419da2e3ebdSchin extern Void_t* pvalloc(reg size_t size)
420da2e3ebdSchin #else
421da2e3ebdSchin extern Void_t* pvalloc(size)
422da2e3ebdSchin reg size_t size;
423da2e3ebdSchin #endif
424da2e3ebdSchin {
425da2e3ebdSchin VMFLINIT();
426da2e3ebdSchin GETPAGESIZE(_Vmpagesize);
427da2e3ebdSchin return VMRECORD((*Vmregion->meth.alignf)(Vmregion,ROUND(size,_Vmpagesize),_Vmpagesize));
428da2e3ebdSchin }
429da2e3ebdSchin
430da2e3ebdSchin #if !_PACKAGE_ast
431da2e3ebdSchin #if __STD_C
strdup(const char * s)432da2e3ebdSchin char* strdup(const char* s)
433da2e3ebdSchin #else
434da2e3ebdSchin char* strdup(s)
435da2e3ebdSchin char* s;
436da2e3ebdSchin #endif
437da2e3ebdSchin {
438da2e3ebdSchin char *ns;
439da2e3ebdSchin size_t n;
440da2e3ebdSchin
441da2e3ebdSchin if(!s)
442da2e3ebdSchin return NIL(char*);
443da2e3ebdSchin else
444da2e3ebdSchin { n = strlen(s);
445da2e3ebdSchin if((ns = malloc(n+1)) )
446da2e3ebdSchin memcpy(ns,s,n+1);
447da2e3ebdSchin return ns;
448da2e3ebdSchin }
449da2e3ebdSchin }
450da2e3ebdSchin #endif /* _PACKAGE_ast */
451da2e3ebdSchin
452da2e3ebdSchin #if !_lib_alloca || _mal_alloca
453da2e3ebdSchin #ifndef _stk_down
454da2e3ebdSchin #define _stk_down 0
455da2e3ebdSchin #endif
456da2e3ebdSchin typedef struct _alloca_s Alloca_t;
457da2e3ebdSchin union _alloca_u
458da2e3ebdSchin { struct
459da2e3ebdSchin { char* addr;
460da2e3ebdSchin Alloca_t* next;
461da2e3ebdSchin } head;
462da2e3ebdSchin char array[ALIGN];
463da2e3ebdSchin };
464da2e3ebdSchin struct _alloca_s
465da2e3ebdSchin { union _alloca_u head;
466da2e3ebdSchin Vmuchar_t data[1];
467da2e3ebdSchin };
468da2e3ebdSchin
469da2e3ebdSchin #if __STD_C
alloca(size_t size)470da2e3ebdSchin extern Void_t* alloca(size_t size)
471da2e3ebdSchin #else
472da2e3ebdSchin extern Void_t* alloca(size)
473da2e3ebdSchin size_t size;
474da2e3ebdSchin #endif
475da2e3ebdSchin { char array[ALIGN];
476da2e3ebdSchin char* file;
477da2e3ebdSchin int line;
478da2e3ebdSchin Void_t* func;
479da2e3ebdSchin reg Alloca_t* f;
480da2e3ebdSchin static Alloca_t* Frame;
481da2e3ebdSchin
482da2e3ebdSchin VMFLINIT();
483da2e3ebdSchin VMFLF(Vmregion,file,line,func);
484da2e3ebdSchin while(Frame)
485da2e3ebdSchin { if(( _stk_down && &array[0] > Frame->head.head.addr) ||
486da2e3ebdSchin (!_stk_down && &array[0] < Frame->head.head.addr) )
487da2e3ebdSchin { f = Frame;
488da2e3ebdSchin Frame = f->head.head.next;
489da2e3ebdSchin (void)(*Vmregion->meth.freef)(Vmregion,f);
490da2e3ebdSchin }
491da2e3ebdSchin else break;
492da2e3ebdSchin }
493da2e3ebdSchin
494da2e3ebdSchin Vmregion->file = file;
495da2e3ebdSchin Vmregion->line = line;
496da2e3ebdSchin Vmregion->func = func;
497da2e3ebdSchin f = (Alloca_t*)(*Vmregion->meth.allocf)(Vmregion,size+sizeof(Alloca_t)-1);
498da2e3ebdSchin
499da2e3ebdSchin f->head.head.addr = &array[0];
500da2e3ebdSchin f->head.head.next = Frame;
501da2e3ebdSchin Frame = f;
502da2e3ebdSchin
503da2e3ebdSchin return (Void_t*)f->data;
504da2e3ebdSchin }
505da2e3ebdSchin #endif /*!_lib_alloca || _mal_alloca*/
506da2e3ebdSchin
507da2e3ebdSchin #if _map_malloc
508da2e3ebdSchin
509da2e3ebdSchin /* not sure of all the implications -- 0 is conservative for now */
510da2e3ebdSchin #define USE_NATIVE 0 /* native free/realloc on non-vmalloc ptrs */
511da2e3ebdSchin
512da2e3ebdSchin #else
513da2e3ebdSchin
514da2e3ebdSchin /* intercept _* __* __libc_* variants */
515da2e3ebdSchin
516da2e3ebdSchin #if __lib__malloc
F2(_calloc,size_t,n,size_t,m)517da2e3ebdSchin extern Void_t* F2(_calloc, size_t,n, size_t,m) { return calloc(n, m); }
F1(_cfree,Void_t *,p)518da2e3ebdSchin extern Void_t F1(_cfree, Void_t*,p) { free(p); }
F1(_free,Void_t *,p)519da2e3ebdSchin extern Void_t F1(_free, Void_t*,p) { free(p); }
F1(_malloc,size_t,n)520da2e3ebdSchin extern Void_t* F1(_malloc, size_t,n) { return malloc(n); }
521da2e3ebdSchin #if _lib_memalign
F2(_memalign,size_t,a,size_t,n)522da2e3ebdSchin extern Void_t* F2(_memalign, size_t,a, size_t,n) { return memalign(a, n); }
523da2e3ebdSchin #endif
524da2e3ebdSchin #if _lib_pvalloc
F1(_pvalloc,size_t,n)525da2e3ebdSchin extern Void_t* F1(_pvalloc, size_t,n) { return pvalloc(n); }
526da2e3ebdSchin #endif
F2(_realloc,Void_t *,p,size_t,n)527da2e3ebdSchin extern Void_t* F2(_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
528da2e3ebdSchin #if _lib_valloc
F1(_valloc,size_t,n)529da2e3ebdSchin extern Void_t* F1(_valloc, size_t,n) { return valloc(n); }
530da2e3ebdSchin #endif
531da2e3ebdSchin #endif
532da2e3ebdSchin
533da2e3ebdSchin #if _lib___malloc
F2(__calloc,size_t,n,size_t,m)534da2e3ebdSchin extern Void_t* F2(__calloc, size_t,n, size_t,m) { return calloc(n, m); }
F1(__cfree,Void_t *,p)535da2e3ebdSchin extern Void_t F1(__cfree, Void_t*,p) { free(p); }
F1(__free,Void_t *,p)536da2e3ebdSchin extern Void_t F1(__free, Void_t*,p) { free(p); }
F1(__malloc,size_t,n)537da2e3ebdSchin extern Void_t* F1(__malloc, size_t,n) { return malloc(n); }
538da2e3ebdSchin #if _lib_memalign
F2(__memalign,size_t,a,size_t,n)539da2e3ebdSchin extern Void_t* F2(__memalign, size_t,a, size_t,n) { return memalign(a, n); }
540da2e3ebdSchin #endif
541da2e3ebdSchin #if _lib_pvalloc
F1(__pvalloc,size_t,n)542da2e3ebdSchin extern Void_t* F1(__pvalloc, size_t,n) { return pvalloc(n); }
543da2e3ebdSchin #endif
F2(__realloc,Void_t *,p,size_t,n)544da2e3ebdSchin extern Void_t* F2(__realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
545da2e3ebdSchin #if _lib_valloc
F1(__valloc,size_t,n)546da2e3ebdSchin extern Void_t* F1(__valloc, size_t,n) { return valloc(n); }
547da2e3ebdSchin #endif
548da2e3ebdSchin #endif
549da2e3ebdSchin
550da2e3ebdSchin #if _lib___libc_malloc
F2(__libc_calloc,size_t,n,size_t,m)551da2e3ebdSchin extern Void_t* F2(__libc_calloc, size_t,n, size_t,m) { return calloc(n, m); }
F1(__libc_cfree,Void_t *,p)552da2e3ebdSchin extern Void_t F1(__libc_cfree, Void_t*,p) { free(p); }
F1(__libc_free,Void_t *,p)553da2e3ebdSchin extern Void_t F1(__libc_free, Void_t*,p) { free(p); }
F1(__libc_malloc,size_t,n)554da2e3ebdSchin extern Void_t* F1(__libc_malloc, size_t,n) { return malloc(n); }
555da2e3ebdSchin #if _lib_memalign
F2(__libc_memalign,size_t,a,size_t,n)556da2e3ebdSchin extern Void_t* F2(__libc_memalign, size_t,a, size_t,n) { return memalign(a, n); }
557da2e3ebdSchin #endif
558da2e3ebdSchin #if _lib_pvalloc
F1(__libc_pvalloc,size_t,n)559da2e3ebdSchin extern Void_t* F1(__libc_pvalloc, size_t,n) { return pvalloc(n); }
560da2e3ebdSchin #endif
F2(__libc_realloc,Void_t *,p,size_t,n)561da2e3ebdSchin extern Void_t* F2(__libc_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
562da2e3ebdSchin #if _lib_valloc
F1(__libc_valloc,size_t,n)563da2e3ebdSchin extern Void_t* F1(__libc_valloc, size_t,n) { return valloc(n); }
564da2e3ebdSchin #endif
565da2e3ebdSchin #endif
566da2e3ebdSchin
567da2e3ebdSchin #endif /* _map_malloc */
568da2e3ebdSchin
569da2e3ebdSchin #undef extern
570da2e3ebdSchin
571da2e3ebdSchin #if _hdr_malloc /* need the mallint interface for statistics, etc. */
572da2e3ebdSchin
573da2e3ebdSchin #undef calloc
574da2e3ebdSchin #define calloc ______calloc
575da2e3ebdSchin #undef cfree
576da2e3ebdSchin #define cfree ______cfree
577da2e3ebdSchin #undef free
578da2e3ebdSchin #define free ______free
579da2e3ebdSchin #undef malloc
580da2e3ebdSchin #define malloc ______malloc
581da2e3ebdSchin #undef pvalloc
582da2e3ebdSchin #define pvalloc ______pvalloc
583da2e3ebdSchin #undef realloc
584da2e3ebdSchin #define realloc ______realloc
585da2e3ebdSchin #undef valloc
586da2e3ebdSchin #define valloc ______valloc
587da2e3ebdSchin
588da2e3ebdSchin #if !_UWIN
589da2e3ebdSchin
590da2e3ebdSchin #include <malloc.h>
591da2e3ebdSchin
592da2e3ebdSchin typedef struct mallinfo Mallinfo_t;
593da2e3ebdSchin typedef struct mstats Mstats_t;
594da2e3ebdSchin
595da2e3ebdSchin #endif
596da2e3ebdSchin
597da2e3ebdSchin #if defined(__EXPORT__)
598da2e3ebdSchin #define extern __EXPORT__
599da2e3ebdSchin #endif
600da2e3ebdSchin
601da2e3ebdSchin #if _lib_mallopt
602da2e3ebdSchin #if __STD_C
mallopt(int cmd,int value)603da2e3ebdSchin extern int mallopt(int cmd, int value)
604da2e3ebdSchin #else
605da2e3ebdSchin extern int mallopt(cmd, value)
606da2e3ebdSchin int cmd;
607da2e3ebdSchin int value;
608da2e3ebdSchin #endif
609da2e3ebdSchin {
610da2e3ebdSchin VMFLINIT();
611da2e3ebdSchin return 0;
612da2e3ebdSchin }
613da2e3ebdSchin #endif /*_lib_mallopt*/
614da2e3ebdSchin
615da2e3ebdSchin #if _lib_mallinfo && _mem_arena_mallinfo
616da2e3ebdSchin #if __STD_C
mallinfo(void)617da2e3ebdSchin extern Mallinfo_t mallinfo(void)
618da2e3ebdSchin #else
619da2e3ebdSchin extern Mallinfo_t mallinfo()
620da2e3ebdSchin #endif
621da2e3ebdSchin {
622da2e3ebdSchin Vmstat_t sb;
623da2e3ebdSchin Mallinfo_t mi;
624da2e3ebdSchin
625da2e3ebdSchin VMFLINIT();
626da2e3ebdSchin memset(&mi,0,sizeof(mi));
627da2e3ebdSchin if(vmstat(Vmregion,&sb) >= 0)
628da2e3ebdSchin { mi.arena = sb.extent;
629da2e3ebdSchin mi.ordblks = sb.n_busy+sb.n_free;
630da2e3ebdSchin mi.uordblks = sb.s_busy;
631da2e3ebdSchin mi.fordblks = sb.s_free;
632da2e3ebdSchin }
633da2e3ebdSchin return mi;
634da2e3ebdSchin }
635da2e3ebdSchin #endif /* _lib_mallinfo */
636da2e3ebdSchin
637da2e3ebdSchin #if _lib_mstats && _mem_bytes_total_mstats
638da2e3ebdSchin #if __STD_C
mstats(void)639da2e3ebdSchin extern Mstats_t mstats(void)
640da2e3ebdSchin #else
641da2e3ebdSchin extern Mstats_t mstats()
642da2e3ebdSchin #endif
643da2e3ebdSchin {
644da2e3ebdSchin Vmstat_t sb;
645da2e3ebdSchin Mstats_t ms;
646da2e3ebdSchin
647da2e3ebdSchin VMFLINIT();
648da2e3ebdSchin memset(&ms,0,sizeof(ms));
649da2e3ebdSchin if(vmstat(Vmregion,&sb) >= 0)
650da2e3ebdSchin { ms.bytes_total = sb.extent;
651da2e3ebdSchin ms.chunks_used = sb.n_busy;
652da2e3ebdSchin ms.bytes_used = sb.s_busy;
653da2e3ebdSchin ms.chunks_free = sb.n_free;
654da2e3ebdSchin ms.bytes_free = sb.s_free;
655da2e3ebdSchin }
656da2e3ebdSchin return ms;
657da2e3ebdSchin }
658da2e3ebdSchin #endif /*_lib_mstats*/
659da2e3ebdSchin
660da2e3ebdSchin #undef extern
661da2e3ebdSchin
662da2e3ebdSchin #endif/*_hdr_malloc*/
663da2e3ebdSchin
664da2e3ebdSchin #else
665da2e3ebdSchin
666da2e3ebdSchin /*
667da2e3ebdSchin * even though there is no malloc override, still provide
668da2e3ebdSchin * _ast_* counterparts for object compatibility
669da2e3ebdSchin */
670da2e3ebdSchin
671da2e3ebdSchin #undef calloc
672da2e3ebdSchin extern Void_t* calloc _ARG_((size_t, size_t));
673da2e3ebdSchin
674da2e3ebdSchin #undef cfree
675da2e3ebdSchin extern void cfree _ARG_((Void_t*));
676da2e3ebdSchin
677da2e3ebdSchin #undef free
678da2e3ebdSchin extern void free _ARG_((Void_t*));
679da2e3ebdSchin
680da2e3ebdSchin #undef malloc
681da2e3ebdSchin extern Void_t* malloc _ARG_((size_t));
682da2e3ebdSchin
683da2e3ebdSchin #if _lib_memalign
684da2e3ebdSchin #undef memalign
685da2e3ebdSchin extern Void_t* memalign _ARG_((size_t, size_t));
686da2e3ebdSchin #endif
687da2e3ebdSchin
688da2e3ebdSchin #if _lib_pvalloc
689da2e3ebdSchin #undef pvalloc
690da2e3ebdSchin extern Void_t* pvalloc _ARG_((size_t));
691da2e3ebdSchin #endif
692da2e3ebdSchin
693da2e3ebdSchin #undef realloc
694da2e3ebdSchin extern Void_t* realloc _ARG_((Void_t*, size_t));
695da2e3ebdSchin
696da2e3ebdSchin #if _lib_valloc
697da2e3ebdSchin #undef valloc
698da2e3ebdSchin extern Void_t* valloc _ARG_((size_t));
699da2e3ebdSchin #endif
700da2e3ebdSchin
701da2e3ebdSchin #if defined(__EXPORT__)
702da2e3ebdSchin #define extern __EXPORT__
703da2e3ebdSchin #endif
704da2e3ebdSchin
F2(_ast_calloc,size_t,n,size_t,m)705da2e3ebdSchin extern Void_t* F2(_ast_calloc, size_t,n, size_t,m) { return calloc(n, m); }
F1(_ast_cfree,Void_t *,p)706da2e3ebdSchin extern Void_t F1(_ast_cfree, Void_t*,p) { free(p); }
F1(_ast_free,Void_t *,p)707da2e3ebdSchin extern Void_t F1(_ast_free, Void_t*,p) { free(p); }
F1(_ast_malloc,size_t,n)708da2e3ebdSchin extern Void_t* F1(_ast_malloc, size_t,n) { return malloc(n); }
709da2e3ebdSchin #if _lib_memalign
F2(_ast_memalign,size_t,a,size_t,n)710da2e3ebdSchin extern Void_t* F2(_ast_memalign, size_t,a, size_t,n) { return memalign(a, n); }
711da2e3ebdSchin #endif
712da2e3ebdSchin #if _lib_pvalloc
F1(_ast_pvalloc,size_t,n)713da2e3ebdSchin extern Void_t* F1(_ast_pvalloc, size_t,n) { return pvalloc(n); }
714da2e3ebdSchin #endif
F2(_ast_realloc,Void_t *,p,size_t,n)715da2e3ebdSchin extern Void_t* F2(_ast_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
716da2e3ebdSchin #if _lib_valloc
F1(_ast_valloc,size_t,n)717da2e3ebdSchin extern Void_t* F1(_ast_valloc, size_t,n) { return valloc(n); }
718da2e3ebdSchin #endif
719da2e3ebdSchin
720da2e3ebdSchin #undef extern
721da2e3ebdSchin
722da2e3ebdSchin #if _hdr_malloc
723da2e3ebdSchin
724da2e3ebdSchin #undef mallinfo
725da2e3ebdSchin #undef mallopt
726da2e3ebdSchin #undef mstats
727da2e3ebdSchin
728da2e3ebdSchin #define calloc ______calloc
729da2e3ebdSchin #define cfree ______cfree
730da2e3ebdSchin #define free ______free
731da2e3ebdSchin #define malloc ______malloc
732da2e3ebdSchin #define pvalloc ______pvalloc
733da2e3ebdSchin #define realloc ______realloc
734da2e3ebdSchin #define valloc ______valloc
735da2e3ebdSchin
736da2e3ebdSchin #if !_UWIN
737da2e3ebdSchin
738da2e3ebdSchin #include <malloc.h>
739da2e3ebdSchin
740da2e3ebdSchin typedef struct mallinfo Mallinfo_t;
741da2e3ebdSchin typedef struct mstats Mstats_t;
742da2e3ebdSchin
743da2e3ebdSchin #endif
744da2e3ebdSchin
745da2e3ebdSchin #if defined(__EXPORT__)
746da2e3ebdSchin #define extern __EXPORT__
747da2e3ebdSchin #endif
748da2e3ebdSchin
749da2e3ebdSchin #if _lib_mallopt
F2(_ast_mallopt,int,cmd,int,value)750da2e3ebdSchin extern int F2(_ast_mallopt, int,cmd, int,value) { return mallopt(cmd, value); }
751da2e3ebdSchin #endif
752da2e3ebdSchin
753da2e3ebdSchin #if _lib_mallinfo && _mem_arena_mallinfo
F0(_ast_mallinfo,void)754da2e3ebdSchin extern Mallinfo_t F0(_ast_mallinfo, void) { return mallinfo(); }
755da2e3ebdSchin #endif
756da2e3ebdSchin
757da2e3ebdSchin #if _lib_mstats && _mem_bytes_total_mstats
F0(_ast_mstats,void)758da2e3ebdSchin extern Mstats_t F0(_ast_mstats, void) { return mstats(); }
759da2e3ebdSchin #endif
760da2e3ebdSchin
761da2e3ebdSchin #undef extern
762da2e3ebdSchin
763da2e3ebdSchin #endif /*_hdr_malloc*/
764da2e3ebdSchin
765da2e3ebdSchin #endif /*!_std_malloc*/
766da2e3ebdSchin
767*3e14f97fSRoger A. Faulkner #if __STD_C
atou(char ** sp)768*3e14f97fSRoger A. Faulkner static Vmulong_t atou(char** sp)
769*3e14f97fSRoger A. Faulkner #else
770*3e14f97fSRoger A. Faulkner static Vmulong_t atou(sp)
771*3e14f97fSRoger A. Faulkner char** sp;
772*3e14f97fSRoger A. Faulkner #endif
773*3e14f97fSRoger A. Faulkner {
774*3e14f97fSRoger A. Faulkner char* s = *sp;
775*3e14f97fSRoger A. Faulkner Vmulong_t v = 0;
776*3e14f97fSRoger A. Faulkner
777*3e14f97fSRoger A. Faulkner if(s[0] == '0' && (s[1] == 'x' || s[1] == 'X') )
778*3e14f97fSRoger A. Faulkner { for(s += 2; *s; ++s)
779*3e14f97fSRoger A. Faulkner { if(*s >= '0' && *s <= '9')
780*3e14f97fSRoger A. Faulkner v = (v << 4) + (*s - '0');
781*3e14f97fSRoger A. Faulkner else if(*s >= 'a' && *s <= 'f')
782*3e14f97fSRoger A. Faulkner v = (v << 4) + (*s - 'a') + 10;
783*3e14f97fSRoger A. Faulkner else if(*s >= 'A' && *s <= 'F')
784*3e14f97fSRoger A. Faulkner v = (v << 4) + (*s - 'A') + 10;
785*3e14f97fSRoger A. Faulkner else break;
786*3e14f97fSRoger A. Faulkner }
787*3e14f97fSRoger A. Faulkner }
788*3e14f97fSRoger A. Faulkner else
789*3e14f97fSRoger A. Faulkner { for(; *s; ++s)
790*3e14f97fSRoger A. Faulkner { if(*s >= '0' && *s <= '9')
791*3e14f97fSRoger A. Faulkner v = v*10 + (*s - '0');
792*3e14f97fSRoger A. Faulkner else break;
793*3e14f97fSRoger A. Faulkner }
794*3e14f97fSRoger A. Faulkner }
795*3e14f97fSRoger A. Faulkner
796*3e14f97fSRoger A. Faulkner *sp = s;
797*3e14f97fSRoger A. Faulkner return v;
798*3e14f97fSRoger A. Faulkner }
799*3e14f97fSRoger A. Faulkner
800*3e14f97fSRoger A. Faulkner #if __STD_C
insertpid(char * begs,char * ends)801*3e14f97fSRoger A. Faulkner static char* insertpid(char* begs, char* ends)
802*3e14f97fSRoger A. Faulkner #else
803*3e14f97fSRoger A. Faulkner static char* insertpid(begs,ends)
804*3e14f97fSRoger A. Faulkner char* begs;
805*3e14f97fSRoger A. Faulkner char* ends;
806*3e14f97fSRoger A. Faulkner #endif
807*3e14f97fSRoger A. Faulkner { int pid;
808*3e14f97fSRoger A. Faulkner char* s;
809*3e14f97fSRoger A. Faulkner
810*3e14f97fSRoger A. Faulkner if((pid = getpid()) < 0)
811*3e14f97fSRoger A. Faulkner return NIL(char*);
812*3e14f97fSRoger A. Faulkner
813*3e14f97fSRoger A. Faulkner s = ends;
814*3e14f97fSRoger A. Faulkner do
815*3e14f97fSRoger A. Faulkner { if(s == begs)
816*3e14f97fSRoger A. Faulkner return NIL(char*);
817*3e14f97fSRoger A. Faulkner *--s = '0' + pid%10;
818*3e14f97fSRoger A. Faulkner } while((pid /= 10) > 0);
819*3e14f97fSRoger A. Faulkner while(s < ends)
820*3e14f97fSRoger A. Faulkner *begs++ = *s++;
821*3e14f97fSRoger A. Faulkner
822*3e14f97fSRoger A. Faulkner return begs;
823*3e14f97fSRoger A. Faulkner }
824*3e14f97fSRoger A. Faulkner
825*3e14f97fSRoger A. Faulkner #if __STD_C
createfile(char * file)826*3e14f97fSRoger A. Faulkner static int createfile(char* file)
827*3e14f97fSRoger A. Faulkner #else
828*3e14f97fSRoger A. Faulkner static int createfile(file)
829*3e14f97fSRoger A. Faulkner char* file;
830*3e14f97fSRoger A. Faulkner #endif
831*3e14f97fSRoger A. Faulkner {
832*3e14f97fSRoger A. Faulkner char buf[1024];
833*3e14f97fSRoger A. Faulkner char *next, *endb;
834*3e14f97fSRoger A. Faulkner int fd;
835*3e14f97fSRoger A. Faulkner
836*3e14f97fSRoger A. Faulkner next = buf;
837*3e14f97fSRoger A. Faulkner endb = buf + sizeof(buf);
838*3e14f97fSRoger A. Faulkner while(*file)
839*3e14f97fSRoger A. Faulkner { if(*file == '%')
840*3e14f97fSRoger A. Faulkner { switch(file[1])
841*3e14f97fSRoger A. Faulkner {
842*3e14f97fSRoger A. Faulkner case 'p' :
843*3e14f97fSRoger A. Faulkner if(!(next = insertpid(next,endb)) )
844*3e14f97fSRoger A. Faulkner return -1;
845*3e14f97fSRoger A. Faulkner file += 2;
846*3e14f97fSRoger A. Faulkner break;
847*3e14f97fSRoger A. Faulkner default :
848*3e14f97fSRoger A. Faulkner goto copy;
849*3e14f97fSRoger A. Faulkner }
850*3e14f97fSRoger A. Faulkner }
851*3e14f97fSRoger A. Faulkner else
852*3e14f97fSRoger A. Faulkner { copy:
853*3e14f97fSRoger A. Faulkner *next++ = *file++;
854*3e14f97fSRoger A. Faulkner }
855*3e14f97fSRoger A. Faulkner
856*3e14f97fSRoger A. Faulkner if(next >= endb)
857*3e14f97fSRoger A. Faulkner return -1;
858*3e14f97fSRoger A. Faulkner }
859*3e14f97fSRoger A. Faulkner
860*3e14f97fSRoger A. Faulkner *next = '\0';
861*3e14f97fSRoger A. Faulkner file = buf;
862*3e14f97fSRoger A. Faulkner if (*file == '&' && *(file += 1) || strncmp(file, "/dev/fd/", 8) == 0 && *(file += 8))
863*3e14f97fSRoger A. Faulkner fd = dup((int)atou(&file));
864*3e14f97fSRoger A. Faulkner else if (*file)
865*3e14f97fSRoger A. Faulkner #if _PACKAGE_ast
866*3e14f97fSRoger A. Faulkner fd = open(file, O_WRONLY|O_CREAT|O_TRUNC, CREAT_MODE);
867*3e14f97fSRoger A. Faulkner #else
868*3e14f97fSRoger A. Faulkner fd = creat(file, CREAT_MODE);
869*3e14f97fSRoger A. Faulkner #endif
870*3e14f97fSRoger A. Faulkner else
871*3e14f97fSRoger A. Faulkner return -1;
872*3e14f97fSRoger A. Faulkner #if _PACKAGE_ast
873*3e14f97fSRoger A. Faulkner #ifdef FD_CLOEXEC
874*3e14f97fSRoger A. Faulkner if (fd >= 0)
875*3e14f97fSRoger A. Faulkner fcntl(fd, F_SETFD, FD_CLOEXEC);
876*3e14f97fSRoger A. Faulkner #endif
877*3e14f97fSRoger A. Faulkner #endif
878*3e14f97fSRoger A. Faulkner return fd;
879*3e14f97fSRoger A. Faulkner }
880*3e14f97fSRoger A. Faulkner
881*3e14f97fSRoger A. Faulkner #if __STD_C
pfprint(void)882*3e14f97fSRoger A. Faulkner static void pfprint(void)
883*3e14f97fSRoger A. Faulkner #else
884*3e14f97fSRoger A. Faulkner static void pfprint()
885*3e14f97fSRoger A. Faulkner #endif
886*3e14f97fSRoger A. Faulkner {
887*3e14f97fSRoger A. Faulkner if(Vmregion->meth.meth == VM_MTPROFILE)
888*3e14f97fSRoger A. Faulkner vmprofile(Vmregion,_Vmpffd);
889*3e14f97fSRoger A. Faulkner }
890*3e14f97fSRoger A. Faulkner
891*3e14f97fSRoger A. Faulkner /*
892*3e14f97fSRoger A. Faulkner * initialize runtime options from the VMALLOC_OPTIONS env var
893*3e14f97fSRoger A. Faulkner */
894*3e14f97fSRoger A. Faulkner
895*3e14f97fSRoger A. Faulkner #define COPY(t,e,f) while ((*t = *f++) && t < e) t++
896*3e14f97fSRoger A. Faulkner
897*3e14f97fSRoger A. Faulkner #if __STD_C
_vmoptions(void)898*3e14f97fSRoger A. Faulkner void _vmoptions(void)
899*3e14f97fSRoger A. Faulkner #else
900*3e14f97fSRoger A. Faulkner void _vmoptions()
901*3e14f97fSRoger A. Faulkner #endif
902*3e14f97fSRoger A. Faulkner {
903*3e14f97fSRoger A. Faulkner Vmalloc_t* vm = 0;
904*3e14f97fSRoger A. Faulkner char* trace = 0;
905*3e14f97fSRoger A. Faulkner char* s;
906*3e14f97fSRoger A. Faulkner char* t;
907*3e14f97fSRoger A. Faulkner char* v;
908*3e14f97fSRoger A. Faulkner Vmulong_t n;
909*3e14f97fSRoger A. Faulkner int fd;
910*3e14f97fSRoger A. Faulkner char buf[1024];
911*3e14f97fSRoger A. Faulkner
912*3e14f97fSRoger A. Faulkner _Vmoptions = 1;
913*3e14f97fSRoger A. Faulkner t = buf;
914*3e14f97fSRoger A. Faulkner v = &buf[sizeof(buf)-1];
915*3e14f97fSRoger A. Faulkner if (s = getenv("VMALLOC_OPTIONS"))
916*3e14f97fSRoger A. Faulkner COPY(t, v, s);
917*3e14f97fSRoger A. Faulkner #if 1 /* backwards compatibility until 2011 */
918*3e14f97fSRoger A. Faulkner else
919*3e14f97fSRoger A. Faulkner {
920*3e14f97fSRoger A. Faulkner char* p;
921*3e14f97fSRoger A. Faulkner
922*3e14f97fSRoger A. Faulkner if (s = getenv("VMDEBUG"))
923*3e14f97fSRoger A. Faulkner {
924*3e14f97fSRoger A. Faulkner switch (*s++)
925*3e14f97fSRoger A. Faulkner {
926*3e14f97fSRoger A. Faulkner case 0:
927*3e14f97fSRoger A. Faulkner break;
928*3e14f97fSRoger A. Faulkner case 'a':
929*3e14f97fSRoger A. Faulkner p = " abort";
930*3e14f97fSRoger A. Faulkner COPY(t, v, p);
931*3e14f97fSRoger A. Faulkner break;
932*3e14f97fSRoger A. Faulkner case 'w':
933*3e14f97fSRoger A. Faulkner p = " warn";
934*3e14f97fSRoger A. Faulkner COPY(t, v, p);
935*3e14f97fSRoger A. Faulkner break;
936*3e14f97fSRoger A. Faulkner case '0':
937*3e14f97fSRoger A. Faulkner if (*s-- == 'x')
938*3e14f97fSRoger A. Faulkner {
939*3e14f97fSRoger A. Faulkner p = " watch=";
940*3e14f97fSRoger A. Faulkner COPY(t, v, p);
941*3e14f97fSRoger A. Faulkner COPY(t, v, s);
942*3e14f97fSRoger A. Faulkner break;
943*3e14f97fSRoger A. Faulkner }
944*3e14f97fSRoger A. Faulkner /*FALLTHROUGH*/
945*3e14f97fSRoger A. Faulkner default:
946*3e14f97fSRoger A. Faulkner p = " period=";
947*3e14f97fSRoger A. Faulkner COPY(t, v, p);
948*3e14f97fSRoger A. Faulkner COPY(t, v, s);
949*3e14f97fSRoger A. Faulkner break;
950*3e14f97fSRoger A. Faulkner }
951*3e14f97fSRoger A. Faulkner }
952*3e14f97fSRoger A. Faulkner if ((s = getenv("VMETHOD")) && *s)
953*3e14f97fSRoger A. Faulkner {
954*3e14f97fSRoger A. Faulkner p = " method=";
955*3e14f97fSRoger A. Faulkner COPY(t, v, p);
956*3e14f97fSRoger A. Faulkner COPY(t, v, s);
957*3e14f97fSRoger A. Faulkner }
958*3e14f97fSRoger A. Faulkner if ((s = getenv("VMPROFILE")) && *s)
959*3e14f97fSRoger A. Faulkner {
960*3e14f97fSRoger A. Faulkner p = " profile=";
961*3e14f97fSRoger A. Faulkner COPY(t, v, p);
962*3e14f97fSRoger A. Faulkner COPY(t, v, s);
963*3e14f97fSRoger A. Faulkner }
964*3e14f97fSRoger A. Faulkner if ((s = getenv("VMTRACE")) && *s)
965*3e14f97fSRoger A. Faulkner {
966*3e14f97fSRoger A. Faulkner p = " trace=";
967*3e14f97fSRoger A. Faulkner COPY(t, v, p);
968*3e14f97fSRoger A. Faulkner COPY(t, v, s);
969*3e14f97fSRoger A. Faulkner }
970*3e14f97fSRoger A. Faulkner }
971*3e14f97fSRoger A. Faulkner #endif
972*3e14f97fSRoger A. Faulkner if (t > buf)
973*3e14f97fSRoger A. Faulkner {
974*3e14f97fSRoger A. Faulkner *t = 0;
975*3e14f97fSRoger A. Faulkner s = buf;
976*3e14f97fSRoger A. Faulkner for (;;)
977*3e14f97fSRoger A. Faulkner {
978*3e14f97fSRoger A. Faulkner while (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n')
979*3e14f97fSRoger A. Faulkner s++;
980*3e14f97fSRoger A. Faulkner if (!*(t = s))
981*3e14f97fSRoger A. Faulkner break;
982*3e14f97fSRoger A. Faulkner v = 0;
983*3e14f97fSRoger A. Faulkner while (*s)
984*3e14f97fSRoger A. Faulkner if (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n')
985*3e14f97fSRoger A. Faulkner {
986*3e14f97fSRoger A. Faulkner *s++ = 0;
987*3e14f97fSRoger A. Faulkner break;
988*3e14f97fSRoger A. Faulkner }
989*3e14f97fSRoger A. Faulkner else if (!v && *s == '=')
990*3e14f97fSRoger A. Faulkner {
991*3e14f97fSRoger A. Faulkner *s++ = 0;
992*3e14f97fSRoger A. Faulkner if (!*(v = s))
993*3e14f97fSRoger A. Faulkner v = 0;
994*3e14f97fSRoger A. Faulkner }
995*3e14f97fSRoger A. Faulkner else
996*3e14f97fSRoger A. Faulkner s++;
997*3e14f97fSRoger A. Faulkner if (t[0] == 'n' && t[1] == 'o')
998*3e14f97fSRoger A. Faulkner continue;
999*3e14f97fSRoger A. Faulkner switch (t[0])
1000*3e14f97fSRoger A. Faulkner {
1001*3e14f97fSRoger A. Faulkner case 'a': /* abort */
1002*3e14f97fSRoger A. Faulkner if (!vm)
1003*3e14f97fSRoger A. Faulkner vm = vmopen(Vmdcsbrk, Vmdebug, 0);
1004*3e14f97fSRoger A. Faulkner if (vm && vm->meth.meth == VM_MTDEBUG)
1005*3e14f97fSRoger A. Faulkner vmset(vm, VM_DBABORT, 1);
1006*3e14f97fSRoger A. Faulkner else
1007*3e14f97fSRoger A. Faulkner _Vmassert |= VM_abort;
1008*3e14f97fSRoger A. Faulkner break;
1009*3e14f97fSRoger A. Faulkner case 'c': /* check */
1010*3e14f97fSRoger A. Faulkner _Vmassert |= VM_check;
1011*3e14f97fSRoger A. Faulkner break;
1012*3e14f97fSRoger A. Faulkner case 'm':
1013*3e14f97fSRoger A. Faulkner switch (t[1])
1014*3e14f97fSRoger A. Faulkner {
1015*3e14f97fSRoger A. Faulkner case 'e': /* method=<method> */
1016*3e14f97fSRoger A. Faulkner if (v && !vm)
1017*3e14f97fSRoger A. Faulkner {
1018*3e14f97fSRoger A. Faulkner if ((v[0] == 'V' || v[0] == 'v') && (v[1] == 'M' || v[1] == 'm'))
1019*3e14f97fSRoger A. Faulkner v += 2;
1020*3e14f97fSRoger A. Faulkner if (strcmp(v, "debug") == 0)
1021*3e14f97fSRoger A. Faulkner vm = vmopen(Vmdcsbrk, Vmdebug, 0);
1022*3e14f97fSRoger A. Faulkner else if (strcmp(v, "profile") == 0)
1023*3e14f97fSRoger A. Faulkner vm = vmopen(Vmdcsbrk, Vmprofile, 0);
1024*3e14f97fSRoger A. Faulkner else if (strcmp(v, "last") == 0)
1025*3e14f97fSRoger A. Faulkner vm = vmopen(Vmdcsbrk, Vmlast, 0);
1026*3e14f97fSRoger A. Faulkner else if (strcmp(v, "best") == 0)
1027*3e14f97fSRoger A. Faulkner vm = Vmheap;
1028*3e14f97fSRoger A. Faulkner }
1029*3e14f97fSRoger A. Faulkner break;
1030*3e14f97fSRoger A. Faulkner case 'm': /* mmap */
1031*3e14f97fSRoger A. Faulkner #if _mem_mmap_anon || _mem_mmap_zero
1032*3e14f97fSRoger A. Faulkner _Vmassert |= VM_mmap;
1033*3e14f97fSRoger A. Faulkner #endif
1034*3e14f97fSRoger A. Faulkner break;
1035*3e14f97fSRoger A. Faulkner }
1036*3e14f97fSRoger A. Faulkner break;
1037*3e14f97fSRoger A. Faulkner case 'p':
1038*3e14f97fSRoger A. Faulkner if (v)
1039*3e14f97fSRoger A. Faulkner switch (t[1])
1040*3e14f97fSRoger A. Faulkner {
1041*3e14f97fSRoger A. Faulkner case 'e': /* period=<count> */
1042*3e14f97fSRoger A. Faulkner if (!vm)
1043*3e14f97fSRoger A. Faulkner vm = vmopen(Vmdcsbrk, Vmdebug, 0);
1044*3e14f97fSRoger A. Faulkner if (vm && vm->meth.meth == VM_MTDEBUG)
1045*3e14f97fSRoger A. Faulkner _Vmdbcheck = atou(&v);
1046*3e14f97fSRoger A. Faulkner break;
1047*3e14f97fSRoger A. Faulkner case 'r': /* profile=<path> */
1048*3e14f97fSRoger A. Faulkner if (!vm)
1049*3e14f97fSRoger A. Faulkner vm = vmopen(Vmdcsbrk, Vmprofile, 0);
1050*3e14f97fSRoger A. Faulkner if (v && vm && vm->meth.meth == VM_MTPROFILE)
1051*3e14f97fSRoger A. Faulkner _Vmpffd = createfile(v);
1052*3e14f97fSRoger A. Faulkner break;
1053*3e14f97fSRoger A. Faulkner }
1054*3e14f97fSRoger A. Faulkner break;
1055*3e14f97fSRoger A. Faulkner case 'r': /* region */
1056*3e14f97fSRoger A. Faulkner _Vmassert |= VM_region;
1057*3e14f97fSRoger A. Faulkner break;
1058*3e14f97fSRoger A. Faulkner case 's': /* start=<count> */
1059*3e14f97fSRoger A. Faulkner if (!vm)
1060*3e14f97fSRoger A. Faulkner vm = vmopen(Vmdcsbrk, Vmdebug, 0);
1061*3e14f97fSRoger A. Faulkner if (v && vm && vm->meth.meth == VM_MTDEBUG)
1062*3e14f97fSRoger A. Faulkner _Vmdbstart = atou(&v);
1063*3e14f97fSRoger A. Faulkner break;
1064*3e14f97fSRoger A. Faulkner case 't': /* trace=<path> */
1065*3e14f97fSRoger A. Faulkner trace = v;
1066*3e14f97fSRoger A. Faulkner break;
1067*3e14f97fSRoger A. Faulkner case 'w':
1068*3e14f97fSRoger A. Faulkner if (t[1] == 'a')
1069*3e14f97fSRoger A. Faulkner switch (t[2])
1070*3e14f97fSRoger A. Faulkner {
1071*3e14f97fSRoger A. Faulkner case 'r': /* warn=<path> */
1072*3e14f97fSRoger A. Faulkner if (!vm)
1073*3e14f97fSRoger A. Faulkner vm = vmopen(Vmdcsbrk, Vmdebug, 0);
1074*3e14f97fSRoger A. Faulkner if (v && vm && vm->meth.meth == VM_MTDEBUG && (fd = createfile(v)) >= 0)
1075*3e14f97fSRoger A. Faulkner vmdebug(fd);
1076*3e14f97fSRoger A. Faulkner break;
1077*3e14f97fSRoger A. Faulkner case 't': /* watch=<addr> */
1078*3e14f97fSRoger A. Faulkner if (!vm)
1079*3e14f97fSRoger A. Faulkner vm = vmopen(Vmdcsbrk, Vmdebug, 0);
1080*3e14f97fSRoger A. Faulkner if (v && vm && vm->meth.meth == VM_MTDEBUG && (n = atou(&v)) >= 0)
1081*3e14f97fSRoger A. Faulkner vmdbwatch((Void_t*)n);
1082*3e14f97fSRoger A. Faulkner break;
1083*3e14f97fSRoger A. Faulkner }
1084*3e14f97fSRoger A. Faulkner break;
1085*3e14f97fSRoger A. Faulkner }
1086*3e14f97fSRoger A. Faulkner }
1087*3e14f97fSRoger A. Faulkner }
1088*3e14f97fSRoger A. Faulkner
1089*3e14f97fSRoger A. Faulkner /* slip in the new region now so that malloc() will work fine */
1090*3e14f97fSRoger A. Faulkner
1091*3e14f97fSRoger A. Faulkner if (vm)
1092*3e14f97fSRoger A. Faulkner {
1093*3e14f97fSRoger A. Faulkner if (vm->meth.meth == VM_MTDEBUG)
1094*3e14f97fSRoger A. Faulkner _Vmdbcheck = 1;
1095*3e14f97fSRoger A. Faulkner Vmregion = vm;
1096*3e14f97fSRoger A. Faulkner }
1097*3e14f97fSRoger A. Faulkner
1098*3e14f97fSRoger A. Faulkner /* enable tracing */
1099*3e14f97fSRoger A. Faulkner
1100*3e14f97fSRoger A. Faulkner if (trace && (fd = createfile(trace)) >= 0)
1101*3e14f97fSRoger A. Faulkner {
1102*3e14f97fSRoger A. Faulkner vmset(Vmregion, VM_TRACE, 1);
1103*3e14f97fSRoger A. Faulkner vmtrace(fd);
1104*3e14f97fSRoger A. Faulkner }
1105*3e14f97fSRoger A. Faulkner
1106*3e14f97fSRoger A. Faulkner /* make sure that profile data is output upon exiting */
1107*3e14f97fSRoger A. Faulkner
1108*3e14f97fSRoger A. Faulkner if (vm && vm->meth.meth == VM_MTPROFILE)
1109*3e14f97fSRoger A. Faulkner {
1110*3e14f97fSRoger A. Faulkner if (_Vmpffd < 0)
1111*3e14f97fSRoger A. Faulkner _Vmpffd = 2;
1112*3e14f97fSRoger A. Faulkner /* this may wind up calling malloc(), but region is ok now */
1113*3e14f97fSRoger A. Faulkner atexit(pfprint);
1114*3e14f97fSRoger A. Faulkner }
1115*3e14f97fSRoger A. Faulkner else if (_Vmpffd >= 0)
1116*3e14f97fSRoger A. Faulkner {
1117*3e14f97fSRoger A. Faulkner close(_Vmpffd);
1118*3e14f97fSRoger A. Faulkner _Vmpffd = -1;
1119*3e14f97fSRoger A. Faulkner }
1120*3e14f97fSRoger A. Faulkner }
1121*3e14f97fSRoger A. Faulkner
1122da2e3ebdSchin #endif /*_UWIN*/
1123