mirror of
https://github.com/postgres/postgres.git
synced 2026-02-23 18:04:41 -05:00
When we are using a C99-compliant vsnprintf implementation (which should be most places, these days) it is worth the trouble to make use of its report of how large the buffer needs to be to succeed. This patch adjusts stringinfo.c and some miscellaneous usages in pg_dump to do that, relying on the logic recently added in libpgcommon's psprintf.c. Since these places want to know the number of bytes written once we succeed, modify the API of pvsnprintf() to report that. There remains near-duplicate logic in pqexpbuffer.c, but since that code is in libpq, psprintf.c's approach of exit()-on-error isn't appropriate for use there. Also note that I didn't bother touching the multitude of places that call (v)snprintf without any attempt to provide a resizable buffer. Release-note-worthy incompatibility: the API of appendStringInfoVA() changed. If there's any third-party code that's calling that directly, it will need tweaking along the same lines as in this patch. David Rowley and Tom Lane
113 lines
4.1 KiB
C
113 lines
4.1 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* palloc.h
|
|
* POSTGRES memory allocator definitions.
|
|
*
|
|
* This file contains the basic memory allocation interface that is
|
|
* needed by almost every backend module. It is included directly by
|
|
* postgres.h, so the definitions here are automatically available
|
|
* everywhere. Keep it lean!
|
|
*
|
|
* Memory allocation occurs within "contexts". Every chunk obtained from
|
|
* palloc()/MemoryContextAlloc() is allocated within a specific context.
|
|
* The entire contents of a context can be freed easily and quickly by
|
|
* resetting or deleting the context --- this is both faster and less
|
|
* prone to memory-leakage bugs than releasing chunks individually.
|
|
* We organize contexts into context trees to allow fine-grain control
|
|
* over chunk lifetime while preserving the certainty that we will free
|
|
* everything that should be freed. See utils/mmgr/README for more info.
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/utils/palloc.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef PALLOC_H
|
|
#define PALLOC_H
|
|
|
|
/*
|
|
* Type MemoryContextData is declared in nodes/memnodes.h. Most users
|
|
* of memory allocation should just treat it as an abstract type, so we
|
|
* do not provide the struct contents here.
|
|
*/
|
|
typedef struct MemoryContextData *MemoryContext;
|
|
|
|
#ifndef FRONTEND
|
|
|
|
/*
|
|
* CurrentMemoryContext is the default allocation context for palloc().
|
|
* We declare it here so that palloc() can be a macro. Avoid accessing it
|
|
* directly! Instead, use MemoryContextSwitchTo() to change the setting.
|
|
*/
|
|
extern PGDLLIMPORT MemoryContext CurrentMemoryContext;
|
|
|
|
/*
|
|
* Fundamental memory-allocation operations (more are in utils/memutils.h)
|
|
*/
|
|
extern void *MemoryContextAlloc(MemoryContext context, Size size);
|
|
extern void *MemoryContextAllocZero(MemoryContext context, Size size);
|
|
extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size);
|
|
|
|
/* Higher-limit allocators. */
|
|
extern void *MemoryContextAllocHuge(MemoryContext context, Size size);
|
|
extern void *repalloc_huge(void *pointer, Size size);
|
|
|
|
/*
|
|
* The result of palloc() is always word-aligned, so we can skip testing
|
|
* alignment of the pointer when deciding which MemSet variant to use.
|
|
* Note that this variant does not offer any advantage, and should not be
|
|
* used, unless its "sz" argument is a compile-time constant; therefore, the
|
|
* issue that it evaluates the argument multiple times isn't a problem in
|
|
* practice.
|
|
*/
|
|
#define palloc0fast(sz) \
|
|
( MemSetTest(0, sz) ? \
|
|
MemoryContextAllocZeroAligned(CurrentMemoryContext, sz) : \
|
|
MemoryContextAllocZero(CurrentMemoryContext, sz) )
|
|
|
|
/*
|
|
* MemoryContextSwitchTo can't be a macro in standard C compilers.
|
|
* But we can make it an inline function if the compiler supports it.
|
|
* See STATIC_IF_INLINE in c.h.
|
|
*/
|
|
|
|
#ifndef PG_USE_INLINE
|
|
extern MemoryContext MemoryContextSwitchTo(MemoryContext context);
|
|
#endif /* !PG_USE_INLINE */
|
|
#if defined(PG_USE_INLINE) || defined(MCXT_INCLUDE_DEFINITIONS)
|
|
STATIC_IF_INLINE MemoryContext
|
|
MemoryContextSwitchTo(MemoryContext context)
|
|
{
|
|
MemoryContext old = CurrentMemoryContext;
|
|
|
|
CurrentMemoryContext = context;
|
|
return old;
|
|
}
|
|
#endif /* PG_USE_INLINE || MCXT_INCLUDE_DEFINITIONS */
|
|
|
|
/*
|
|
* These are like standard strdup() except the copied string is
|
|
* allocated in a context, not with malloc().
|
|
*/
|
|
extern char *MemoryContextStrdup(MemoryContext context, const char *string);
|
|
#endif /* !FRONTEND */
|
|
|
|
extern char *pstrdup(const char *in);
|
|
extern char *pnstrdup(const char *in, Size len);
|
|
|
|
/* basic memory allocation functions */
|
|
extern void *palloc(Size size);
|
|
extern void *palloc0(Size size);
|
|
extern void pfree(void *pointer);
|
|
extern void *repalloc(void *pointer, Size size);
|
|
|
|
/* sprintf into a palloc'd buffer --- these are in psprintf.c */
|
|
extern char *psprintf(const char *fmt,...)
|
|
__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
|
|
extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
|
|
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
|
|
|
|
#endif /* PALLOC_H */
|