xref: /titanic_51/usr/src/lib/libast/common/vmalloc/malloc.c (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
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