mirror of
https://github.com/samba-team/samba.git
synced 2025-02-03 13:47:25 +03:00
merge latest versions of lib/replace, lib/talloc, lib/tdb and lib/events into ctdb bzr tree
(This used to be ctdb commit eaea8a9fa8d2f5e08f3af619fa1008a663f39053)
This commit is contained in:
parent
3a05ad1402
commit
169f129404
@ -13,25 +13,28 @@ srcdir = @srcdir@
|
||||
builddir = @builddir@
|
||||
EXTRA_OBJ=@EXTRA_OBJ@
|
||||
|
||||
CFLAGS=-g -I$(srcdir)/include -Iinclude -Ilib/util -I$(srcdir) \
|
||||
CFLAGS=-g -I$(srcdir)/include -Iinclude -Ilib -Ilib/util -I$(srcdir) \
|
||||
-I@tallocdir@ -I@tdbdir@/include -I@libreplacedir@ \
|
||||
-DVARDIR=\"$(localstatedir)\" -DUSE_MMAP=1 @CFLAGS@
|
||||
|
||||
LIB_FLAGS=@LDFLAGS@ -Llib @LIBS@ -lpopt @INFINIBAND_LIBS@
|
||||
|
||||
EVENTS_OBJ = lib/events/events.o lib/events/events_standard.o
|
||||
EVENTS_OBJ = lib/events/events.o lib/events/events_standard.o \
|
||||
lib/events/events_signal.o lib/events/events_timed.o
|
||||
|
||||
UTIL_OBJ = lib/util/idtree.o lib/util/db_wrap.o lib/util/strlist.o lib/util/util.o
|
||||
|
||||
CTDB_COMMON_OBJ = common/ctdb.o common/ctdb_daemon.o common/ctdb_client.o \
|
||||
common/ctdb_io.o common/util.o common/ctdb_util.o \
|
||||
common/ctdb_call.o common/ctdb_ltdb.o common/ctdb_lockwait.o \
|
||||
common/ctdb_message.o common/cmdline.o common/ctdb_control.o \
|
||||
lib/util/idtree.o lib/util/db_wrap.o lib/util/debug.o
|
||||
lib/util/debug.o
|
||||
|
||||
CTDB_TCP_OBJ = tcp/tcp_connect.o tcp/tcp_io.o tcp/tcp_init.o
|
||||
|
||||
CTDB_OBJ = $(CTDB_COMMON_OBJ) $(CTDB_TCP_OBJ)
|
||||
|
||||
OBJS = @TDBOBJ@ @TALLOCOBJ@ @LIBREPLACEOBJ@ @INFINIBAND_WRAPPER_OBJ@ $(EXTRA_OBJ) $(EVENTS_OBJ) $(CTDB_OBJ)
|
||||
OBJS = @TDB_OBJ@ @TALLOC_OBJ@ @LIBREPLACEOBJ@ @INFINIBAND_WRAPPER_OBJ@ $(EXTRA_OBJ) $(EVENTS_OBJ) $(CTDB_OBJ) $(UTIL_OBJ)
|
||||
|
||||
BINS = bin/ctdbd bin/ctdbd_test bin/ctdb_test bin/ctdb_bench bin/ctdb_messaging bin/ctdb_fetch bin/ctdb_fetch1 bin/lockwait bin/ctdb_control bin/ctdb_dump @INFINIBAND_BINS@
|
||||
|
||||
|
@ -36,4 +36,6 @@ _PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs);
|
||||
double timeval_elapsed(struct timeval *tv);
|
||||
char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx);
|
||||
char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len);
|
||||
_PUBLIC_ const char **str_list_add(const char **list, const char *s);
|
||||
_PUBLIC_ int set_blocking(int fd, BOOL set);
|
||||
|
||||
|
@ -1,2 +1,17 @@
|
||||
# check for EPOLL and native Linux AIO interface
|
||||
SMB_ENABLE(EVENTS_EPOLL, NO)
|
||||
SMB_ENABLE(EVENTS_AIO, NO)
|
||||
AC_CHECK_HEADERS(sys/epoll.h)
|
||||
AC_CHECK_FUNCS(epoll_create)
|
||||
if test x"$ac_cv_header_sys_epoll_h" = x"yes" -a x"$ac_cv_func_epoll_create" = x"yes";then
|
||||
SMB_ENABLE(EVENTS_EPOLL,YES)
|
||||
|
||||
# check for native Linux AIO interface
|
||||
AC_CHECK_HEADERS(libaio.h)
|
||||
AC_CHECK_LIB_EXT(aio, AIO_LIBS, io_getevents)
|
||||
if test x"$ac_cv_header_libaio_h" = x"yes" -a x"$ac_cv_lib_ext_aio_io_getevents" = x"yes";then
|
||||
SMB_ENABLE(EVENTS_AIO,YES)
|
||||
AC_DEFINE(HAVE_LINUX_AIO, 1, [Whether Linux AIO is available])
|
||||
fi
|
||||
fi
|
||||
SMB_EXT_LIB(LIBAIO_LINUX, $AIO_LIBS)
|
||||
|
@ -1,7 +1,38 @@
|
||||
##############################
|
||||
[MODULE::EVENTS_AIO]
|
||||
OBJ_FILES = events_aio.o
|
||||
PRIVATE_DEPENDENCIES = LIBAIO_LINUX
|
||||
SUBSYSTEM = LIBEVENTS
|
||||
INIT_FUNCTION = s4_events_aio_init
|
||||
##############################
|
||||
|
||||
##############################
|
||||
[MODULE::EVENTS_EPOLL]
|
||||
OBJ_FILES = events_epoll.o
|
||||
SUBSYSTEM = LIBEVENTS
|
||||
INIT_FUNCTION = s4_events_epoll_init
|
||||
##############################
|
||||
|
||||
##############################
|
||||
[MODULE::EVENTS_SELECT]
|
||||
OBJ_FILES = events_select.o
|
||||
SUBSYSTEM = LIBEVENTS
|
||||
INIT_FUNCTION = s4_events_select_init
|
||||
##############################
|
||||
|
||||
##############################
|
||||
[MODULE::EVENTS_STANDARD]
|
||||
OBJ_FILES = events_standard.o
|
||||
SUBSYSTEM = LIBEVENTS
|
||||
INIT_FUNCTION = s4_events_standard_init
|
||||
##############################
|
||||
|
||||
|
||||
##############################
|
||||
# Start SUBSYSTEM LIBEVENTS
|
||||
[SUBSYSTEM::LIBEVENTS]
|
||||
OBJ_FILES = events.o events_standard.o
|
||||
OBJ_FILES = events.o events_timed.o events_signal.o
|
||||
PUBLIC_HEADERS = events.h events_internal.h
|
||||
PUBLIC_DEPENDENCIES = LIBTALLOC
|
||||
# End SUBSYSTEM LIBEVENTS
|
||||
##############################
|
||||
|
@ -57,6 +57,70 @@
|
||||
#include "includes.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "lib/events/events_internal.h"
|
||||
#include "lib/util/dlinklist.h"
|
||||
#if _SAMBA_BUILD_
|
||||
#include "build.h"
|
||||
#endif
|
||||
|
||||
struct event_ops_list {
|
||||
struct event_ops_list *next, *prev;
|
||||
const char *name;
|
||||
const struct event_ops *ops;
|
||||
};
|
||||
|
||||
/* list of registered event backends */
|
||||
static struct event_ops_list *event_backends;
|
||||
|
||||
/*
|
||||
register an events backend
|
||||
*/
|
||||
bool event_register_backend(const char *name, const struct event_ops *ops)
|
||||
{
|
||||
struct event_ops_list *e;
|
||||
e = talloc(talloc_autofree_context(), struct event_ops_list);
|
||||
if (e == NULL) return False;
|
||||
e->name = name;
|
||||
e->ops = ops;
|
||||
DLIST_ADD(event_backends, e);
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
initialise backends if not already done
|
||||
*/
|
||||
static void event_backend_init(void)
|
||||
{
|
||||
#if _SAMBA_BUILD_
|
||||
init_module_fn static_init[] = STATIC_LIBEVENTS_MODULES;
|
||||
init_module_fn *shared_init;
|
||||
if (event_backends) return;
|
||||
shared_init = load_samba_modules(NULL, "LIBEVENTS");
|
||||
run_init_functions(static_init);
|
||||
run_init_functions(shared_init);
|
||||
#else
|
||||
bool events_standard_init(void);
|
||||
events_standard_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
list available backends
|
||||
*/
|
||||
const char **event_backend_list(TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
const char **list = NULL;
|
||||
struct event_ops_list *e;
|
||||
|
||||
event_backend_init();
|
||||
|
||||
for (e=event_backends;e;e=e->next) {
|
||||
list = str_list_add(list, e->name);
|
||||
}
|
||||
|
||||
talloc_steal(mem_ctx, list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
create a event_context structure for a specific implemementation.
|
||||
@ -69,7 +133,8 @@
|
||||
|
||||
NOTE: use event_context_init() inside of samba!
|
||||
*/
|
||||
struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct event_ops *ops, void *private_data)
|
||||
static struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx,
|
||||
const struct event_ops *ops)
|
||||
{
|
||||
struct event_context *ev;
|
||||
int ret;
|
||||
@ -79,7 +144,7 @@ struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct e
|
||||
|
||||
ev->ops = ops;
|
||||
|
||||
ret = ev->ops->context_init(ev, private_data);
|
||||
ret = ev->ops->context_init(ev);
|
||||
if (ret != 0) {
|
||||
talloc_free(ev);
|
||||
return NULL;
|
||||
@ -88,6 +153,35 @@ struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct e
|
||||
return ev;
|
||||
}
|
||||
|
||||
/*
|
||||
create a event_context structure. This must be the first events
|
||||
call, and all subsequent calls pass this event_context as the first
|
||||
element. Event handlers also receive this as their first argument.
|
||||
*/
|
||||
struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name)
|
||||
{
|
||||
struct event_ops_list *e;
|
||||
|
||||
event_backend_init();
|
||||
|
||||
#if _SAMBA_BUILD_
|
||||
if (name == NULL) {
|
||||
name = lp_parm_string(-1, "event", "backend");
|
||||
}
|
||||
#endif
|
||||
if (name == NULL) {
|
||||
name = "standard";
|
||||
}
|
||||
|
||||
for (e=event_backends;e;e=e->next) {
|
||||
if (strcmp(name, e->name) == 0) {
|
||||
return event_context_init_ops(mem_ctx, e->ops);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
create a event_context structure. This must be the first events
|
||||
call, and all subsequent calls pass this event_context as the first
|
||||
@ -95,8 +189,7 @@ struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct e
|
||||
*/
|
||||
struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
const struct event_ops *ops = event_standard_get_ops();
|
||||
return event_context_init_ops(mem_ctx, ops, NULL);
|
||||
return event_context_init_byname(mem_ctx, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -110,6 +203,19 @@ struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data);
|
||||
}
|
||||
|
||||
/*
|
||||
add a disk aio event
|
||||
*/
|
||||
struct aio_event *event_add_aio(struct event_context *ev,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct iocb *iocb,
|
||||
event_aio_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
if (ev->ops->add_aio == NULL) return NULL;
|
||||
return ev->ops->add_aio(ev, mem_ctx, iocb, handler, private_data);
|
||||
}
|
||||
|
||||
/*
|
||||
return the fd event flags
|
||||
*/
|
||||
@ -140,6 +246,22 @@ struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ct
|
||||
return ev->ops->add_timed(ev, mem_ctx, next_event, handler, private_data);
|
||||
}
|
||||
|
||||
/*
|
||||
add a signal event
|
||||
|
||||
sa_flags are flags to sigaction(2)
|
||||
|
||||
return NULL on failure
|
||||
*/
|
||||
struct signal_event *event_add_signal(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
int signum,
|
||||
int sa_flags,
|
||||
event_signal_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data);
|
||||
}
|
||||
|
||||
/*
|
||||
do a single event loop using the events defined in ev
|
||||
*/
|
||||
@ -168,7 +290,7 @@ int event_loop_wait(struct event_context *ev)
|
||||
struct event_context *event_context_find(TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
struct event_context *ev = talloc_find_parent_bytype(mem_ctx, struct event_context);
|
||||
if (ev == NULL) {
|
||||
if (ev == NULL) {
|
||||
ev = event_context_init(mem_ctx);
|
||||
}
|
||||
return ev;
|
||||
|
@ -23,19 +23,29 @@
|
||||
#ifndef __EVENTS_H__
|
||||
#define __EVENTS_H__
|
||||
|
||||
#include "talloc/talloc.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
struct event_context;
|
||||
struct event_ops;
|
||||
struct fd_event;
|
||||
struct timed_event;
|
||||
struct aio_event;
|
||||
struct signal_event;
|
||||
|
||||
/* event handler types */
|
||||
typedef void (*event_fd_handler_t)(struct event_context *, struct fd_event *,
|
||||
uint16_t , void *);
|
||||
typedef void (*event_timed_handler_t)(struct event_context *, struct timed_event *,
|
||||
struct timeval , void *);
|
||||
typedef void (*event_signal_handler_t)(struct event_context *, struct signal_event *,
|
||||
int , int, void *, void *);
|
||||
typedef void (*event_aio_handler_t)(struct event_context *, struct aio_event *,
|
||||
int, void *);
|
||||
|
||||
struct event_context *event_context_init(TALLOC_CTX *mem_ctx);
|
||||
struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct event_ops *ops, void *private_data);
|
||||
struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name);
|
||||
const char **event_backend_list(TALLOC_CTX *mem_ctx);
|
||||
|
||||
struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
int fd, uint16_t flags, event_fd_handler_t handler,
|
||||
@ -46,6 +56,18 @@ struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ct
|
||||
event_timed_handler_t handler,
|
||||
void *private);
|
||||
|
||||
struct signal_event *event_add_signal(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
int signum, int sa_flags,
|
||||
event_signal_handler_t handler,
|
||||
void *private);
|
||||
|
||||
struct iocb;
|
||||
struct aio_event *event_add_aio(struct event_context *ev,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct iocb *iocb,
|
||||
event_aio_handler_t handler,
|
||||
void *private);
|
||||
|
||||
int event_loop_once(struct event_context *ev);
|
||||
int event_loop_wait(struct event_context *ev);
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
struct event_ops {
|
||||
/* conntext init */
|
||||
int (*context_init)(struct event_context *ev, void *private_data);
|
||||
int (*context_init)(struct event_context *ev);
|
||||
|
||||
/* fd_event functions */
|
||||
struct fd_event *(*add_fd)(struct event_context *ev,
|
||||
@ -41,6 +41,18 @@ struct event_ops {
|
||||
struct timeval next_event,
|
||||
event_timed_handler_t handler,
|
||||
void *private_data);
|
||||
/* disk aio event functions */
|
||||
struct aio_event *(*add_aio)(struct event_context *ev,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct iocb *iocb,
|
||||
event_aio_handler_t handler,
|
||||
void *private_data);
|
||||
/* signal functions */
|
||||
struct signal_event *(*add_signal)(struct event_context *ev,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
int signum, int sa_flags,
|
||||
event_signal_handler_t handler,
|
||||
void *private_data);
|
||||
|
||||
/* loop functions */
|
||||
int (*loop_once)(struct event_context *ev);
|
||||
@ -71,11 +83,48 @@ struct timed_event {
|
||||
void *additional_data;
|
||||
};
|
||||
|
||||
struct signal_event {
|
||||
struct signal_event *prev, *next;
|
||||
struct event_context *event_ctx;
|
||||
event_signal_handler_t handler;
|
||||
void *private_data;
|
||||
int signum;
|
||||
int sa_flags;
|
||||
};
|
||||
|
||||
/* aio event is private to the aio backend */
|
||||
struct aio_event;
|
||||
|
||||
struct event_context {
|
||||
/* the specific events implementation */
|
||||
const struct event_ops *ops;
|
||||
|
||||
/* list of timed events - used by common code */
|
||||
struct timed_event *timed_events;
|
||||
|
||||
/* this is private for the events_ops implementation */
|
||||
void *additional_data;
|
||||
|
||||
/* number of signal event handlers */
|
||||
int num_signal_handlers;
|
||||
|
||||
/* pipe hack used with signal handlers */
|
||||
struct fd_event *pipe_fde;
|
||||
};
|
||||
|
||||
const struct event_ops *event_standard_get_ops(void);
|
||||
|
||||
bool event_register_backend(const char *name, const struct event_ops *ops);
|
||||
|
||||
struct timed_event *common_event_add_timed(struct event_context *, TALLOC_CTX *,
|
||||
struct timeval, event_timed_handler_t, void *);
|
||||
void common_event_loop_timer(struct event_context *);
|
||||
struct timeval common_event_loop_delay(struct event_context *);
|
||||
|
||||
struct signal_event *common_event_add_signal(struct event_context *ev,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
int signum,
|
||||
int sa_flags,
|
||||
event_signal_handler_t handler,
|
||||
void *private_data);
|
||||
int common_event_check_signal(struct event_context *ev);
|
||||
|
||||
|
@ -274,6 +274,7 @@ static const struct event_ops event_oop_ops = {
|
||||
.get_fd_flags = oop_event_get_fd_flags,
|
||||
.set_fd_flags = oop_event_set_fd_flags,
|
||||
.add_timed = oop_event_add_timed,
|
||||
.add_signal = common_event_add_signal,
|
||||
.loop_once = oop_event_loop_once,
|
||||
.loop_wait = oop_event_loop_wait,
|
||||
};
|
||||
|
@ -42,9 +42,6 @@ struct std_event_context {
|
||||
/* list of filedescriptor events */
|
||||
struct fd_event *fd_events;
|
||||
|
||||
/* list of timed events */
|
||||
struct timed_event *timed_events;
|
||||
|
||||
/* the maximum file descriptor number in fd_events */
|
||||
int maxfd;
|
||||
|
||||
@ -63,8 +60,6 @@ struct std_event_context {
|
||||
int epoll_fd;
|
||||
};
|
||||
|
||||
static void std_event_loop_timer(struct std_event_context *std_ev);
|
||||
|
||||
/* use epoll if it is available */
|
||||
#if WITH_EPOLL
|
||||
/*
|
||||
@ -103,9 +98,8 @@ static int epoll_ctx_destructor(struct std_event_context *std_ev)
|
||||
/*
|
||||
init the epoll fd
|
||||
*/
|
||||
static void epoll_init_ctx(struct std_event_context *std_ev, BOOL try_epoll)
|
||||
static void epoll_init_ctx(struct std_event_context *std_ev)
|
||||
{
|
||||
if (!try_epoll) return;
|
||||
std_ev->epoll_fd = epoll_create(64);
|
||||
talloc_set_destructor(std_ev, epoll_ctx_destructor);
|
||||
}
|
||||
@ -186,9 +180,9 @@ static void epoll_mod_event(struct std_event_context *std_ev, struct fd_event *f
|
||||
|
||||
static void epoll_change_event(struct std_event_context *std_ev, struct fd_event *fde)
|
||||
{
|
||||
BOOL got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
|
||||
BOOL want_read = (fde->flags & EVENT_FD_READ);
|
||||
BOOL want_write= (fde->flags & EVENT_FD_WRITE);
|
||||
bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
|
||||
bool want_read = (fde->flags & EVENT_FD_READ);
|
||||
bool want_write= (fde->flags & EVENT_FD_WRITE);
|
||||
|
||||
if (std_ev->epoll_fd == -1) return;
|
||||
|
||||
@ -225,7 +219,7 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
|
||||
int ret, i;
|
||||
#define MAXEVENTS 8
|
||||
struct epoll_event events[MAXEVENTS];
|
||||
uint32_t destruction_count = std_ev->destruction_count;
|
||||
uint32_t destruction_count = ++std_ev->destruction_count;
|
||||
int timeout = -1;
|
||||
|
||||
if (std_ev->epoll_fd == -1) return -1;
|
||||
@ -235,15 +229,26 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
|
||||
timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000);
|
||||
}
|
||||
|
||||
if (epoll_ev->ev->num_signal_handlers &&
|
||||
common_event_check_signal(epoll_ev->ev)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
|
||||
|
||||
if (ret == -1 && errno == EINTR && epoll_ev->ev->num_signal_handlers) {
|
||||
if (common_event_check_signal(epoll_ev->ev)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == -1 && errno != EINTR) {
|
||||
epoll_fallback_to_select(std_ev, "epoll_wait() failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == 0 && tvalp) {
|
||||
std_event_loop_timer(std_ev);
|
||||
common_event_loop_timer(std_ev->ev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -283,7 +288,7 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define epoll_init_ctx(std_ev,try_epoll) if (try_epoll) {/* fix unused variable warning*/}
|
||||
#define epoll_init_ctx(std_ev)
|
||||
#define epoll_add_event(std_ev,fde)
|
||||
#define epoll_del_event(std_ev,fde)
|
||||
#define epoll_change_event(std_ev,fde)
|
||||
@ -293,18 +298,16 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
|
||||
/*
|
||||
create a std_event_context structure.
|
||||
*/
|
||||
static int std_event_context_init(struct event_context *ev, void *private_data)
|
||||
static int std_event_context_init(struct event_context *ev)
|
||||
{
|
||||
struct std_event_context *std_ev;
|
||||
BOOL *_try_epoll = private_data;
|
||||
BOOL try_epoll = (_try_epoll == NULL ? True : *_try_epoll);
|
||||
|
||||
std_ev = talloc_zero(ev, struct std_event_context);
|
||||
if (!std_ev) return -1;
|
||||
std_ev->ev = ev;
|
||||
std_ev->epoll_fd = -1;
|
||||
|
||||
epoll_init_ctx(std_ev, try_epoll);
|
||||
epoll_init_ctx(std_ev);
|
||||
|
||||
ev->additional_data = std_ev;
|
||||
return 0;
|
||||
@ -379,8 +382,8 @@ static struct fd_event *std_event_add_fd(struct event_context *ev, TALLOC_CTX *m
|
||||
DLIST_ADD(std_ev->fd_events, fde);
|
||||
if ((std_ev->maxfd != EVENT_INVALID_MAXFD)
|
||||
&& (fde->fd > std_ev->maxfd)) {
|
||||
std_ev->maxfd = fde->fd;
|
||||
}
|
||||
std_ev->maxfd = fde->fd;
|
||||
}
|
||||
talloc_set_destructor(fde, std_event_fd_destructor);
|
||||
|
||||
epoll_add_event(std_ev, fde);
|
||||
@ -415,93 +418,6 @@ static void std_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
|
||||
epoll_change_event(std_ev, fde);
|
||||
}
|
||||
|
||||
/*
|
||||
destroy a timed event
|
||||
*/
|
||||
static int std_event_timed_destructor(struct timed_event *te)
|
||||
{
|
||||
struct std_event_context *std_ev = talloc_get_type(te->event_ctx->additional_data,
|
||||
struct std_event_context);
|
||||
DLIST_REMOVE(std_ev->timed_events, te);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int std_event_timed_deny_destructor(struct timed_event *te)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
add a timed event
|
||||
return NULL on failure (memory allocation error)
|
||||
*/
|
||||
static struct timed_event *std_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
struct timeval next_event,
|
||||
event_timed_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
|
||||
struct std_event_context);
|
||||
struct timed_event *te, *last_te, *cur_te;
|
||||
|
||||
te = talloc(mem_ctx?mem_ctx:ev, struct timed_event);
|
||||
if (te == NULL) return NULL;
|
||||
|
||||
te->event_ctx = ev;
|
||||
te->next_event = next_event;
|
||||
te->handler = handler;
|
||||
te->private_data = private_data;
|
||||
te->additional_data = NULL;
|
||||
|
||||
/* keep the list ordered */
|
||||
last_te = NULL;
|
||||
for (cur_te = std_ev->timed_events; cur_te; cur_te = cur_te->next) {
|
||||
/* if the new event comes before the current one break */
|
||||
if (!timeval_is_zero(&cur_te->next_event) &&
|
||||
timeval_compare(&te->next_event,
|
||||
&cur_te->next_event) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
last_te = cur_te;
|
||||
}
|
||||
|
||||
DLIST_ADD_AFTER(std_ev->timed_events, te, last_te);
|
||||
|
||||
talloc_set_destructor(te, std_event_timed_destructor);
|
||||
|
||||
return te;
|
||||
}
|
||||
|
||||
/*
|
||||
a timer has gone off - call it
|
||||
*/
|
||||
static void std_event_loop_timer(struct std_event_context *std_ev)
|
||||
{
|
||||
struct timeval t = timeval_current();
|
||||
struct timed_event *te = std_ev->timed_events;
|
||||
|
||||
if (te == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* deny the handler to free the event */
|
||||
talloc_set_destructor(te, std_event_timed_deny_destructor);
|
||||
|
||||
/* We need to remove the timer from the list before calling the
|
||||
* handler because in a semi-async inner event loop called from the
|
||||
* handler we don't want to come across this event again -- vl */
|
||||
DLIST_REMOVE(std_ev->timed_events, te);
|
||||
|
||||
te->handler(std_ev->ev, te, t, te->private_data);
|
||||
|
||||
/* The destructor isn't necessary anymore, we've already removed the
|
||||
* event from the list. */
|
||||
talloc_set_destructor(te, NULL);
|
||||
|
||||
talloc_free(te);
|
||||
}
|
||||
|
||||
/*
|
||||
event loop handling using select()
|
||||
*/
|
||||
@ -510,7 +426,7 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
|
||||
fd_set r_fds, w_fds;
|
||||
struct fd_event *fde;
|
||||
int selrtn;
|
||||
uint32_t destruction_count = std_ev->destruction_count;
|
||||
uint32_t destruction_count = ++std_ev->destruction_count;
|
||||
|
||||
/* we maybe need to recalculate the maxfd */
|
||||
if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
|
||||
@ -530,8 +446,19 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
|
||||
}
|
||||
}
|
||||
|
||||
if (std_ev->ev->num_signal_handlers &&
|
||||
common_event_check_signal(std_ev->ev)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
|
||||
|
||||
if (selrtn == -1 && errno == EINTR &&
|
||||
std_ev->ev->num_signal_handlers) {
|
||||
common_event_check_signal(std_ev->ev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (selrtn == -1 && errno == EBADF) {
|
||||
/* the socket is dead! this should never
|
||||
happen as the socket should have first been
|
||||
@ -544,7 +471,7 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
|
||||
}
|
||||
|
||||
if (selrtn == 0 && tvalp) {
|
||||
std_event_loop_timer(std_ev);
|
||||
common_event_loop_timer(std_ev->ev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -578,19 +505,11 @@ static int std_event_loop_once(struct event_context *ev)
|
||||
struct std_event_context);
|
||||
struct timeval tval;
|
||||
|
||||
/* work out the right timeout for all timed events */
|
||||
if (std_ev->timed_events) {
|
||||
struct timeval t = timeval_current();
|
||||
tval = timeval_until(&t, &std_ev->timed_events->next_event);
|
||||
if (timeval_is_zero(&tval)) {
|
||||
std_event_loop_timer(std_ev);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* have a default tick time of 30 seconds. This guarantees
|
||||
that code that uses its own timeout checking will be
|
||||
able to proceeed eventually */
|
||||
tval = timeval_set(30, 0);
|
||||
tval = common_event_loop_delay(ev);
|
||||
|
||||
if (timeval_is_zero(&tval)) {
|
||||
common_event_loop_timer(ev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (epoll_event_loop(std_ev, &tval) == 0) {
|
||||
@ -623,12 +542,24 @@ static const struct event_ops std_event_ops = {
|
||||
.add_fd = std_event_add_fd,
|
||||
.get_fd_flags = std_event_get_fd_flags,
|
||||
.set_fd_flags = std_event_set_fd_flags,
|
||||
.add_timed = std_event_add_timed,
|
||||
.add_timed = common_event_add_timed,
|
||||
.add_signal = common_event_add_signal,
|
||||
.loop_once = std_event_loop_once,
|
||||
.loop_wait = std_event_loop_wait,
|
||||
};
|
||||
|
||||
const struct event_ops *event_standard_get_ops(void)
|
||||
|
||||
bool events_standard_init(void)
|
||||
{
|
||||
return &std_event_ops;
|
||||
return event_register_backend("standard", &std_event_ops);
|
||||
}
|
||||
|
||||
#if _SAMBA_BUILD_
|
||||
NTSTATUS s4_events_standard_init(void)
|
||||
{
|
||||
if (!events_standard_init()) {
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
|
@ -11,9 +11,9 @@ srcdir = @srcdir@
|
||||
builddir = @builddir@
|
||||
INSTALL = @INSTALL@
|
||||
|
||||
.PHONY: test
|
||||
.PHONY: test all showflags install installcheck clean distclean realdistclean
|
||||
|
||||
CFLAGS=-I. -I@libreplacedir@ @CFLAGS@
|
||||
CFLAGS=-I. @CFLAGS@
|
||||
|
||||
OBJS = @LIBREPLACEOBJ@
|
||||
|
||||
@ -37,7 +37,7 @@ test: all
|
||||
|
||||
installcheck: install test
|
||||
|
||||
TEST_OBJS = test/testsuite.o test/os2_delete.o
|
||||
TEST_OBJS = test/testsuite.o test/os2_delete.o test/strptime.o
|
||||
|
||||
testsuite: libreplace.a $(TEST_OBJS)
|
||||
$(CC) -o testsuite $(TEST_OBJS) -L. -lreplace
|
||||
|
@ -12,7 +12,6 @@ strlcpy
|
||||
strlcat
|
||||
mktime
|
||||
rename
|
||||
innetgr
|
||||
initgroups
|
||||
memmove
|
||||
strdup
|
||||
@ -21,6 +20,7 @@ setlinebuf
|
||||
vsyslog
|
||||
timegm
|
||||
setenv
|
||||
unsetenv
|
||||
strndup
|
||||
strnlen
|
||||
waitpid
|
||||
@ -53,6 +53,7 @@ inet_ntoa
|
||||
strtoll
|
||||
strtoull
|
||||
socketpair
|
||||
strptime
|
||||
|
||||
Types:
|
||||
bool
|
||||
@ -76,13 +77,27 @@ CHAR_BIT
|
||||
Macros:
|
||||
va_copy
|
||||
__FUNCTION__
|
||||
__FILE__
|
||||
__LINE__
|
||||
__LINESTR__
|
||||
__location__
|
||||
__STRING
|
||||
__STRINGSTRING
|
||||
MIN
|
||||
MAX
|
||||
QSORT_CAST
|
||||
ZERO_STRUCT
|
||||
ZERO_STRUCTP
|
||||
ZERO_STRUCTPN
|
||||
ZERO_ARRAY
|
||||
ARRAY_SIZE
|
||||
PTR_DIFF
|
||||
|
||||
Headers:
|
||||
stdint.h
|
||||
stdbool.h
|
||||
|
||||
Prerequisites:
|
||||
memset (for bzero)
|
||||
syslog (for vsyslog)
|
||||
setnetgrent, getnetgrent, endnetgrent (for innetgr)
|
||||
mktemp (for mkstemp and mkdtemp)
|
||||
|
@ -61,9 +61,12 @@ AC_FUNC_MEMCMP
|
||||
|
||||
AC_CHECK_FUNCS(pipe strftime srandom random srand rand usleep setbuffer lstat getpgrp)
|
||||
|
||||
AC_CHECK_HEADERS(stdbool.h sys/select.h)
|
||||
AC_CHECK_HEADERS(stdbool.h stdint.h sys/select.h)
|
||||
AC_CHECK_HEADERS(setjmp.h)
|
||||
|
||||
LIBREPLACE_PROVIDE_HEADER([stdint.h])
|
||||
LIBREPLACE_PROVIDE_HEADER([stdbool.h])
|
||||
|
||||
AC_CHECK_TYPE(bool,
|
||||
[AC_DEFINE(HAVE_BOOL, 1, [Whether the bool type is available])],,
|
||||
[
|
||||
@ -147,7 +150,7 @@ AC_TRY_COMPILE([
|
||||
|
||||
AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror)
|
||||
AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename)
|
||||
AC_CHECK_FUNCS(waitpid strlcpy strlcat innetgr initgroups memmove strdup)
|
||||
AC_CHECK_FUNCS(waitpid strlcpy strlcat initgroups memmove strdup)
|
||||
AC_CHECK_FUNCS(pread pwrite strndup strcasestr strtok_r mkdtemp socketpair)
|
||||
AC_HAVE_DECL(setresuid, [#include <unistd.h>])
|
||||
AC_HAVE_DECL(setresgid, [#include <unistd.h>])
|
||||
@ -260,7 +263,10 @@ AC_CHECK_HEADERS([sys/param.h limits.h])
|
||||
AC_CHECK_TYPE(comparison_fn_t,
|
||||
[AC_DEFINE(HAVE_COMPARISON_FN_T, 1,[Whether or not we have comparison_fn_t])])
|
||||
|
||||
AC_CHECK_FUNCS(strnlen setenv)
|
||||
AC_HAVE_DECL(setenv, [#include <stdlib.h>])
|
||||
AC_CHECK_FUNCS(setenv unsetenv)
|
||||
|
||||
AC_CHECK_FUNCS(strnlen)
|
||||
AC_CHECK_FUNCS(strtoull __strtoull strtouq strtoll __strtoll strtoq)
|
||||
|
||||
# this test disabled as we don't actually need __VA_ARGS__ yet
|
||||
@ -323,12 +329,12 @@ m4_include(system/config.m4)
|
||||
|
||||
m4_include(dlfcn.m4)
|
||||
m4_include(getpass.m4)
|
||||
m4_include(strptime.m4)
|
||||
m4_include(win32.m4)
|
||||
m4_include(timegm.m4)
|
||||
m4_include(repdir.m4)
|
||||
|
||||
AC_CHECK_FUNCS([syslog memset setnetgrent getnetgrent endnetgrent memcpy],,
|
||||
[AC_MSG_ERROR([Required function not found])])
|
||||
AC_CHECK_FUNCS([syslog memset memcpy],,[AC_MSG_ERROR([Required function not found])])
|
||||
|
||||
echo "LIBREPLACE_BROKEN_CHECKS: END"
|
||||
]) dnl end AC_LIBREPLACE_BROKEN_CHECKS
|
||||
@ -348,6 +354,7 @@ AC_LIBREPLACE_LOCATION_CHECKS
|
||||
AC_LIBREPLACE_CC_CHECKS
|
||||
AC_LIBREPLACE_BROKEN_CHECKS
|
||||
AC__LIBREPLACE_ALL_CHECKS_END
|
||||
CFLAGS="$CFLAGS -I$libreplacedir"
|
||||
])
|
||||
|
||||
m4_include(libreplace_cc.m4)
|
||||
|
@ -306,3 +306,12 @@ AC_DEFUN(AC_VERIFY_C_PROTOTYPE,
|
||||
)
|
||||
AS_IF([test $AS_TR_SH([ac_cv_c_prototype_$1]) = yes],[$3],[$4])
|
||||
])
|
||||
|
||||
AC_DEFUN(LIBREPLACE_PROVIDE_HEADER,
|
||||
[AC_CHECK_HEADER([$1],
|
||||
[ AC_CONFIG_COMMANDS(rm-$1, [rm -f $libreplacedir/$1], [libreplacedir=$libreplacedir]) ],
|
||||
[ AC_CONFIG_COMMANDS(mk-$1, [echo "#include \"replace.h\"" > $libreplacedir/$1], [libreplacedir=$libreplacedir]) ]
|
||||
)
|
||||
])
|
||||
|
||||
|
||||
|
@ -154,33 +154,6 @@ time_t rep_mktime(struct tm *t)
|
||||
#endif /* !HAVE_MKTIME */
|
||||
|
||||
|
||||
#ifndef HAVE_INNETGR
|
||||
#if defined(HAVE_SETNETGRENT) && defined(HAVE_GETNETGRENT) && defined(HAVE_ENDNETGRENT)
|
||||
/*
|
||||
* Search for a match in a netgroup. This replaces it on broken systems.
|
||||
*/
|
||||
int rep_innetgr(const char *group, const char *host, const char *user,
|
||||
const char *dom)
|
||||
{
|
||||
char *hst, *usr, *dm;
|
||||
|
||||
setnetgrent(group);
|
||||
while (getnetgrent(&hst, &usr, &dm)) {
|
||||
if (((host == 0) || (hst == 0) || !strcmp(host, hst)) &&
|
||||
((user == 0) || (usr == 0) || !strcmp(user, usr)) &&
|
||||
((dom == 0) || (dm == 0) || !strcmp(dom, dm))) {
|
||||
endnetgrent();
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
endnetgrent();
|
||||
return (0);
|
||||
}
|
||||
#endif /* HAVE_SETNETGRENT HAVE_GETNETGRENT HAVE_ENDNETGRENT */
|
||||
#endif /* HAVE_INNETGR */
|
||||
|
||||
|
||||
|
||||
#ifndef HAVE_INITGROUPS
|
||||
/****************************************************************************
|
||||
some systems don't have an initgroups call
|
||||
@ -590,6 +563,32 @@ int rep_setenv(const char *name, const char *value, int overwrite)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_UNSETENV
|
||||
int rep_unsetenv(const char *name)
|
||||
{
|
||||
extern char **environ;
|
||||
size_t len = strlen(name);
|
||||
size_t i;
|
||||
int found = 0;
|
||||
|
||||
for (i=0; (environ && environ[i]); i++) {
|
||||
if (found) {
|
||||
environ[i-1] = environ[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
|
||||
free(environ[i]);
|
||||
environ[i] = NULL;
|
||||
found = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SOCKETPAIR
|
||||
int rep_socketpair(int d, int type, int protocol, int sv[2])
|
||||
{
|
||||
|
@ -79,6 +79,29 @@
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
this is a warning hack. The idea is to use this everywhere that we
|
||||
get the "discarding const" warning from gcc. That doesn't actually
|
||||
fix the problem of course, but it means that when we do get to
|
||||
cleaning them up we can do it by searching the code for
|
||||
discard_const.
|
||||
|
||||
It also means that other error types aren't as swamped by the noise
|
||||
of hundreds of const warnings, so we are more likely to notice when
|
||||
we get new errors.
|
||||
|
||||
Please only add more uses of this macro when you find it
|
||||
_really_ hard to fix const warnings. Our aim is to eventually use
|
||||
this function in only a very few places.
|
||||
|
||||
Also, please call this via the discard_const_p() macro interface, as that
|
||||
makes the return type safe.
|
||||
*/
|
||||
#define discard_const(ptr) ((void *)((intptr_t)(ptr)))
|
||||
|
||||
/** Type-safe version of discard_const */
|
||||
#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
|
||||
|
||||
#ifndef HAVE_STRERROR
|
||||
extern char *sys_errlist[];
|
||||
#define strerror(i) sys_errlist[i]
|
||||
@ -137,7 +160,16 @@ size_t rep_strnlen(const char *s, size_t n);
|
||||
|
||||
#ifndef HAVE_SETENV
|
||||
#define setenv rep_setenv
|
||||
int rep_setenv(const char *name, const char *value, int overwrite);
|
||||
int rep_setenv(const char *name, const char *value, int overwrite);
|
||||
#else
|
||||
#ifndef HAVE_SETENV_DECL
|
||||
int setenv(const char *name, const char *value, int overwrite);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_UNSETENV
|
||||
#define unsetenv rep_unsetenv
|
||||
int rep_unsetenv(const char *name);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SETEUID
|
||||
@ -275,6 +307,12 @@ void rep_vsyslog (int facility_priority, const char *format, va_list arglist) PR
|
||||
typedef int (*comparison_fn_t)(const void *, const void *);
|
||||
#endif
|
||||
|
||||
#ifdef REPLACE_STRPTIME
|
||||
#define strptime rep_strptime
|
||||
struct tm;
|
||||
char *rep_strptime(const char *buf, const char *format, struct tm *tm);
|
||||
#endif
|
||||
|
||||
/* Load header file for dynamic linking stuff */
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
@ -401,6 +439,47 @@ typedef int bool;
|
||||
#define __STRING(x) #x
|
||||
#endif
|
||||
|
||||
#ifndef _STRINGSTRING
|
||||
#define __STRINGSTRING(x) __STRING(x)
|
||||
#endif
|
||||
|
||||
#ifndef __LINESTR__
|
||||
#define __LINESTR__ __STRINGSTRING(__LINE__)
|
||||
#endif
|
||||
|
||||
#ifndef __location__
|
||||
#define __location__ __FILE__ ":" __LINESTR__
|
||||
#endif
|
||||
|
||||
/**
|
||||
* zero a structure
|
||||
*/
|
||||
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
|
||||
|
||||
/**
|
||||
* zero a structure given a pointer to the structure
|
||||
*/
|
||||
#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
|
||||
|
||||
/**
|
||||
* zero a structure given a pointer to the structure - no zero check
|
||||
*/
|
||||
#define ZERO_STRUCTPN(x) memset((char *)(x), 0, sizeof(*(x)))
|
||||
|
||||
/* zero an array - note that sizeof(array) must work - ie. it must not be a
|
||||
pointer */
|
||||
#define ZERO_ARRAY(x) memset((char *)(x), 0, sizeof(x))
|
||||
|
||||
/**
|
||||
* work out how many elements there are in a static array
|
||||
*/
|
||||
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
/**
|
||||
* pointer difference macro
|
||||
*/
|
||||
#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2)))
|
||||
|
||||
#if MMAP_BLACKLIST
|
||||
#undef HAVE_MMAP
|
||||
#endif
|
||||
|
@ -3,8 +3,16 @@ AC_LIBREPLACE_BROKEN_CHECKS
|
||||
SMB_EXT_LIB(LIBREPLACE_EXT, [${LIBDL}])
|
||||
SMB_ENABLE(LIBREPLACE_EXT)
|
||||
|
||||
# remove leading ./
|
||||
LIBREPLACE_DIR=`echo ${libreplacedir} |sed -e 's/^\.\///g'`
|
||||
|
||||
# remove leading srcdir .. we are looking for the relative
|
||||
# path within the samba source tree or wherever libreplace is.
|
||||
# We need to make sure the object is not forced to end up in
|
||||
# the source directory because we might be using a separate
|
||||
# build directory.
|
||||
LIBREPLACE_DIR=`echo ${LIBREPLACE_DIR} | sed -e "s|^$srcdir/||g"`
|
||||
|
||||
LIBREPLACE_OBJS=""
|
||||
for obj in ${LIBREPLACEOBJ}; do
|
||||
LIBREPLACE_OBJS="${LIBREPLACE_OBJS} ${LIBREPLACE_DIR}/${obj}"
|
||||
|
@ -742,6 +742,8 @@ static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in
|
||||
ret = currlen;
|
||||
|
||||
done:
|
||||
va_end(args);
|
||||
|
||||
while (chunks) {
|
||||
cnk = chunks->next;
|
||||
free(chunks);
|
||||
@ -1260,16 +1262,16 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
|
||||
va_list ap2;
|
||||
|
||||
VA_COPY(ap2, ap);
|
||||
|
||||
ret = vsnprintf(NULL, 0, format, ap2);
|
||||
va_end(ap2);
|
||||
if (ret <= 0) return ret;
|
||||
|
||||
(*ptr) = (char *)malloc(ret+1);
|
||||
if (!*ptr) return -1;
|
||||
|
||||
VA_COPY(ap2, ap);
|
||||
|
||||
ret = vsnprintf(*ptr, ret+1, format, ap2);
|
||||
va_end(ap2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
# filesys
|
||||
AC_HEADER_DIRENT
|
||||
AC_CHECK_HEADERS(fcntl.h sys/fcntl.h sys/acl.h sys/resource.h sys/ioctl.h sys/mode.h sys/filio.h sys/fs/s5param.h sys/filsys.h )
|
||||
AC_CHECK_HEADERS(fcntl.h sys/fcntl.h sys/resource.h sys/ioctl.h sys/mode.h sys/filio.h sys/fs/s5param.h sys/filsys.h)
|
||||
AC_CHECK_HEADERS(sys/acl.h acl/libacl.h)
|
||||
|
||||
# select
|
||||
AC_CHECK_HEADERS(sys/select.h)
|
||||
|
@ -41,6 +41,10 @@
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ACL_LIBACL_H
|
||||
#include <acl/libacl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_FS_S5PARAM_H
|
||||
#include <sys/fs/s5param.h>
|
||||
#endif
|
||||
|
@ -12,12 +12,12 @@ builddir = @builddir@
|
||||
XSLTPROC = @XSLTPROC@
|
||||
INSTALLCMD = @INSTALL@
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@ -DHAVE_CONFIG_H= -I. -I@srcdir@ -I@libreplacedir@
|
||||
CFLAGS = @CFLAGS@ -DHAVE_CONFIG_H= -I. -I@srcdir@
|
||||
EXTRA_TARGETS = @DOC_TARGET@
|
||||
|
||||
.SUFFIXES: .c .o .3 .3.xml .xml .html
|
||||
|
||||
LIBOBJ = @TALLOCOBJ@ @LIBREPLACEOBJ@
|
||||
LIBOBJ = @TALLOC_OBJ@ @LIBREPLACEOBJ@
|
||||
|
||||
all: showflags libtalloc.a testsuite $(EXTRA_TARGETS)
|
||||
|
||||
@ -34,13 +34,14 @@ libtalloc.a: $(LIBOBJ)
|
||||
@-ranlib $@
|
||||
|
||||
install: all
|
||||
${INSTALLCMD} -d ${libdir}
|
||||
${INSTALLCMD} -m 755 libtalloc.a $(libdir)
|
||||
${INSTALLCMD} -d ${includedir}
|
||||
${INSTALLCMD} -m 644 $(srcdir)/talloc.h $(includedir)
|
||||
${INSTALLCMD} -m 644 talloc.pc $(libdir)/pkgconfig
|
||||
if [ -f talloc.3 ];then ${INSTALLCMD} -d ${mandir}/man3; fi
|
||||
if [ -f talloc.3 ];then ${INSTALLCMD} -m 644 talloc.3 $(mandir)/man3; fi
|
||||
${INSTALLCMD} -d $(DESTDIR)$(libdir)
|
||||
${INSTALLCMD} -d $(DESTDIR)$(libdir)/pkgconfig
|
||||
${INSTALLCMD} -m 755 libtalloc.a $(DESTDIR)$(libdir)
|
||||
${INSTALLCMD} -d $(DESTDIR)${includedir}
|
||||
${INSTALLCMD} -m 644 $(srcdir)/talloc.h $(DESTDIR)$(includedir)
|
||||
${INSTALLCMD} -m 644 talloc.pc $(DESTDIR)$(libdir)/pkgconfig
|
||||
if [ -f talloc.3 ];then ${INSTALLCMD} -d $(DESTDIR)$(mandir)/man3; fi
|
||||
if [ -f talloc.3 ];then ${INSTALLCMD} -m 644 talloc.3 $(DESTDIR)$(mandir)/man3; fi
|
||||
|
||||
doc: talloc.3 talloc.3.html
|
||||
|
||||
|
@ -77,9 +77,6 @@
|
||||
/* Define to 1 if you have the `endnetgrent' function. */
|
||||
#undef HAVE_ENDNETGRENT
|
||||
|
||||
/* Define to 1 if you have the `epoll_create' function. */
|
||||
#undef HAVE_EPOLL_CREATE
|
||||
|
||||
/* Whether errno() is available */
|
||||
#undef HAVE_ERRNO_DECL
|
||||
|
||||
@ -224,6 +221,9 @@
|
||||
/* Define to 1 if you have the `seteuid' function. */
|
||||
#undef HAVE_SETEUID
|
||||
|
||||
/* Define to 1 if you have the <setjmp.h> header file. */
|
||||
#undef HAVE_SETJMP_H
|
||||
|
||||
/* Define to 1 if you have the `setlinebuf' function. */
|
||||
#undef HAVE_SETLINEBUF
|
||||
|
||||
@ -346,9 +346,6 @@
|
||||
*/
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
#undef HAVE_SYS_EPOLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/fcntl.h> header file. */
|
||||
#undef HAVE_SYS_FCNTL_H
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(talloc.h)
|
||||
AC_INIT(talloc, 1.0)
|
||||
AC_CONFIG_SRCDIR([talloc.c])
|
||||
AC_SUBST(datarootdir)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
@ -12,8 +12,14 @@ done
|
||||
if test x"$tallocdir" = "x"; then
|
||||
AC_MSG_ERROR([cannot find talloc source in $tallocpaths])
|
||||
fi
|
||||
TALLOCOBJ="talloc.o"
|
||||
AC_SUBST(TALLOCOBJ)
|
||||
TALLOC_OBJ="talloc.o"
|
||||
AC_SUBST(TALLOC_OBJ)
|
||||
|
||||
TALLOC_CFLAGS="-I$tallocdir"
|
||||
AC_SUBST(TALLOC_CFLAGS)
|
||||
|
||||
TALLOC_LIBS=""
|
||||
AC_SUBST(TALLOC_LIBS)
|
||||
|
||||
AC_CHECK_SIZEOF(size_t,cross)
|
||||
AC_CHECK_SIZEOF(void *,cross)
|
||||
|
@ -1,11 +1,11 @@
|
||||
.\" Title: talloc
|
||||
.\" Author:
|
||||
.\" Generator: DocBook XSL Stylesheets v1.71.0 <http://docbook.sf.net/>
|
||||
.\" Date: 12/09/2006
|
||||
.\" Date: 02/26/2007
|
||||
.\" Manual:
|
||||
.\" Source:
|
||||
.\"
|
||||
.TH "TALLOC" "3" "12/09/2006" "" ""
|
||||
.TH "TALLOC" "3" "02/26/2007" "" ""
|
||||
.\" disable hyphenation
|
||||
.nh
|
||||
.\" disable justification (adjust text to left margin only)
|
||||
|
@ -1,4 +1,4 @@
|
||||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>talloc</title><meta name="generator" content="DocBook XSL Stylesheets V1.71.0"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en"><a name="id2478266"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>talloc — hierarchical reference counted memory pool system with destructors</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">#include <talloc/talloc.h></pre></div><div class="refsect1" lang="en"><a name="id2517036"></a><h2>DESCRIPTION</h2><p>
|
||||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>talloc</title><meta name="generator" content="DocBook XSL Stylesheets V1.71.0"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en"><a name="id2478730"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>talloc — hierarchical reference counted memory pool system with destructors</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">#include <talloc/talloc.h></pre></div><div class="refsect1" lang="en"><a name="id2517362"></a><h2>DESCRIPTION</h2><p>
|
||||
If you are used to talloc from Samba3 then please read this
|
||||
carefully, as talloc has changed a lot.
|
||||
</p><p>
|
||||
@ -30,10 +30,10 @@
|
||||
If you find this confusing, then I suggest you run the <code class="literal">testsuite</code> program to watch talloc
|
||||
in action. You may also like to add your own tests to <code class="literal">testsuite.c</code> to clarify how some
|
||||
particular situation is handled.
|
||||
</p></div><div class="refsect1" lang="en"><a name="id2478366"></a><h2>TALLOC API</h2><p>
|
||||
</p></div><div class="refsect1" lang="en"><a name="id2478829"></a><h2>TALLOC API</h2><p>
|
||||
The following is a complete guide to the talloc API. Read it all at
|
||||
least twice.
|
||||
</p><div class="refsect2" lang="en"><a name="id2478375"></a><h3>(type *)talloc(const void *ctx, type);</h3><p>
|
||||
</p><div class="refsect2" lang="en"><a name="id2478838"></a><h3>(type *)talloc(const void *ctx, type);</h3><p>
|
||||
The talloc() macro is the core of the talloc library. It takes a
|
||||
memory <span class="italic">ctx</span> and a <span class="italic">type</span>, and returns a pointer to a new
|
||||
area of memory of the given <span class="italic">type</span>.
|
||||
@ -48,18 +48,18 @@
|
||||
</p><p>
|
||||
The <span class="italic">ctx</span> argument to talloc()
|
||||
can be NULL, in which case a new top level context is created.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2478439"></a><h3>void *talloc_size(const void *ctx, size_t size);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2478902"></a><h3>void *talloc_size(const void *ctx, size_t size);</h3><p>
|
||||
The function talloc_size() should be used when you don't have a
|
||||
convenient type to pass to talloc(). Unlike talloc(), it is not
|
||||
type safe (as it returns a void *), so you are on your own for
|
||||
type checking.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2478452"></a><h3>(typeof(ptr)) talloc_ptrtype(const void *ctx, ptr);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2478915"></a><h3>(typeof(ptr)) talloc_ptrtype(const void *ctx, ptr);</h3><p>
|
||||
The talloc_ptrtype() macro should be used when you have a pointer and
|
||||
want to allocate memory to point at with this pointer. When compiling
|
||||
with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size()
|
||||
and talloc_get_name() will return the current location in the source file.
|
||||
and not the type.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2478467"></a><h3>int talloc_free(void *ptr);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2478930"></a><h3>int talloc_free(void *ptr);</h3><p>
|
||||
The talloc_free() function frees a piece of talloc memory, and
|
||||
all its children. You can call talloc_free() on any pointer
|
||||
returned by talloc().
|
||||
@ -143,14 +143,14 @@
|
||||
free will be ignored. This would be a pointless operation
|
||||
anyway, as the destructor is only called when the memory is just
|
||||
about to go away.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2479422"></a><h3>int talloc_increase_ref_count(const void *<span class="italic">ptr</span>);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2479748"></a><h3>int talloc_increase_ref_count(const void *<span class="italic">ptr</span>);</h3><p>
|
||||
The talloc_increase_ref_count(<span class="italic">ptr</span>) function is exactly equivalent to:
|
||||
</p><pre class="programlisting">talloc_reference(NULL, ptr);</pre><p>
|
||||
You can use either syntax, depending on which you think is
|
||||
clearer in your code.
|
||||
</p><p>
|
||||
It returns 0 on success and -1 on failure.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2479459"></a><h3>size_t talloc_reference_count(const void *<span class="italic">ptr</span>);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2479785"></a><h3>size_t talloc_reference_count(const void *<span class="italic">ptr</span>);</h3><p>
|
||||
Return the number of references to the pointer.
|
||||
</p></div><div class="refsect2" lang="en"><a name="talloc_set_name"></a><h3>void talloc_set_name(const void *ptr, const char *fmt, ...);</h3><p>
|
||||
Each talloc pointer has a "name". The name is used principally
|
||||
@ -173,7 +173,7 @@
|
||||
Note that multiple calls to talloc_set_name() will allocate more
|
||||
memory without releasing the name. All of the memory is released
|
||||
when the ptr is freed using talloc_free().
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2479578"></a><h3>void talloc_set_name_const(const void *<span class="italic">ptr</span>, const char *<span class="italic">name</span>);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2479904"></a><h3>void talloc_set_name_const(const void *<span class="italic">ptr</span>, const char *<span class="italic">name</span>);</h3><p>
|
||||
The function talloc_set_name_const() is just like
|
||||
talloc_set_name(), but it takes a string constant, and is much
|
||||
faster. It is extensively used by the "auto naming" macros, such
|
||||
@ -184,27 +184,27 @@
|
||||
ptr. This means you must not pass a <span class="italic">name</span> pointer to memory that will
|
||||
disappear before <span class="italic">ptr</span> is freed
|
||||
with talloc_free().
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2479622"></a><h3>void *talloc_named(const void *<span class="italic">ctx</span>, size_t <span class="italic">size</span>, const char *<span class="italic">fmt</span>, ...);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2479948"></a><h3>void *talloc_named(const void *<span class="italic">ctx</span>, size_t <span class="italic">size</span>, const char *<span class="italic">fmt</span>, ...);</h3><p>
|
||||
The talloc_named() function creates a named talloc pointer. It
|
||||
is equivalent to:
|
||||
</p><pre class="programlisting">ptr = talloc_size(ctx, size);
|
||||
talloc_set_name(ptr, fmt, ....);</pre></div><div class="refsect2" lang="en"><a name="id2479657"></a><h3>void *talloc_named_const(const void *<span class="italic">ctx</span>, size_t <span class="italic">size</span>, const char *<span class="italic">name</span>);</h3><p>
|
||||
talloc_set_name(ptr, fmt, ....);</pre></div><div class="refsect2" lang="en"><a name="id2479983"></a><h3>void *talloc_named_const(const void *<span class="italic">ctx</span>, size_t <span class="italic">size</span>, const char *<span class="italic">name</span>);</h3><p>
|
||||
This is equivalent to:
|
||||
</p><pre class="programlisting">ptr = talloc_size(ctx, size);
|
||||
talloc_set_name_const(ptr, name);</pre></div><div class="refsect2" lang="en"><a name="id2479692"></a><h3>const char *talloc_get_name(const void *<span class="italic">ptr</span>);</h3><p>
|
||||
talloc_set_name_const(ptr, name);</pre></div><div class="refsect2" lang="en"><a name="id2480018"></a><h3>const char *talloc_get_name(const void *<span class="italic">ptr</span>);</h3><p>
|
||||
This returns the current name for the given talloc pointer,
|
||||
<span class="italic">ptr</span>. See <a href="#talloc_set_name" title="void talloc_set_name(const void *ptr, const char *fmt, ...);">“<span class="quote">talloc_set_name()</span>”</a>
|
||||
for details.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2479723"></a><h3>void *talloc_init(const char *<span class="italic">fmt</span>, ...);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2480049"></a><h3>void *talloc_init(const char *<span class="italic">fmt</span>, ...);</h3><p>
|
||||
This function creates a zero length named talloc context as a top
|
||||
level context. It is equivalent to:
|
||||
</p><pre class="programlisting">talloc_named(NULL, 0, fmt, ...);</pre></div><div class="refsect2" lang="en"><a name="id2479746"></a><h3>void *talloc_new(void *<span class="italic">ctx</span>);</h3><p>
|
||||
</p><pre class="programlisting">talloc_named(NULL, 0, fmt, ...);</pre></div><div class="refsect2" lang="en"><a name="id2480072"></a><h3>void *talloc_new(void *<span class="italic">ctx</span>);</h3><p>
|
||||
This is a utility macro that creates a new memory context hanging
|
||||
off an exiting context, automatically naming it "talloc_new:
|
||||
__location__" where __location__ is the source line it is called
|
||||
from. It is particularly useful for creating a new temporary
|
||||
working context.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526437"></a><h3>(<span class="italic">type</span> *)talloc_realloc(const void *<span class="italic">ctx</span>, void *<span class="italic">ptr</span>, <span class="italic">type</span>, <span class="italic">count</span>);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526763"></a><h3>(<span class="italic">type</span> *)talloc_realloc(const void *<span class="italic">ctx</span>, void *<span class="italic">ptr</span>, <span class="italic">type</span>, <span class="italic">count</span>);</h3><p>
|
||||
The talloc_realloc() macro changes the size of a talloc pointer.
|
||||
It has the following equivalences:
|
||||
</p><pre class="programlisting">talloc_realloc(ctx, NULL, type, 1) ==> talloc(ctx, type);
|
||||
@ -216,10 +216,10 @@ talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr);</pre><p>
|
||||
talloc_realloc() returns the new pointer, or NULL on failure.
|
||||
The call will fail either due to a lack of memory, or because the
|
||||
pointer has more than one parent (see <a href="#talloc_reference" title="void *talloc_reference(const void *ctx, const void *ptr);">“<span class="quote">talloc_reference()</span>”</a>).
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526515"></a><h3>void *talloc_realloc_size(const void *ctx, void *ptr, size_t size);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526841"></a><h3>void *talloc_realloc_size(const void *ctx, void *ptr, size_t size);</h3><p>
|
||||
the talloc_realloc_size() function is useful when the type is not
|
||||
known so the type-safe talloc_realloc() cannot be used.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526527"></a><h3>TYPE *talloc_steal(const void *<span class="italic">new_ctx</span>, const TYPE *<span class="italic">ptr</span>);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526853"></a><h3>TYPE *talloc_steal(const void *<span class="italic">new_ctx</span>, const TYPE *<span class="italic">ptr</span>);</h3><p>
|
||||
The talloc_steal() function changes the parent context of a
|
||||
talloc pointer. It is typically used when the context that the
|
||||
pointer is currently a child of is going to be freed and you wish
|
||||
@ -232,14 +232,14 @@ talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr);</pre><p>
|
||||
relationship if you are not careful with talloc_steal(). No
|
||||
guarantees are provided as to your sanity or the safety of your
|
||||
data if you do this.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526564"></a><h3>TYPE *talloc_move(const void *<span class="italic">new_ctx</span>, TYPE **<span class="italic">ptr</span>);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526890"></a><h3>TYPE *talloc_move(const void *<span class="italic">new_ctx</span>, TYPE **<span class="italic">ptr</span>);</h3><p>
|
||||
The talloc_move() function is a wrapper around
|
||||
talloc_steal() which zeros the source pointer after the
|
||||
move. This avoids a potential source of bugs where a
|
||||
programmer leaves a pointer in two structures, and uses the
|
||||
pointer from the old structure after it has been moved to a
|
||||
new one.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526590"></a><h3>size_t talloc_total_size(const void *<span class="italic">ptr</span>);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526916"></a><h3>size_t talloc_total_size(const void *<span class="italic">ptr</span>);</h3><p>
|
||||
The talloc_total_size() function returns the total size in bytes
|
||||
used by this pointer and all child pointers. Mostly useful for
|
||||
debugging.
|
||||
@ -247,7 +247,7 @@ talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr);</pre><p>
|
||||
Passing NULL is allowed, but it will only give a meaningful
|
||||
result if talloc_enable_leak_report() or
|
||||
talloc_enable_leak_report_full() has been called.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526614"></a><h3>size_t talloc_total_blocks(const void *<span class="italic">ptr</span>);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526940"></a><h3>size_t talloc_total_blocks(const void *<span class="italic">ptr</span>);</h3><p>
|
||||
The talloc_total_blocks() function returns the total memory block
|
||||
count used by this pointer and all child pointers. Mostly useful
|
||||
for debugging.
|
||||
@ -331,79 +331,79 @@ p1 contains 18 bytes in 7 blocks (ref 0)
|
||||
x3 contains 1 bytes in 1 blocks (ref 0)
|
||||
x2 contains 1 bytes in 1 blocks (ref 0)
|
||||
x1 contains 1 bytes in 1 blocks (ref 0)
|
||||
</pre></div><div class="refsect2" lang="en"><a name="id2526922"></a><h3>(<span class="italic">type</span> *)talloc_zero(const void *<span class="italic">ctx</span>, <span class="italic">type</span>);</h3><p>
|
||||
</pre></div><div class="refsect2" lang="en"><a name="id2527248"></a><h3>(<span class="italic">type</span> *)talloc_zero(const void *<span class="italic">ctx</span>, <span class="italic">type</span>);</h3><p>
|
||||
The talloc_zero() macro is equivalent to:
|
||||
</p><pre class="programlisting">ptr = talloc(ctx, type);
|
||||
if (ptr) memset(ptr, 0, sizeof(type));</pre></div><div class="refsect2" lang="en"><a name="id2526956"></a><h3>void *talloc_zero_size(const void *<span class="italic">ctx</span>, size_t <span class="italic">size</span>)</h3><p>
|
||||
if (ptr) memset(ptr, 0, sizeof(type));</pre></div><div class="refsect2" lang="en"><a name="id2527281"></a><h3>void *talloc_zero_size(const void *<span class="italic">ctx</span>, size_t <span class="italic">size</span>)</h3><p>
|
||||
The talloc_zero_size() function is useful when you don't have a
|
||||
known type.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2526977"></a><h3>void *talloc_memdup(const void *<span class="italic">ctx</span>, const void *<span class="italic">p</span>, size_t size);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527304"></a><h3>void *talloc_memdup(const void *<span class="italic">ctx</span>, const void *<span class="italic">p</span>, size_t size);</h3><p>
|
||||
The talloc_memdup() function is equivalent to:
|
||||
</p><pre class="programlisting">ptr = talloc_size(ctx, size);
|
||||
if (ptr) memcpy(ptr, p, size);</pre></div><div class="refsect2" lang="en"><a name="id2527006"></a><h3>char *talloc_strdup(const void *<span class="italic">ctx</span>, const char *<span class="italic">p</span>);</h3><p>
|
||||
if (ptr) memcpy(ptr, p, size);</pre></div><div class="refsect2" lang="en"><a name="id2527332"></a><h3>char *talloc_strdup(const void *<span class="italic">ctx</span>, const char *<span class="italic">p</span>);</h3><p>
|
||||
The talloc_strdup() function is equivalent to:
|
||||
</p><pre class="programlisting">ptr = talloc_size(ctx, strlen(p)+1);
|
||||
if (ptr) memcpy(ptr, p, strlen(p)+1);</pre><p>
|
||||
This function sets the name of the new pointer to the passed
|
||||
string. This is equivalent to:
|
||||
</p><pre class="programlisting">talloc_set_name_const(ptr, ptr)</pre></div><div class="refsect2" lang="en"><a name="id2527046"></a><h3>char *talloc_strndup(const void *<span class="italic">t</span>, const char *<span class="italic">p</span>, size_t <span class="italic">n</span>);</h3><p>
|
||||
</p><pre class="programlisting">talloc_set_name_const(ptr, ptr)</pre></div><div class="refsect2" lang="en"><a name="id2527372"></a><h3>char *talloc_strndup(const void *<span class="italic">t</span>, const char *<span class="italic">p</span>, size_t <span class="italic">n</span>);</h3><p>
|
||||
The talloc_strndup() function is the talloc equivalent of the C
|
||||
library function strndup(3).
|
||||
</p><p>
|
||||
This function sets the name of the new pointer to the passed
|
||||
string. This is equivalent to:
|
||||
</p><pre class="programlisting">talloc_set_name_const(ptr, ptr)</pre></div><div class="refsect2" lang="en"><a name="id2527086"></a><h3>char *talloc_vasprintf(const void *<span class="italic">t</span>, const char *<span class="italic">fmt</span>, va_list <span class="italic">ap</span>);</h3><p>
|
||||
</p><pre class="programlisting">talloc_set_name_const(ptr, ptr)</pre></div><div class="refsect2" lang="en"><a name="id2527412"></a><h3>char *talloc_vasprintf(const void *<span class="italic">t</span>, const char *<span class="italic">fmt</span>, va_list <span class="italic">ap</span>);</h3><p>
|
||||
The talloc_vasprintf() function is the talloc equivalent of the C
|
||||
library function vasprintf(3).
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527114"></a><h3>char *talloc_asprintf(const void *<span class="italic">t</span>, const char *<span class="italic">fmt</span>, ...);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527441"></a><h3>char *talloc_asprintf(const void *<span class="italic">t</span>, const char *<span class="italic">fmt</span>, ...);</h3><p>
|
||||
The talloc_asprintf() function is the talloc equivalent of the C
|
||||
library function asprintf(3).
|
||||
</p><p>
|
||||
This function sets the name of the new pointer to the passed
|
||||
string. This is equivalent to:
|
||||
</p><pre class="programlisting">talloc_set_name_const(ptr, ptr)</pre></div><div class="refsect2" lang="en"><a name="id2527148"></a><h3>char *talloc_asprintf_append(char *s, const char *fmt, ...);</h3><p>
|
||||
</p><pre class="programlisting">talloc_set_name_const(ptr, ptr)</pre></div><div class="refsect2" lang="en"><a name="id2527475"></a><h3>char *talloc_asprintf_append(char *s, const char *fmt, ...);</h3><p>
|
||||
The talloc_asprintf_append() function appends the given formatted
|
||||
string to the given string.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527160"></a><h3>(type *)talloc_array(const void *ctx, type, uint_t count);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527486"></a><h3>(type *)talloc_array(const void *ctx, type, uint_t count);</h3><p>
|
||||
The talloc_array() macro is equivalent to:
|
||||
</p><pre class="programlisting">(type *)talloc_size(ctx, sizeof(type) * count);</pre><p>
|
||||
except that it provides integer overflow protection for the
|
||||
multiply, returning NULL if the multiply overflows.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527183"></a><h3>void *talloc_array_size(const void *ctx, size_t size, uint_t count);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527509"></a><h3>void *talloc_array_size(const void *ctx, size_t size, uint_t count);</h3><p>
|
||||
The talloc_array_size() function is useful when the type is not
|
||||
known. It operates in the same way as talloc_array(), but takes a
|
||||
size instead of a type.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527196"></a><h3>(typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, uint_t count);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527522"></a><h3>(typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, uint_t count);</h3><p>
|
||||
The talloc_ptrtype() macro should be used when you have a pointer to an array
|
||||
and want to allocate memory of an array to point at with this pointer. When compiling
|
||||
with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size()
|
||||
and talloc_get_name() will return the current location in the source file.
|
||||
and not the type.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527212"></a><h3>void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size)</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527538"></a><h3>void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size)</h3><p>
|
||||
This is a non-macro version of talloc_realloc(), which is useful
|
||||
as libraries sometimes want a realloc function pointer. A
|
||||
realloc(3) implementation encapsulates the functionality of
|
||||
malloc(3), free(3) and realloc(3) in one call, which is why it is
|
||||
useful to be able to pass around a single function pointer.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527227"></a><h3>void *talloc_autofree_context(void);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527554"></a><h3>void *talloc_autofree_context(void);</h3><p>
|
||||
This is a handy utility function that returns a talloc context
|
||||
which will be automatically freed on program exit. This can be
|
||||
used to reduce the noise in memory leak reports.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527240"></a><h3>void *talloc_check_name(const void *ptr, const char *name);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527566"></a><h3>void *talloc_check_name(const void *ptr, const char *name);</h3><p>
|
||||
This function checks if a pointer has the specified <span class="italic">name</span>. If it does then the pointer is
|
||||
returned. It it doesn't then NULL is returned.
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527258"></a><h3>(type *)talloc_get_type(const void *ptr, type);</h3><p>
|
||||
</p></div><div class="refsect2" lang="en"><a name="id2527584"></a><h3>(type *)talloc_get_type(const void *ptr, type);</h3><p>
|
||||
This macro allows you to do type checking on talloc pointers. It
|
||||
is particularly useful for void* private pointers. It is
|
||||
equivalent to this:
|
||||
</p><pre class="programlisting">(type *)talloc_check_name(ptr, #type)</pre></div><div class="refsect2" lang="en"><a name="id2527277"></a><h3>talloc_set_type(const void *ptr, type);</h3><p>
|
||||
</p><pre class="programlisting">(type *)talloc_check_name(ptr, #type)</pre></div><div class="refsect2" lang="en"><a name="id2527603"></a><h3>talloc_set_type(const void *ptr, type);</h3><p>
|
||||
This macro allows you to force the name of a pointer to be a
|
||||
particular <span class="emphasis"><em>type</em></span>. This can be
|
||||
used in conjunction with talloc_get_type() to do type checking on
|
||||
void* pointers.
|
||||
</p><p>
|
||||
It is equivalent to this:
|
||||
</p><pre class="programlisting">talloc_set_name_const(ptr, #type)</pre></div></div><div class="refsect1" lang="en"><a name="id2527304"></a><h2>PERFORMANCE</h2><p>
|
||||
</p><pre class="programlisting">talloc_set_name_const(ptr, #type)</pre></div></div><div class="refsect1" lang="en"><a name="id2527631"></a><h2>PERFORMANCE</h2><p>
|
||||
All the additional features of talloc(3) over malloc(3) do come at a
|
||||
price. We have a simple performance test in Samba4 that measures
|
||||
talloc() versus malloc() performance, and it seems that talloc() is
|
||||
@ -411,10 +411,10 @@ if (ptr) memcpy(ptr, p, strlen(p)+1);</pre><p>
|
||||
Samba, the great reduction in code complexity that we get by using
|
||||
talloc makes this worthwhile, especially as the total overhead of
|
||||
talloc/malloc in Samba is already quite small.
|
||||
</p></div><div class="refsect1" lang="en"><a name="id2527322"></a><h2>SEE ALSO</h2><p>
|
||||
</p></div><div class="refsect1" lang="en"><a name="id2527648"></a><h2>SEE ALSO</h2><p>
|
||||
malloc(3), strndup(3), vasprintf(3), asprintf(3),
|
||||
<a href="http://talloc.samba.org/" target="_top">http://talloc.samba.org/</a>
|
||||
</p></div><div class="refsect1" lang="en"><a name="id2527336"></a><h2>COPYRIGHT/LICENSE</h2><p>
|
||||
</p></div><div class="refsect1" lang="en"><a name="id2527662"></a><h2>COPYRIGHT/LICENSE</h2><p>
|
||||
Copyright (C) Andrew Tridgell 2004
|
||||
</p><p>
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -1028,7 +1028,7 @@ static void talloc_report_null(void)
|
||||
/*
|
||||
report on any memory hanging off the null context
|
||||
*/
|
||||
void talloc_report_null_full(void)
|
||||
static void talloc_report_null_full(void)
|
||||
{
|
||||
if (talloc_total_size(null_context) != 0) {
|
||||
talloc_report_full(null_context, stderr);
|
||||
@ -1086,7 +1086,6 @@ void *_talloc_zero(const void *ctx, size_t size, const char *name)
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
memdup with a talloc.
|
||||
*/
|
||||
@ -1174,10 +1173,11 @@ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
|
||||
va_list ap2;
|
||||
char c;
|
||||
|
||||
va_copy(ap2, ap);
|
||||
|
||||
/* this call looks strange, but it makes it work on older solaris boxes */
|
||||
if ((len = vsnprintf(&c, 1, fmt, ap2)) < 0) {
|
||||
va_copy(ap2, ap);
|
||||
len = vsnprintf(&c, 1, fmt, ap2);
|
||||
va_end(ap2);
|
||||
if (len < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1185,6 +1185,7 @@ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
|
||||
if (ret) {
|
||||
va_copy(ap2, ap);
|
||||
vsnprintf(ret, len+1, fmt, ap2);
|
||||
va_end(ap2);
|
||||
_talloc_set_name_const(ret, ret);
|
||||
}
|
||||
|
||||
@ -1226,10 +1227,13 @@ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
|
||||
|
||||
tc = talloc_chunk_from_ptr(s);
|
||||
|
||||
va_copy(ap2, ap);
|
||||
|
||||
s_len = tc->size - 1;
|
||||
if ((len = vsnprintf(&c, 1, fmt, ap2)) <= 0) {
|
||||
|
||||
va_copy(ap2, ap);
|
||||
len = vsnprintf(&c, 1, fmt, ap2);
|
||||
va_end(ap2);
|
||||
|
||||
if (len <= 0) {
|
||||
/* Either the vsnprintf failed or the format resulted in
|
||||
* no characters being formatted. In the former case, we
|
||||
* ought to return NULL, in the latter we ought to return
|
||||
@ -1243,8 +1247,8 @@ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
|
||||
if (!s) return NULL;
|
||||
|
||||
va_copy(ap2, ap);
|
||||
|
||||
vsnprintf(s+s_len, len+1, fmt, ap2);
|
||||
va_end(ap2);
|
||||
_talloc_set_name_const(s, s);
|
||||
|
||||
return s;
|
||||
@ -1287,7 +1291,6 @@ void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const
|
||||
return _talloc_zero(ctx, el_size * count, name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
realloc an array, checking for integer overflow in the array size
|
||||
*/
|
||||
|
@ -26,16 +26,22 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* this is only needed for compatibility with the old talloc */
|
||||
typedef void TALLOC_CTX;
|
||||
|
||||
/*
|
||||
this uses a little trick to allow __LINE__ to be stringified
|
||||
*/
|
||||
#define _STRING_LINE_(s) #s
|
||||
#define _STRING_LINE2_(s) _STRING_LINE_(s)
|
||||
#define __LINESTR__ _STRING_LINE2_(__LINE__)
|
||||
#define __location__ __FILE__ ":" __LINESTR__
|
||||
#ifndef __location__
|
||||
#define __TALLOC_STRING_LINE1__(s) #s
|
||||
#define __TALLOC_STRING_LINE2__(s) __TALLOC_STRING_LINE1__(s)
|
||||
#define __TALLOC_STRING_LINE3__ __TALLOC_STRING_LINE2__(__LINE__)
|
||||
#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__
|
||||
#endif
|
||||
|
||||
#ifndef TALLOC_DEPRECATED
|
||||
#define TALLOC_DEPRECATED 0
|
||||
@ -142,7 +148,6 @@ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f
|
||||
void talloc_report_full(const void *ptr, FILE *f);
|
||||
void talloc_report(const void *ptr, FILE *f);
|
||||
void talloc_enable_null_tracking(void);
|
||||
void talloc_report_null_full(void);
|
||||
void talloc_disable_null_tracking(void);
|
||||
void talloc_enable_leak_report(void);
|
||||
void talloc_enable_leak_report_full(void);
|
||||
@ -166,4 +171,3 @@ void talloc_show_parents(const void *context, FILE *file);
|
||||
int talloc_is_parent(const void *context, const void *ptr);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -5,6 +5,7 @@ includedir=${prefix}/include
|
||||
|
||||
Name: talloc
|
||||
Description: A hierarchical pool based memory system with destructors
|
||||
Requires.private:
|
||||
Version: 0.0.1
|
||||
Libs: -L${libdir} -ltalloc
|
||||
Libs.private: -lreplace
|
||||
|
@ -5,7 +5,7 @@ includedir=@includedir@
|
||||
|
||||
Name: talloc
|
||||
Description: A hierarchical pool based memory system with destructors
|
||||
Version: 4.0
|
||||
Version: @PACKAGE_VERSION@
|
||||
Libs: -L${libdir} -ltalloc
|
||||
Cflags: -I${includedir}
|
||||
URL: http://talloc.samba.org/
|
||||
|
@ -12,7 +12,7 @@ this carefully, as talloc has changed a lot. With 3.0.20 (or 3.0.14?) the
|
||||
Samba4 talloc has been ported back to Samba3, so this guide applies to both.
|
||||
|
||||
The new talloc is a hierarchical, reference counted memory pool system
|
||||
with destructors. Quite a mounthful really, but not too bad once you
|
||||
with destructors. Quite a mouthful really, but not too bad once you
|
||||
get used to it.
|
||||
|
||||
Perhaps the biggest change from Samba3 is that there is no distinction
|
||||
|
@ -1012,7 +1012,7 @@ static bool test_talloc_ptrtype(void)
|
||||
|
||||
static bool test_autofree(void)
|
||||
{
|
||||
#ifndef _SAMBA_BUILD_
|
||||
#if _SAMBA_BUILD_ < 4
|
||||
/* autofree test would kill smbtorture */
|
||||
void *p;
|
||||
printf("test: autofree [\nTALLOC AUTOFREE CONTEXT\n]\n");
|
||||
@ -1064,7 +1064,7 @@ bool torture_local_talloc(struct torture_context *tctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef _SAMBA_BUILD_
|
||||
#if _SAMBA_BUILD_ < 4
|
||||
int main(void)
|
||||
{
|
||||
bool ret = torture_local_talloc(NULL);
|
||||
|
@ -12,7 +12,7 @@ libdir = @libdir@
|
||||
VPATH = @srcdir@:@libreplacedir@
|
||||
srcdir = @srcdir@
|
||||
builddir = @builddir@
|
||||
CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude -I@libreplacedir@
|
||||
CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude
|
||||
CFLAGS = $(CPPFLAGS) @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
@ -23,7 +23,7 @@ PROGS = bin/tdbtool$(EXEEXT) bin/tdbtorture$(EXEEXT)
|
||||
PROGS_NOINSTALL = bin/tdbtest$(EXEEXT) bin/tdbdump$(EXEEXT) bin/tdbbackup$(EXEEXT)
|
||||
ALL_PROGS = $(PROGS) $(PROGS_NOINSTALL)
|
||||
|
||||
TDB_OBJ = @TDBOBJ@ @LIBREPLACEOBJ@
|
||||
TDB_OBJ = @TDB_OBJ@ @LIBREPLACEOBJ@
|
||||
|
||||
DIRS = bin common tools
|
||||
|
||||
@ -45,13 +45,13 @@ dirs:
|
||||
@mkdir -p $(DIRS)
|
||||
|
||||
install: all
|
||||
mkdir -p $(bindir)
|
||||
mkdir -p $(includedir)
|
||||
mkdir -p $(libdir)
|
||||
mkdir -p $(libdir)/pkgconfig
|
||||
cp $(PROGS) $(bindir)
|
||||
cp $(srcdir)/include/tdb.h $(includedir)
|
||||
cp tdb.pc $(libdir)/pkgconfig
|
||||
mkdir -p $(DESTDIR)$(bindir)
|
||||
mkdir -p $(DESTDIR)$(includedir)
|
||||
mkdir -p $(DESTDIR)$(libdir)
|
||||
mkdir -p $(DESTDIR)$(libdir)/pkgconfig
|
||||
cp $(PROGS) $(DESTDIR)$(bindir)
|
||||
cp $(srcdir)/include/tdb.h $(DESTDIR)$(includedir)
|
||||
cp tdb.pc $(DESTDIR)$(libdir)/pkgconfig
|
||||
|
||||
libtdb.a: $(TDB_OBJ)
|
||||
ar -rv libtdb.a $(TDB_OBJ)
|
||||
|
@ -2,7 +2,7 @@ AC_PREREQ(2.50)
|
||||
AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""])
|
||||
AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""])
|
||||
AC_DEFUN([SMB_ENABLE], [echo -n ""])
|
||||
AC_INIT(include/tdb.h)
|
||||
AC_INIT(tdb, 1.1)
|
||||
AC_CONFIG_SRCDIR([common/tdb.c])
|
||||
AC_CONFIG_HEADER(include/config.h)
|
||||
AC_LIBREPLACE_ALL_CHECKS
|
||||
|
@ -12,11 +12,17 @@ done
|
||||
if test x"$tdbdir" = "x"; then
|
||||
AC_MSG_ERROR([cannot find tdb source in $tdbpaths])
|
||||
fi
|
||||
TDBOBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o"
|
||||
TDBOBJ="$TDBOBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o"
|
||||
AC_SUBST(TDBOBJ)
|
||||
TDB_OBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o"
|
||||
TDB_OBJ="$TDB_OBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o"
|
||||
AC_SUBST(TDB_OBJ)
|
||||
AC_SUBST(LIBREPLACEOBJ)
|
||||
|
||||
TDB_LIBS=""
|
||||
AC_SUBST(TDB_LIBS)
|
||||
|
||||
TDB_CFLAGS="-I$tdbdir/include"
|
||||
AC_SUBST(TDB_CFLAGS)
|
||||
|
||||
AC_CHECK_FUNCS(mmap pread pwrite getpagesize utime)
|
||||
AC_CHECK_HEADERS(getopt.h sys/select.h sys/time.h)
|
||||
|
||||
|
@ -5,6 +5,6 @@ includedir=@includedir@
|
||||
|
||||
Name: tdb
|
||||
Description: A trivial database
|
||||
Version: 4.0
|
||||
Version: @PACKAGE_VERSION@
|
||||
Libs: -L${libdir} -ltdb
|
||||
Cflags: -I${includedir}
|
||||
|
@ -142,10 +142,6 @@ static void bench_fetch(struct ctdb_context *ctdb, struct event_context *ev)
|
||||
printf("Event loop failed!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (LogLevel > 9) {
|
||||
talloc_report_null_full();
|
||||
}
|
||||
}
|
||||
|
||||
printf("Fetch: %.2f msgs/sec\n", msg_count/end_timer());
|
||||
|
Loading…
x
Reference in New Issue
Block a user