ia64/xen-unstable

changeset 9430:40e3df4cffe4

Import the current version of talloc from the Samba 3 source base. This gives
us greater confidence that our talloc implementation is "known good". Remove
the OOM handling from consider_message: talloc_set_fail_handler is no longer
supported.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Thu Mar 23 14:32:15 2006 +0100 (2006-03-23)
parents a594a5b2407c
children f3943890794a
files tools/xenstore/README tools/xenstore/talloc.c tools/xenstore/talloc.h tools/xenstore/xenstored_core.c
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/xenstore/README	Thu Mar 23 14:32:15 2006 +0100
     1.3 @@ -0,0 +1,5 @@
     1.4 +The following files are imported from the Samba project.  We use the versions
     1.5 +from Samba 3, the current stable branch.
     1.6 +
     1.7 +talloc.c: samba-trunk/source/lib/talloc.c     r14291 2006-03-13 04:27:47 +0000
     1.8 +talloc.h: samba-trunk/source/include/talloc.h r11986 2005-12-01 00:43:36 +0000
     2.1 --- a/tools/xenstore/talloc.c	Thu Mar 23 14:26:38 2006 +0100
     2.2 +++ b/tools/xenstore/talloc.c	Thu Mar 23 14:32:15 2006 +0100
     2.3 @@ -1,4 +1,4 @@
     2.4 -/* 
     2.5 +/*
     2.6     Samba Unix SMB/CIFS implementation.
     2.7  
     2.8     Samba trivial allocation library - new interface
     2.9 @@ -6,27 +6,30 @@
    2.10     NOTE: Please read talloc_guide.txt for full documentation
    2.11  
    2.12     Copyright (C) Andrew Tridgell 2004
    2.13 -   
    2.14 -   This program is free software; you can redistribute it and/or modify
    2.15 -   it under the terms of the GNU General Public License as published by
    2.16 -   the Free Software Foundation; either version 2 of the License, or
    2.17 -   (at your option) any later version.
    2.18 -   
    2.19 -   This program is distributed in the hope that it will be useful,
    2.20 +
    2.21 +     ** NOTE! The following LGPL license applies to the talloc
    2.22 +     ** library. This does NOT imply that all of Samba is released
    2.23 +     ** under the LGPL
    2.24 +
    2.25 +   This library is free software; you can redistribute it and/or
    2.26 +   modify it under the terms of the GNU Lesser General Public
    2.27 +   License as published by the Free Software Foundation; either
    2.28 +   version 2 of the License, or (at your option) any later version.
    2.29 +
    2.30 +   This library is distributed in the hope that it will be useful,
    2.31     but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.32 -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.33 -   GNU General Public License for more details.
    2.34 -   
    2.35 -   You should have received a copy of the GNU General Public License
    2.36 -   along with this program; if not, write to the Free Software
    2.37 -   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    2.38 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    2.39 +   Lesser General Public License for more details.
    2.40 +
    2.41 +   You should have received a copy of the GNU Lesser General Public
    2.42 +   License along with this library; if not, write to the Free Software
    2.43 +   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2.44  */
    2.45  
    2.46  /*
    2.47    inspired by http://swapped.cc/halloc/
    2.48  */
    2.49  
    2.50 -
    2.51  #ifdef _SAMBA_BUILD_
    2.52  #include "includes.h"
    2.53  #if ((SAMBA_VERSION_MAJOR==3)&&(SAMBA_VERSION_MINOR<9))
    2.54 @@ -52,15 +55,13 @@
    2.55  
    2.56  /* use this to force every realloc to change the pointer, to stress test
    2.57     code that might not cope */
    2.58 -#ifdef TESTING
    2.59 -#define ALWAYS_REALLOC 1
    2.60 -void *test_malloc(size_t size);
    2.61 -#define malloc test_malloc
    2.62 -#endif
    2.63 +#define ALWAYS_REALLOC 0
    2.64 +
    2.65  
    2.66  #define MAX_TALLOC_SIZE 0x10000000
    2.67 -#define TALLOC_MAGIC 0xe814ec4f
    2.68 -#define TALLOC_MAGIC_FREE 0x7faebef3
    2.69 +#define TALLOC_MAGIC 0xe814ec70
    2.70 +#define TALLOC_FLAG_FREE 0x01
    2.71 +#define TALLOC_FLAG_LOOP 0x02
    2.72  #define TALLOC_MAGIC_REFERENCE ((const char *)1)
    2.73  
    2.74  /* by default we abort when given a bad pointer (such as when talloc_free() is called 
    2.75 @@ -83,8 +84,7 @@ void *test_malloc(size_t size);
    2.76  */
    2.77  static const void *null_context;
    2.78  static void *cleanup_context;
    2.79 -static int (*malloc_fail_handler)(void *);
    2.80 -static void *malloc_fail_data;
    2.81 +
    2.82  
    2.83  struct talloc_reference_handle {
    2.84  	struct talloc_reference_handle *next, *prev;
    2.85 @@ -97,24 +97,27 @@ struct talloc_chunk {
    2.86  	struct talloc_chunk *next, *prev;
    2.87  	struct talloc_chunk *parent, *child;
    2.88  	struct talloc_reference_handle *refs;
    2.89 -	size_t size;
    2.90 -	unsigned magic;
    2.91  	talloc_destructor_t destructor;
    2.92  	const char *name;
    2.93 +	size_t size;
    2.94 +	unsigned flags;
    2.95  };
    2.96  
    2.97 +/* 16 byte alignment seems to keep everyone happy */
    2.98 +#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
    2.99 +#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
   2.100 +
   2.101  /* panic if we get a bad magic value */
   2.102  static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
   2.103  {
   2.104 -	struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
   2.105 -	if (tc->magic != TALLOC_MAGIC) { 
   2.106 -		if (tc->magic == TALLOC_MAGIC_FREE) {
   2.107 -			TALLOC_ABORT("Bad talloc magic value - double free"); 
   2.108 -		} else {
   2.109 -			TALLOC_ABORT("Bad talloc magic value - unknown value"); 
   2.110 -		}
   2.111 +	const char *pp = ptr;
   2.112 +	struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
   2.113 +	if ((tc->flags & ~0xF) != TALLOC_MAGIC) { 
   2.114 +		TALLOC_ABORT("Bad talloc magic value - unknown value"); 
   2.115  	}
   2.116 -
   2.117 +	if (tc->flags & TALLOC_FLAG_FREE) {
   2.118 +		TALLOC_ABORT("Bad talloc magic value - double free"); 
   2.119 +	}
   2.120  	return tc;
   2.121  }
   2.122  
   2.123 @@ -159,7 +162,7 @@ static struct talloc_chunk *talloc_paren
   2.124  void *talloc_parent(const void *ptr)
   2.125  {
   2.126  	struct talloc_chunk *tc = talloc_parent_chunk(ptr);
   2.127 -	return (void *)(tc+1);
   2.128 +	return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
   2.129  }
   2.130  
   2.131  /* 
   2.132 @@ -177,17 +180,11 @@ void *_talloc(const void *context, size_
   2.133  		return NULL;
   2.134  	}
   2.135  
   2.136 -	tc = malloc(sizeof(*tc)+size);
   2.137 -	if (tc == NULL) {
   2.138 -		if (malloc_fail_handler)
   2.139 -			if (malloc_fail_handler(malloc_fail_data))
   2.140 -				tc = malloc(sizeof(*tc)+size);
   2.141 -		if (!tc)
   2.142 -			return NULL;
   2.143 -	}
   2.144 +	tc = malloc(TC_HDR_SIZE+size);
   2.145 +	if (tc == NULL) return NULL;
   2.146  
   2.147  	tc->size = size;
   2.148 -	tc->magic = TALLOC_MAGIC;
   2.149 +	tc->flags = TALLOC_MAGIC;
   2.150  	tc->destructor = NULL;
   2.151  	tc->child = NULL;
   2.152  	tc->name = NULL;
   2.153 @@ -207,7 +204,7 @@ void *_talloc(const void *context, size_
   2.154  		tc->next = tc->prev = tc->parent = NULL;
   2.155  	}
   2.156  
   2.157 -	return (void *)(tc+1);
   2.158 +	return TC_PTR_FROM_CHUNK(tc);
   2.159  }
   2.160  
   2.161  
   2.162 @@ -292,7 +289,11 @@ static int talloc_unreference(const void
   2.163  
   2.164  	for (h=tc->refs;h;h=h->next) {
   2.165  		struct talloc_chunk *p = talloc_parent_chunk(h);
   2.166 -		if ((p==NULL && context==NULL) || p+1 == context) break;
   2.167 +		if (p == NULL) {
   2.168 +			if (context == NULL) break;
   2.169 +		} else if (TC_PTR_FROM_CHUNK(p) == context) {
   2.170 +			break;
   2.171 +		}
   2.172  	}
   2.173  	if (h == NULL) {
   2.174  		return -1;
   2.175 @@ -343,7 +344,7 @@ int talloc_unlink(const void *context, v
   2.176  
   2.177  	new_p = talloc_parent_chunk(tc_p->refs);
   2.178  	if (new_p) {
   2.179 -		new_parent = new_p+1;
   2.180 +		new_parent = TC_PTR_FROM_CHUNK(new_p);
   2.181  	} else {
   2.182  		new_parent = NULL;
   2.183  	}
   2.184 @@ -471,6 +472,8 @@ void *talloc_init(const char *fmt, ...)
   2.185  	va_list ap;
   2.186  	void *ptr;
   2.187  
   2.188 +	talloc_enable_null_tracking();
   2.189 +
   2.190  	ptr = _talloc(NULL, 0);
   2.191  	if (ptr == NULL) return NULL;
   2.192  
   2.193 @@ -502,16 +505,16 @@ void talloc_free_children(void *ptr)
   2.194  		   choice is owner of any remaining reference to this
   2.195  		   pointer, the second choice is our parent, and the
   2.196  		   final choice is the null context. */
   2.197 -		void *child = tc->child+1;
   2.198 +		void *child = TC_PTR_FROM_CHUNK(tc->child);
   2.199  		const void *new_parent = null_context;
   2.200  		if (tc->child->refs) {
   2.201  			struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
   2.202 -			if (p) new_parent = p+1;
   2.203 +			if (p) new_parent = TC_PTR_FROM_CHUNK(p);
   2.204  		}
   2.205  		if (talloc_free(child) == -1) {
   2.206  			if (new_parent == null_context) {
   2.207  				struct talloc_chunk *p = talloc_parent_chunk(ptr);
   2.208 -				if (p) new_parent = p+1;
   2.209 +				if (p) new_parent = TC_PTR_FROM_CHUNK(p);
   2.210  			}
   2.211  			talloc_steal(new_parent, child);
   2.212  		}
   2.213 @@ -541,6 +544,11 @@ int talloc_free(void *ptr)
   2.214  		return -1;
   2.215  	}
   2.216  
   2.217 +	if (tc->flags & TALLOC_FLAG_LOOP) {
   2.218 +		/* we have a free loop - stop looping */
   2.219 +		return 0;
   2.220 +	}
   2.221 +
   2.222  	if (tc->destructor) {
   2.223  		talloc_destructor_t d = tc->destructor;
   2.224  		if (d == (talloc_destructor_t)-1) {
   2.225 @@ -554,6 +562,8 @@ int talloc_free(void *ptr)
   2.226  		tc->destructor = NULL;
   2.227  	}
   2.228  
   2.229 +	tc->flags |= TALLOC_FLAG_LOOP;
   2.230 +
   2.231  	talloc_free_children(ptr);
   2.232  
   2.233  	if (tc->parent) {
   2.234 @@ -566,7 +576,7 @@ int talloc_free(void *ptr)
   2.235  		if (tc->next) tc->next->prev = tc->prev;
   2.236  	}
   2.237  
   2.238 -	tc->magic = TALLOC_MAGIC_FREE;
   2.239 +	tc->flags |= TALLOC_FLAG_FREE;
   2.240  
   2.241  	free(tc);
   2.242  	return 0;
   2.243 @@ -606,36 +616,24 @@ void *_talloc_realloc(const void *contex
   2.244  	}
   2.245  
   2.246  	/* by resetting magic we catch users of the old memory */
   2.247 -	tc->magic = TALLOC_MAGIC_FREE;
   2.248 +	tc->flags |= TALLOC_FLAG_FREE;
   2.249  
   2.250  #if ALWAYS_REALLOC
   2.251 -	new_ptr = malloc(size + sizeof(*tc));
   2.252 -	if (!new_ptr) {
   2.253 -		tc->magic = TALLOC_MAGIC; 
   2.254 -		if (malloc_fail_handler)
   2.255 -			if (malloc_fail_handler(malloc_fail_data))
   2.256 -				new_ptr = malloc(size + sizeof(*tc));
   2.257 -	}
   2.258 +	new_ptr = malloc(size + TC_HDR_SIZE);
   2.259  	if (new_ptr) {
   2.260 -		memcpy(new_ptr, tc, tc->size + sizeof(*tc));
   2.261 +		memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
   2.262  		free(tc);
   2.263  	}
   2.264  #else
   2.265 -	new_ptr = realloc(tc, size + sizeof(*tc));
   2.266 -	if (!new_ptr) {
   2.267 -		tc->magic = TALLOC_MAGIC; 
   2.268 -		if (malloc_fail_handler)
   2.269 -			if (malloc_fail_handler(malloc_fail_data))
   2.270 -				new_ptr = realloc(tc, size + sizeof(*tc));
   2.271 -	}
   2.272 +	new_ptr = realloc(tc, size + TC_HDR_SIZE);
   2.273  #endif
   2.274  	if (!new_ptr) {	
   2.275 -		tc->magic = TALLOC_MAGIC; 
   2.276 +		tc->flags &= ~TALLOC_FLAG_FREE; 
   2.277  		return NULL; 
   2.278  	}
   2.279  
   2.280  	tc = new_ptr;
   2.281 -	tc->magic = TALLOC_MAGIC;
   2.282 +	tc->flags &= ~TALLOC_FLAG_FREE; 
   2.283  	if (tc->parent) {
   2.284  		tc->parent->child = new_ptr;
   2.285  	}
   2.286 @@ -651,9 +649,9 @@ void *_talloc_realloc(const void *contex
   2.287  	}
   2.288  
   2.289  	tc->size = size;
   2.290 -	talloc_set_name_const(tc+1, name);
   2.291 +	talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
   2.292  
   2.293 -	return (void *)(tc+1);
   2.294 +	return TC_PTR_FROM_CHUNK(tc);
   2.295  }
   2.296  
   2.297  /* 
   2.298 @@ -730,10 +728,19 @@ off_t talloc_total_size(const void *ptr)
   2.299  
   2.300  	tc = talloc_chunk_from_ptr(ptr);
   2.301  
   2.302 +	if (tc->flags & TALLOC_FLAG_LOOP) {
   2.303 +		return 0;
   2.304 +	}
   2.305 +
   2.306 +	tc->flags |= TALLOC_FLAG_LOOP;
   2.307 +
   2.308  	total = tc->size;
   2.309  	for (c=tc->child;c;c=c->next) {
   2.310 -		total += talloc_total_size(c+1);
   2.311 +		total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
   2.312  	}
   2.313 +
   2.314 +	tc->flags &= ~TALLOC_FLAG_LOOP;
   2.315 +
   2.316  	return total;
   2.317  }
   2.318  
   2.319 @@ -743,20 +750,21 @@ off_t talloc_total_size(const void *ptr)
   2.320  off_t talloc_total_blocks(const void *ptr)
   2.321  {
   2.322  	off_t total = 0;
   2.323 -	struct talloc_chunk *c, *tc;
   2.324 +	struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
   2.325  
   2.326 -	if (ptr == NULL) {
   2.327 -		ptr = null_context;
   2.328 -	}
   2.329 -	if (ptr == NULL) {
   2.330 +	if (tc->flags & TALLOC_FLAG_LOOP) {
   2.331  		return 0;
   2.332  	}
   2.333 -	tc = talloc_chunk_from_ptr(ptr);
   2.334 +
   2.335 +	tc->flags |= TALLOC_FLAG_LOOP;
   2.336  
   2.337  	total++;
   2.338  	for (c=tc->child;c;c=c->next) {
   2.339 -		total += talloc_total_blocks(c+1);
   2.340 +		total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
   2.341  	}
   2.342 +
   2.343 +	tc->flags &= ~TALLOC_FLAG_LOOP;
   2.344 +
   2.345  	return total;
   2.346  }
   2.347  
   2.348 @@ -782,23 +790,29 @@ void talloc_report_depth(const void *ptr
   2.349  {
   2.350  	struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
   2.351  
   2.352 +	if (tc->flags & TALLOC_FLAG_LOOP) {
   2.353 +		return;
   2.354 +	}
   2.355 +
   2.356 +	tc->flags |= TALLOC_FLAG_LOOP;
   2.357 +
   2.358  	for (c=tc->child;c;c=c->next) {
   2.359  		if (c->name == TALLOC_MAGIC_REFERENCE) {
   2.360 -			struct talloc_reference_handle *handle = (void *)(c+1);
   2.361 +			struct talloc_reference_handle *handle = TC_PTR_FROM_CHUNK(c);
   2.362  			const char *name2 = talloc_get_name(handle->ptr);
   2.363  			fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
   2.364  		} else {
   2.365 -			const char *name = talloc_get_name(c+1);
   2.366 +			const char *name = talloc_get_name(TC_PTR_FROM_CHUNK(c));
   2.367  			fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n", 
   2.368  				depth*4, "",
   2.369  				name,
   2.370 -				(unsigned long)talloc_total_size(c+1),
   2.371 -				(unsigned long)talloc_total_blocks(c+1),
   2.372 -				talloc_reference_count(c+1));
   2.373 -			talloc_report_depth(c+1, f, depth+1);
   2.374 +				(unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
   2.375 +				(unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
   2.376 +				talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
   2.377 +			talloc_report_depth(TC_PTR_FROM_CHUNK(c), f, depth+1);
   2.378  		}
   2.379  	}
   2.380 -
   2.381 +	tc->flags &= ~TALLOC_FLAG_LOOP;
   2.382  }
   2.383  
   2.384  /*
   2.385 @@ -841,9 +855,9 @@ void talloc_report(const void *ptr, FILE
   2.386  
   2.387  	for (c=tc->child;c;c=c->next) {
   2.388  		fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n", 
   2.389 -			talloc_get_name(c+1),
   2.390 -			(unsigned long)talloc_total_size(c+1),
   2.391 -			(unsigned long)talloc_total_blocks(c+1));
   2.392 +			talloc_get_name(TC_PTR_FROM_CHUNK(c)),
   2.393 +			(unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
   2.394 +			(unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)));
   2.395  	}
   2.396  	fflush(f);
   2.397  }
   2.398 @@ -878,6 +892,74 @@ void talloc_enable_null_tracking(void)
   2.399  	}
   2.400  }
   2.401  
   2.402 +#ifdef _SAMBA_BUILD_
   2.403 +/* Ugly calls to Samba-specific sprintf_append... JRA. */
   2.404 +
   2.405 +/*
   2.406 +  report on memory usage by all children of a pointer, giving a full tree view
   2.407 +*/
   2.408 +static void talloc_report_depth_str(const void *ptr, char **pps, ssize_t *plen, size_t *pbuflen, int depth)
   2.409 +{
   2.410 +	struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
   2.411 +
   2.412 +	if (tc->flags & TALLOC_FLAG_LOOP) {
   2.413 +		return;
   2.414 +	}
   2.415 +
   2.416 +	tc->flags |= TALLOC_FLAG_LOOP;
   2.417 +
   2.418 +	for (c=tc->child;c;c=c->next) {
   2.419 +		if (c->name == TALLOC_MAGIC_REFERENCE) {
   2.420 +			struct talloc_reference_handle *handle = TC_PTR_FROM_CHUNK(c);
   2.421 +			const char *name2 = talloc_get_name(handle->ptr);
   2.422 +
   2.423 +			sprintf_append(NULL, pps, plen, pbuflen,
   2.424 +				"%*sreference to: %s\n", depth*4, "", name2);
   2.425 +
   2.426 +		} else {
   2.427 +			const char *name = talloc_get_name(TC_PTR_FROM_CHUNK(c));
   2.428 +
   2.429 +			sprintf_append(NULL, pps, plen, pbuflen,
   2.430 +				"%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n", 
   2.431 +				depth*4, "",
   2.432 +				name,
   2.433 +				(unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
   2.434 +				(unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
   2.435 +				talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
   2.436 +
   2.437 +			talloc_report_depth_str(TC_PTR_FROM_CHUNK(c), pps, plen, pbuflen, depth+1);
   2.438 +		}
   2.439 +	}
   2.440 +	tc->flags &= ~TALLOC_FLAG_LOOP;
   2.441 +}
   2.442 +
   2.443 +/*
   2.444 +  report on memory usage by all children of a pointer
   2.445 +*/
   2.446 +char *talloc_describe_all(void)
   2.447 +{
   2.448 +	ssize_t len = 0;
   2.449 +	size_t buflen = 512;
   2.450 +	char *s = NULL;
   2.451 +
   2.452 +	if (null_context == NULL) {
   2.453 +		return NULL;
   2.454 +	}
   2.455 +
   2.456 +	sprintf_append(NULL, &s, &len, &buflen,
   2.457 +		"full talloc report on '%s' (total %lu bytes in %lu blocks)\n", 
   2.458 +		talloc_get_name(null_context), 
   2.459 +		(unsigned long)talloc_total_size(null_context),
   2.460 +		(unsigned long)talloc_total_blocks(null_context));
   2.461 +
   2.462 +	if (!s) {
   2.463 +		return NULL;
   2.464 +	}
   2.465 +	talloc_report_depth_str(null_context, &s, &len, &buflen, 1);
   2.466 +	return s;
   2.467 +}
   2.468 +#endif
   2.469 +
   2.470  /*
   2.471    enable leak reporting on exit
   2.472  */
   2.473 @@ -942,6 +1024,30 @@ char *talloc_strdup(const void *t, const
   2.474  }
   2.475  
   2.476  /*
   2.477 + append to a talloced string 
   2.478 +*/
   2.479 +char *talloc_append_string(const void *t, char *orig, const char *append)
   2.480 +{
   2.481 +	char *ret;
   2.482 +	size_t olen = strlen(orig);
   2.483 +	size_t alenz;
   2.484 +
   2.485 +	if (!append)
   2.486 +		return orig;
   2.487 +
   2.488 +	alenz = strlen(append) + 1;
   2.489 +
   2.490 +	ret = talloc_realloc(t, orig, char, olen + alenz);
   2.491 +	if (!ret)
   2.492 +		return NULL;
   2.493 +
   2.494 +	/* append the string with the trailing \0 */
   2.495 +	memcpy(&ret[olen], append, alenz);
   2.496 +
   2.497 +	return ret;
   2.498 +}
   2.499 +
   2.500 +/*
   2.501    strndup with a talloc 
   2.502  */
   2.503  char *talloc_strndup(const void *t, const char *p, size_t n)
   2.504 @@ -949,7 +1055,7 @@ char *talloc_strndup(const void *t, cons
   2.505  	size_t len;
   2.506  	char *ret;
   2.507  
   2.508 -	for (len=0; p[len] && len<n; len++) ;
   2.509 +	for (len=0; len<n && p[len]; len++) ;
   2.510  
   2.511  	ret = _talloc(t, len + 1);
   2.512  	if (!ret) { return NULL; }
   2.513 @@ -974,10 +1080,14 @@ char *talloc_vasprintf(const void *t, co
   2.514  	int len;
   2.515  	char *ret;
   2.516  	va_list ap2;
   2.517 +	char c;
   2.518  	
   2.519  	VA_COPY(ap2, ap);
   2.520  
   2.521 -	len = vsnprintf(NULL, 0, fmt, ap2);
   2.522 +	/* this call looks strange, but it makes it work on older solaris boxes */
   2.523 +	if ((len = vsnprintf(&c, 1, fmt, ap2)) < 0) {
   2.524 +		return NULL;
   2.525 +	}
   2.526  
   2.527  	ret = _talloc(t, len+1);
   2.528  	if (ret) {
   2.529 @@ -1029,7 +1139,15 @@ static char *talloc_vasprintf_append(cha
   2.530  	VA_COPY(ap2, ap);
   2.531  
   2.532  	s_len = tc->size - 1;
   2.533 -	len = vsnprintf(NULL, 0, fmt, ap2);
   2.534 +	if ((len = vsnprintf(NULL, 0, fmt, ap2)) <= 0) {
   2.535 +		/* Either the vsnprintf failed or the format resulted in
   2.536 +		 * no characters being formatted. In the former case, we
   2.537 +		 * ought to return NULL, in the latter we ought to return
   2.538 +		 * the original string. Most current callers of this 
   2.539 +		 * function expect it to never return NULL.
   2.540 +		 */
   2.541 +		return s;
   2.542 +	}
   2.543  
   2.544  	s = talloc_realloc(NULL, s, char, s_len + len+1);
   2.545  	if (!s) return NULL;
   2.546 @@ -1133,11 +1251,45 @@ size_t talloc_get_size(const void *conte
   2.547  	return tc->size;
   2.548  }
   2.549  
   2.550 -talloc_fail_handler *talloc_set_fail_handler(talloc_fail_handler *handler,
   2.551 -					     void *data)
   2.552 +/*
   2.553 +  find a parent of this context that has the given name, if any
   2.554 +*/
   2.555 +void *talloc_find_parent_byname(const void *context, const char *name)
   2.556  {
   2.557 -	talloc_fail_handler *old = malloc_fail_handler;
   2.558 -	malloc_fail_handler = handler;
   2.559 -	malloc_fail_data = data;
   2.560 -	return old;
   2.561 +	struct talloc_chunk *tc;
   2.562 +
   2.563 +	if (context == NULL) {
   2.564 +		return NULL;
   2.565 +	}
   2.566 +
   2.567 +	tc = talloc_chunk_from_ptr(context);
   2.568 +	while (tc) {
   2.569 +		if (tc->name && strcmp(tc->name, name) == 0) {
   2.570 +			return TC_PTR_FROM_CHUNK(tc);
   2.571 +		}
   2.572 +		while (tc && tc->prev) tc = tc->prev;
   2.573 +		tc = tc->parent;
   2.574 +	}
   2.575 +	return NULL;
   2.576  }
   2.577 +
   2.578 +/*
   2.579 +  show the parentage of a context
   2.580 +*/
   2.581 +void talloc_show_parents(const void *context, FILE *file)
   2.582 +{
   2.583 +	struct talloc_chunk *tc;
   2.584 +
   2.585 +	if (context == NULL) {
   2.586 +		fprintf(file, "talloc no parents for NULL\n");
   2.587 +		return;
   2.588 +	}
   2.589 +
   2.590 +	tc = talloc_chunk_from_ptr(context);
   2.591 +	fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
   2.592 +	while (tc) {
   2.593 +		fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
   2.594 +		while (tc && tc->prev) tc = tc->prev;
   2.595 +		tc = tc->parent;
   2.596 +	}
   2.597 +}
     3.1 --- a/tools/xenstore/talloc.h	Thu Mar 23 14:26:38 2006 +0100
     3.2 +++ b/tools/xenstore/talloc.h	Thu Mar 23 14:32:15 2006 +0100
     3.3 @@ -6,19 +6,23 @@
     3.4  
     3.5     Copyright (C) Andrew Tridgell 2004-2005
     3.6     
     3.7 -   This program is free software; you can redistribute it and/or modify
     3.8 -   it under the terms of the GNU General Public License as published by
     3.9 -   the Free Software Foundation; either version 2 of the License, or
    3.10 -   (at your option) any later version.
    3.11 +     ** NOTE! The following LGPL license applies to the talloc
    3.12 +     ** library. This does NOT imply that all of Samba is released
    3.13 +     ** under the LGPL
    3.14     
    3.15 -   This program is distributed in the hope that it will be useful,
    3.16 +   This library is free software; you can redistribute it and/or
    3.17 +   modify it under the terms of the GNU Lesser General Public
    3.18 +   License as published by the Free Software Foundation; either
    3.19 +   version 2 of the License, or (at your option) any later version.
    3.20 +
    3.21 +   This library is distributed in the hope that it will be useful,
    3.22     but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.23 -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.24 -   GNU General Public License for more details.
    3.25 -   
    3.26 -   You should have received a copy of the GNU General Public License
    3.27 -   along with this program; if not, write to the Free Software
    3.28 -   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    3.29 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    3.30 +   Lesser General Public License for more details.
    3.31 +
    3.32 +   You should have received a copy of the GNU Lesser General Public
    3.33 +   License along with this library; if not, write to the Free Software
    3.34 +   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.35  */
    3.36  
    3.37  /* this is only needed for compatibility with the old talloc */
    3.38 @@ -58,13 +62,18 @@ typedef void TALLOC_CTX;
    3.39  #define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type), count)
    3.40  #define realloc_p(p, type, count) (type *)realloc_array(p, sizeof(type), count)
    3.41  
    3.42 +#if 0 
    3.43 +/* Not correct for Samba3. */
    3.44  #define data_blob(ptr, size) data_blob_named(ptr, size, "DATA_BLOB: "__location__)
    3.45  #define data_blob_talloc(ctx, ptr, size) data_blob_talloc_named(ctx, ptr, size, "DATA_BLOB: "__location__)
    3.46  #define data_blob_dup_talloc(ctx, blob) data_blob_talloc_named(ctx, (blob)->data, (blob)->length, "DATA_BLOB: "__location__)
    3.47 +#endif
    3.48  
    3.49  #define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
    3.50  #define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
    3.51  
    3.52 +#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type)
    3.53 +
    3.54  
    3.55  #if TALLOC_DEPRECATED
    3.56  #define talloc_zero_p(ctx, type) talloc_zero(ctx, type)
    3.57 @@ -117,6 +126,7 @@ void *_talloc_zero(const void *ctx, size
    3.58  void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
    3.59  char *talloc_strdup(const void *t, const char *p);
    3.60  char *talloc_strndup(const void *t, const char *p, size_t n);
    3.61 +char *talloc_append_string(const void *t, char *orig, const char *append);
    3.62  char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
    3.63  char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
    3.64  char *talloc_asprintf_append(char *s,
    3.65 @@ -127,8 +137,8 @@ void *_talloc_realloc_array(const void *
    3.66  void *talloc_realloc_fn(const void *context, void *ptr, size_t size);
    3.67  void *talloc_autofree_context(void);
    3.68  size_t talloc_get_size(const void *ctx);
    3.69 +void *talloc_find_parent_byname(const void *ctx, const char *name);
    3.70 +void talloc_show_parents(const void *context, FILE *file);
    3.71  
    3.72 -typedef int talloc_fail_handler(void *);
    3.73 -talloc_fail_handler *talloc_set_fail_handler(talloc_fail_handler *, void *);
    3.74  #endif
    3.75  
     4.1 --- a/tools/xenstore/xenstored_core.c	Thu Mar 23 14:26:38 2006 +0100
     4.2 +++ b/tools/xenstore/xenstored_core.c	Thu Mar 23 14:32:15 2006 +0100
     4.3 @@ -1231,39 +1231,17 @@ static void process_message(struct conne
     4.4  	conn->transaction = NULL;
     4.5  }
     4.6  
     4.7 -static int out_of_mem(void *data)
     4.8 -{
     4.9 -	longjmp(*(jmp_buf *)data, 1);
    4.10 -}
    4.11 -
    4.12  static void consider_message(struct connection *conn)
    4.13  {
    4.14 -	jmp_buf talloc_fail;
    4.15 -
    4.16  	if (verbose)
    4.17  		xprintf("Got message %s len %i from %p\n",
    4.18  			sockmsg_string(conn->in->hdr.msg.type),
    4.19  			conn->in->hdr.msg.len, conn);
    4.20  
    4.21 -	/* For simplicity, we kill the connection on OOM. */
    4.22 -	talloc_set_fail_handler(out_of_mem, &talloc_fail);
    4.23 -	if (setjmp(talloc_fail)) {
    4.24 -		talloc_free(conn);
    4.25 -		goto end;
    4.26 -	}
    4.27 -
    4.28  	process_message(conn, conn->in);
    4.29  
    4.30  	talloc_free(conn->in);
    4.31  	conn->in = new_buffer(conn);
    4.32 -
    4.33 -end:
    4.34 -	talloc_set_fail_handler(NULL, NULL);
    4.35 -	if (talloc_total_blocks(NULL)
    4.36 -	    != talloc_total_blocks(talloc_autofree_context()) + 1) {
    4.37 -		talloc_report_full(NULL, stderr);
    4.38 -		abort();
    4.39 -	}
    4.40  }
    4.41  
    4.42  /* Errors in reading or allocating here mean we get out of sync, so we