mirror of
https://github.com/samba-team/samba.git
synced 2025-01-08 21:18:16 +03:00
initial version
(This used to be ctdb commit 5bba7deef9b03a68d336c138e83d6d4fac35bfce)
This commit is contained in:
commit
6613b7d438
61
ctdb/Makefile.in
Normal file
61
ctdb/Makefile.in
Normal file
@ -0,0 +1,61 @@
|
||||
#!gmake
|
||||
#
|
||||
CC = @CC@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
datarootdir = @datarootdir@
|
||||
includedir = @includedir@
|
||||
libdir = @libdir@
|
||||
bindir = @bindir@
|
||||
VPATH = @srcdir@:@tdbdir@:@tallocdir@:@libreplacedir@
|
||||
srcdir = @srcdir@
|
||||
builddir = @builddir@
|
||||
EXTRA_OBJ=@EXTRA_OBJ@
|
||||
|
||||
CFLAGS=-g -I$(srcdir)/include -Iinclude -I$(srcdir) \
|
||||
-I@tallocdir@ -I@tdbdir@/include -I@libreplacedir@ \
|
||||
-DLIBDIR=\"$(libdir)\" -DSHLIBEXT=\"@SHLIBEXT@\" -DUSE_MMAP=1 @CFLAGS@
|
||||
|
||||
LIB_FLAGS=@LDFLAGS@ -Llib @LIBS@ -lpopt
|
||||
|
||||
EVENTS_OBJ = lib/events/events.o lib/events/events_standard.o
|
||||
|
||||
CTDB_OBJ = ctdb_tcp_child.o ctdb_tcp.o util.o
|
||||
|
||||
OBJS = @TDBOBJ@ @TALLOCOBJ@ @LIBREPLACEOBJ@ $(EXTRA_OBJ) $(EVENTS_OBJ) $(CTDB_OBJ)
|
||||
|
||||
BINS = bin/ctdb_test
|
||||
|
||||
DIRS = lib bin
|
||||
|
||||
all: showflags dirs $(OBJS) $(BINS)
|
||||
|
||||
showflags:
|
||||
@echo 'ctdb will be compiled with flags:'
|
||||
@echo ' CFLAGS = $(CFLAGS)'
|
||||
@echo ' LIBS = $(LIBS)'
|
||||
|
||||
.c.o:
|
||||
@echo Compiling $*.c
|
||||
@mkdir -p `dirname $@`
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
dirs:
|
||||
@mkdir -p $(DIRS)
|
||||
|
||||
bin/ctdb_test: $(OBJS) ctdb_test.o
|
||||
@echo Linking $@
|
||||
@$(CC) $(CFLAGS) -o $@ ctdb_test.o $(OBJS) $(LIB_FLAGS)
|
||||
|
||||
clean:
|
||||
rm -f *.o */*.o
|
||||
rm -f $(BINS)
|
||||
|
||||
distclean: clean
|
||||
rm -f *~ */*~
|
||||
rm -rf bin lib
|
||||
rm -f config.log config.status config.cache include/config.h
|
||||
rm -f Makefile
|
||||
|
||||
realdistclean: distclean
|
||||
rm -f configure.in include/config.h.in
|
1
ctdb/aclocal.m4
vendored
Normal file
1
ctdb/aclocal.m4
vendored
Normal file
@ -0,0 +1 @@
|
||||
m4_include(libreplace.m4)
|
17
ctdb/autogen.sh
Executable file
17
ctdb/autogen.sh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -rf autom4te.cache
|
||||
rm -f configure config.h.in
|
||||
|
||||
IPATHS="-I libreplace -I lib/replace -I ../libreplace -I ../replace"
|
||||
IPATHS="$IPATHS -I lib/talloc -I talloc -I ../talloc"
|
||||
IPATHS="$IPATHS -I lib/tdb -I tdb -I ../tdb"
|
||||
IPATHS="$IPATHS -I lib/popt -I popt -I ../popt"
|
||||
autoheader $IPATHS || exit 1
|
||||
autoconf $IPATHS || exit 1
|
||||
|
||||
rm -rf autom4te.cache
|
||||
|
||||
echo "Now run ./configure and then make."
|
||||
exit 0
|
||||
|
1466
ctdb/config.guess
vendored
Executable file
1466
ctdb/config.guess
vendored
Executable file
File diff suppressed because it is too large
Load Diff
712
ctdb/config.h
Normal file
712
ctdb/config.h
Normal file
@ -0,0 +1,712 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Whether strndup is broken */
|
||||
/* #undef BROKEN_STRNDUP */
|
||||
|
||||
/* Whether strnlen is broken */
|
||||
/* #undef BROKEN_STRNLEN */
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
|
||||
/* Define to 1 if you have the `asprintf' function. */
|
||||
#define HAVE_ASPRINTF 1
|
||||
|
||||
/* Whether the bool type is available */
|
||||
#define HAVE_BOOL 1
|
||||
|
||||
/* Define to 1 if you have the `bzero' function. */
|
||||
#define HAVE_BZERO 1
|
||||
|
||||
/* Whether there is a C99 compliant vsnprintf */
|
||||
#define HAVE_C99_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `chroot' function. */
|
||||
#define HAVE_CHROOT 1
|
||||
|
||||
/* Define to 1 if you have the `chsize' function. */
|
||||
/* #undef HAVE_CHSIZE */
|
||||
|
||||
/* Whether or not we have comparison_fn_t */
|
||||
#define HAVE_COMPARISON_FN_T 1
|
||||
|
||||
/* Define to 1 if you have the <compat.h> header file. */
|
||||
/* #undef HAVE_COMPAT_H */
|
||||
|
||||
/* Define to 1 if you have the <ctype.h> header file. */
|
||||
#define HAVE_CTYPE_H 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `asprintf', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_ASPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `snprintf', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_SNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `vasprintf', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_VASPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the <direct.h> header file. */
|
||||
/* #undef HAVE_DIRECT_H */
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#define HAVE_DIRENT_H 1
|
||||
|
||||
/* Define to 1 if you have the `dlclose' function. */
|
||||
#define HAVE_DLCLOSE 1
|
||||
|
||||
/* Define to 1 if you have the `dlerror' function. */
|
||||
#define HAVE_DLERROR 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the `dlopen' function. */
|
||||
#define HAVE_DLOPEN 1
|
||||
|
||||
/* Define to 1 if you have the `dlsym' function. */
|
||||
#define HAVE_DLSYM 1
|
||||
|
||||
/* Define to 1 if you have the `endnetgrent' function. */
|
||||
#define HAVE_ENDNETGRENT 1
|
||||
|
||||
/* Define to 1 if you have the `epoll_create' function. */
|
||||
#define HAVE_EPOLL_CREATE 1
|
||||
|
||||
/* Whether errno() is available */
|
||||
#define HAVE_ERRNO_DECL 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <fnmatch.h> header file. */
|
||||
#define HAVE_FNMATCH_H 1
|
||||
|
||||
/* Define to 1 if you have the `ftruncate' function. */
|
||||
#define HAVE_FTRUNCATE 1
|
||||
|
||||
/* Whether there is a __FUNCTION__ macro */
|
||||
#define HAVE_FUNCTION_MACRO 1
|
||||
|
||||
/* Define to 1 if you have the `getdents' function. */
|
||||
/* #undef HAVE_GETDENTS */
|
||||
|
||||
/* Define to 1 if you have the `getdirentries' function. */
|
||||
/* #undef HAVE_GETDIRENTRIES */
|
||||
|
||||
/* Define to 1 if you have the `getnetgrent' function. */
|
||||
#define HAVE_GETNETGRENT 1
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#define HAVE_GETOPT_H 1
|
||||
|
||||
/* Define to 1 if you have the `getpagesize' function. */
|
||||
#define HAVE_GETPAGESIZE 1
|
||||
|
||||
/* Define to 1 if you have the `getpgrp' function. */
|
||||
#define HAVE_GETPGRP 1
|
||||
|
||||
/* Define to 1 if you have the <grp.h> header file. */
|
||||
#define HAVE_GRP_H 1
|
||||
|
||||
/* Whether the compiler supports immediate structures */
|
||||
#define HAVE_IMMEDIATE_STRUCTURES 1
|
||||
|
||||
/* Define to 1 if you have the `initgroups' function. */
|
||||
#define HAVE_INITGROUPS 1
|
||||
|
||||
/* Define to 1 if you have the `innetgr' function. */
|
||||
#define HAVE_INNETGR 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `long long'. */
|
||||
#define HAVE_LONG_LONG 1
|
||||
|
||||
/* Define to 1 if you have the `lstat' function. */
|
||||
#define HAVE_LSTAT 1
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
#define HAVE_MEMMOVE 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define if target mkdir supports mode option */
|
||||
#define HAVE_MKDIR_MODE 1
|
||||
|
||||
/* Define to 1 if you have the `mkdtemp' function. */
|
||||
#define HAVE_MKDTEMP 1
|
||||
|
||||
/* Define to 1 if you have the `mktime' function. */
|
||||
#define HAVE_MKTIME 1
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#define HAVE_MMAP 1
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#define HAVE_NETDB_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in_ip.h> header file. */
|
||||
/* #undef HAVE_NETINET_IN_IP_H */
|
||||
|
||||
/* Define to 1 if you have the <netinet/in_systm.h> header file. */
|
||||
#define HAVE_NETINET_IN_SYSTM_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/ip.h> header file. */
|
||||
#define HAVE_NETINET_IP_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
||||
#define HAVE_NETINET_TCP_H 1
|
||||
|
||||
/* usability of net/if.h */
|
||||
#define HAVE_NET_IF_H 1
|
||||
|
||||
/* Whether the open(2) accepts O_DIRECT */
|
||||
/* #undef HAVE_OPEN_O_DIRECT */
|
||||
|
||||
/* Define to 1 if you have the `pipe' function. */
|
||||
#define HAVE_PIPE 1
|
||||
|
||||
/* Define to 1 if you have the `pread' function. */
|
||||
#define HAVE_PREAD 1
|
||||
|
||||
/* Whether pread() is available */
|
||||
#define HAVE_PREAD_DECL 1
|
||||
|
||||
/* Define to 1 if you have the `printf' function. */
|
||||
#define HAVE_PRINTF 1
|
||||
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#define HAVE_PWD_H 1
|
||||
|
||||
/* Define to 1 if you have the `pwrite' function. */
|
||||
#define HAVE_PWRITE 1
|
||||
|
||||
/* Whether pwrite() is available */
|
||||
#define HAVE_PWRITE_DECL 1
|
||||
|
||||
/* Define to 1 if you have the `rand' function. */
|
||||
#define HAVE_RAND 1
|
||||
|
||||
/* Define to 1 if you have the `random' function. */
|
||||
#define HAVE_RANDOM 1
|
||||
|
||||
/* Define to 1 if you have the `rename' function. */
|
||||
#define HAVE_RENAME 1
|
||||
|
||||
/* Whether mkstemp is secure */
|
||||
#define HAVE_SECURE_MKSTEMP 1
|
||||
|
||||
/* Define to 1 if you have the `setbuffer' function. */
|
||||
#define HAVE_SETBUFFER 1
|
||||
|
||||
/* Define to 1 if you have the `setegid' function. */
|
||||
#define HAVE_SETEGID 1
|
||||
|
||||
/* Define to 1 if you have the `setenv' function. */
|
||||
#define HAVE_SETENV 1
|
||||
|
||||
/* Define to 1 if you have the `seteuid' function. */
|
||||
#define HAVE_SETEUID 1
|
||||
|
||||
/* Define to 1 if you have the `setlinebuf' function. */
|
||||
#define HAVE_SETLINEBUF 1
|
||||
|
||||
/* Define to 1 if you have the `setnetgrent' function. */
|
||||
#define HAVE_SETNETGRENT 1
|
||||
|
||||
/* Define to 1 if you have the `setresgid' function. */
|
||||
#define HAVE_SETRESGID 1
|
||||
|
||||
/* Whether setresgid() is available */
|
||||
#define HAVE_SETRESGID_DECL 1
|
||||
|
||||
/* Define to 1 if you have the `setresuid' function. */
|
||||
#define HAVE_SETRESUID 1
|
||||
|
||||
/* Whether setresuid() is available */
|
||||
#define HAVE_SETRESUID_DECL 1
|
||||
|
||||
/* Define to 1 if you have the <shadow.h> header file. */
|
||||
#define HAVE_SHADOW_H 1
|
||||
|
||||
/* Whether we have the atomic_t variable type */
|
||||
#define HAVE_SIG_ATOMIC_T_TYPE 1
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#define HAVE_SNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `socketpair' function. */
|
||||
#define HAVE_SOCKETPAIR 1
|
||||
|
||||
/* Define to 1 if you have the `srand' function. */
|
||||
#define HAVE_SRAND 1
|
||||
|
||||
/* Define to 1 if you have the `srandom' function. */
|
||||
#define HAVE_SRANDOM 1
|
||||
|
||||
/* Define to 1 if you have the <standards.h> header file. */
|
||||
/* #undef HAVE_STANDARDS_H */
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#define HAVE_STDARG_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdbool.h> header file. */
|
||||
#define HAVE_STDBOOL_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#define HAVE_STDIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasestr' function. */
|
||||
#define HAVE_STRCASESTR 1
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strlcat' function. */
|
||||
/* #undef HAVE_STRLCAT */
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
/* #undef HAVE_STRLCPY */
|
||||
|
||||
/* Define to 1 if you have the `strndup' function. */
|
||||
#define HAVE_STRNDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strnlen' function. */
|
||||
#define HAVE_STRNLEN 1
|
||||
|
||||
/* Define to 1 if you have the `strtok_r' function. */
|
||||
#define HAVE_STRTOK_R 1
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#define HAVE_STRTOLL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoq' function. */
|
||||
#define HAVE_STRTOQ 1
|
||||
|
||||
/* Define to 1 if you have the `strtoull' function. */
|
||||
#define HAVE_STRTOULL 1
|
||||
|
||||
/* Define to 1 if you have the `strtouq' function. */
|
||||
#define HAVE_STRTOUQ 1
|
||||
|
||||
/* Define to 1 if `st_rdev' is member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_RDEV 1
|
||||
|
||||
/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
|
||||
`HAVE_STRUCT_STAT_ST_RDEV' instead. */
|
||||
#define HAVE_ST_RDEV 1
|
||||
|
||||
/* Define to 1 if you have the `syslog' function. */
|
||||
#define HAVE_SYSLOG 1
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#define HAVE_SYSLOG_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/acl.h> header file. */
|
||||
#define HAVE_SYS_ACL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/capability.h> header file. */
|
||||
/* #undef HAVE_SYS_CAPABILITY_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
/* #undef HAVE_SYS_DIR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
#define HAVE_SYS_EPOLL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/fcntl.h> header file. */
|
||||
#define HAVE_SYS_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/filio.h> header file. */
|
||||
/* #undef HAVE_SYS_FILIO_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/filsys.h> header file. */
|
||||
/* #undef HAVE_SYS_FILSYS_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/fs/s5param.h> header file. */
|
||||
/* #undef HAVE_SYS_FS_S5PARAM_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/id.h> header file. */
|
||||
/* #undef HAVE_SYS_ID_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ipc.h> header file. */
|
||||
#define HAVE_SYS_IPC_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#define HAVE_SYS_MMAN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mode.h> header file. */
|
||||
/* #undef HAVE_SYS_MODE_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/priv.h> header file. */
|
||||
/* #undef HAVE_SYS_PRIV_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#define HAVE_SYS_RESOURCE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/security.h> header file. */
|
||||
/* #undef HAVE_SYS_SECURITY_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/shm.h> header file. */
|
||||
#define HAVE_SYS_SHM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
||||
/* #undef HAVE_SYS_SOCKIO_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/syslog.h> header file. */
|
||||
#define HAVE_SYS_SYSLOG_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/termio.h> header file. */
|
||||
/* #undef HAVE_SYS_TERMIO_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/un.h> header file. */
|
||||
#define HAVE_SYS_UN_H 1
|
||||
|
||||
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#define HAVE_TERMIOS_H 1
|
||||
|
||||
/* Define to 1 if you have the <termio.h> header file. */
|
||||
#define HAVE_TERMIO_H 1
|
||||
|
||||
/* Define to 1 if you have the `timegm' function. */
|
||||
#define HAVE_TIMEGM 1
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#define HAVE_USLEEP 1
|
||||
|
||||
/* Define to 1 if you have the `utime' function. */
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#define HAVE_UTIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <vararg.h> header file. */
|
||||
/* #undef HAVE_VARARG_H */
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
#define HAVE_VASPRINTF 1
|
||||
|
||||
/* Whether va_copy() is available */
|
||||
#define HAVE_VA_COPY 1
|
||||
|
||||
/* Whether the C compiler understands volatile */
|
||||
#define HAVE_VOLATILE 1
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#define HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vsyslog' function. */
|
||||
#define HAVE_VSYSLOG 1
|
||||
|
||||
/* Define to 1 if you have the `waitpid' function. */
|
||||
#define HAVE_WAITPID 1
|
||||
|
||||
/* Define to 1 if you have the <windows.h> header file. */
|
||||
/* #undef HAVE_WINDOWS_H */
|
||||
|
||||
/* Define to 1 if you have the <winsock2.h> header file. */
|
||||
/* #undef HAVE_WINSOCK2_H */
|
||||
|
||||
/* Define to 1 if you have the <ws2tcpip.h> header file. */
|
||||
/* #undef HAVE_WS2TCPIP_H */
|
||||
|
||||
/* Whether the _Bool type is available */
|
||||
#define HAVE__Bool 1
|
||||
|
||||
/* Whether the __VA_ARGS__ macro is available */
|
||||
#define HAVE__VA_ARGS__MACRO 1
|
||||
|
||||
/* Define to 1 if you have the `__strtoll' function. */
|
||||
/* #undef HAVE___STRTOLL */
|
||||
|
||||
/* Define to 1 if you have the `__strtoull' function. */
|
||||
/* #undef HAVE___STRTOULL */
|
||||
|
||||
/* Whether __va_copy() is available */
|
||||
/* #undef HAVE___VA_COPY */
|
||||
|
||||
/* Whether there is a __func__ macro */
|
||||
/* #undef HAVE_func_MACRO */
|
||||
|
||||
/* Whether MMAP is broken */
|
||||
/* #undef MMAP_BLACKLIST */
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME ""
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING ""
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION ""
|
||||
|
||||
/* Whether getpass should be replaced */
|
||||
/* #undef REPLACE_GETPASS */
|
||||
|
||||
/* Whether inet_ntoa should be replaced */
|
||||
/* #undef REPLACE_INET_NTOA */
|
||||
|
||||
/* replace readdir */
|
||||
/* #undef REPLACE_READDIR */
|
||||
|
||||
/* replace readdir using getdents() */
|
||||
/* #undef REPLACE_READDIR_GETDENTS */
|
||||
|
||||
/* replace readdir using getdirentries() */
|
||||
/* #undef REPLACE_READDIR_GETDIRENTRIES */
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Whether seekdir returns an int */
|
||||
/* #undef SEEKDIR_RETURNS_INT */
|
||||
|
||||
/* The size of `char', as computed by sizeof. */
|
||||
#define SIZEOF_CHAR 1
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG 4
|
||||
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG_LONG 8
|
||||
|
||||
/* The size of `off_t', as computed by sizeof. */
|
||||
#define SIZEOF_OFF_T 8
|
||||
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
#define SIZEOF_SHORT 2
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#define SIZEOF_SIZE_T 4
|
||||
|
||||
/* The size of `ssize_t', as computed by sizeof. */
|
||||
#define SIZEOF_SSIZE_T 4
|
||||
|
||||
/* The size of `void *', as computed by sizeof. */
|
||||
#define SIZEOF_VOID_P 4
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Whether telldir takes a const pointer */
|
||||
/* #undef TELLDIR_TAKES_CONST_DIR */
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Define to 1 if your processor stores words with the most significant byte
|
||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
/* #undef WORDS_BIGENDIAN */
|
||||
|
||||
/* Define to 1 if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
/* # undef _ALL_SOURCE */
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
||||
#ifndef _OSF_SOURCE
|
||||
# define _OSF_SOURCE 1
|
||||
#endif
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
|
||||
/* Whether to enable POSIX support */
|
||||
/* #undef _POSIX_C_SOURCE */
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
/* #undef _POSIX_SOURCE */
|
||||
|
||||
/* Whether to enable System V compatibility */
|
||||
/* #undef _SYSV */
|
||||
|
||||
#ifndef _XOPEN_SOURCE_EXTENDED
|
||||
# define _XOPEN_SOURCE_EXTENDED 1
|
||||
#endif
|
||||
|
||||
/* Enable extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# define __EXTENSIONS__ 1
|
||||
#endif
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#endif
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
/* #undef gid_t */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
/* #undef inline */
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
/* #undef ino_t */
|
||||
|
||||
/* Define to `short' if <sys/types.h> does not define. */
|
||||
/* #undef int16_t */
|
||||
|
||||
/* Define to `long' if <sys/types.h> does not define. */
|
||||
/* #undef int32_t */
|
||||
|
||||
/* Define to `long long' if <sys/types.h> does not define. */
|
||||
/* #undef int64_t */
|
||||
|
||||
/* Define to `char' if <sys/types.h> does not define. */
|
||||
/* #undef int8_t */
|
||||
|
||||
/* Define to `unsigned long long' if <sys/types.h> does not define. */
|
||||
/* #undef intptr_t */
|
||||
|
||||
/* Define to `off_t' if <sys/types.h> does not define. */
|
||||
/* #undef loff_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef mode_t */
|
||||
|
||||
/* Define to `long int' if <sys/types.h> does not define. */
|
||||
/* #undef off_t */
|
||||
|
||||
/* Define to `loff_t' if <sys/types.h> does not define. */
|
||||
#define offset_t loff_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef pid_t */
|
||||
|
||||
/* Define to `unsigned long long' if <sys/types.h> does not define. */
|
||||
/* #undef ptrdiff_t */
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
||||
|
||||
/* Socket length type */
|
||||
/* #undef socklen_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef ssize_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
/* #undef uid_t */
|
||||
|
||||
/* Define to `unsigned short' if <sys/types.h> does not define. */
|
||||
/* #undef uint16_t */
|
||||
|
||||
/* Define to `unsigned long' if <sys/types.h> does not define. */
|
||||
/* #undef uint32_t */
|
||||
|
||||
/* Define to `unsigned long long' if <sys/types.h> does not define. */
|
||||
/* #undef uint64_t */
|
||||
|
||||
/* Define to `unsigned char' if <sys/types.h> does not define. */
|
||||
/* #undef uint8_t */
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#define uint_t unsigned int
|
711
ctdb/config.h.in
Normal file
711
ctdb/config.h.in
Normal file
@ -0,0 +1,711 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Whether strndup is broken */
|
||||
#undef BROKEN_STRNDUP
|
||||
|
||||
/* Whether strnlen is broken */
|
||||
#undef BROKEN_STRNLEN
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#undef HAVE_ARPA_INET_H
|
||||
|
||||
/* Define to 1 if you have the `asprintf' function. */
|
||||
#undef HAVE_ASPRINTF
|
||||
|
||||
/* Whether the bool type is available */
|
||||
#undef HAVE_BOOL
|
||||
|
||||
/* Define to 1 if you have the `bzero' function. */
|
||||
#undef HAVE_BZERO
|
||||
|
||||
/* Whether there is a C99 compliant vsnprintf */
|
||||
#undef HAVE_C99_VSNPRINTF
|
||||
|
||||
/* Define to 1 if you have the `chroot' function. */
|
||||
#undef HAVE_CHROOT
|
||||
|
||||
/* Define to 1 if you have the `chsize' function. */
|
||||
#undef HAVE_CHSIZE
|
||||
|
||||
/* Whether or not we have comparison_fn_t */
|
||||
#undef HAVE_COMPARISON_FN_T
|
||||
|
||||
/* Define to 1 if you have the <compat.h> header file. */
|
||||
#undef HAVE_COMPAT_H
|
||||
|
||||
/* Define to 1 if you have the <ctype.h> header file. */
|
||||
#undef HAVE_CTYPE_H
|
||||
|
||||
/* Define to 1 if you have the declaration of `asprintf', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_ASPRINTF
|
||||
|
||||
/* Define to 1 if you have the declaration of `snprintf', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_SNPRINTF
|
||||
|
||||
/* Define to 1 if you have the declaration of `vasprintf', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_VASPRINTF
|
||||
|
||||
/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_VSNPRINTF
|
||||
|
||||
/* Define to 1 if you have the <direct.h> header file. */
|
||||
#undef HAVE_DIRECT_H
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define to 1 if you have the `dlclose' function. */
|
||||
#undef HAVE_DLCLOSE
|
||||
|
||||
/* Define to 1 if you have the `dlerror' function. */
|
||||
#undef HAVE_DLERROR
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the `dlopen' function. */
|
||||
#undef HAVE_DLOPEN
|
||||
|
||||
/* Define to 1 if you have the `dlsym' function. */
|
||||
#undef HAVE_DLSYM
|
||||
|
||||
/* 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
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if you have the <fnmatch.h> header file. */
|
||||
#undef HAVE_FNMATCH_H
|
||||
|
||||
/* Define to 1 if you have the `ftruncate' function. */
|
||||
#undef HAVE_FTRUNCATE
|
||||
|
||||
/* Whether there is a __FUNCTION__ macro */
|
||||
#undef HAVE_FUNCTION_MACRO
|
||||
|
||||
/* Define to 1 if you have the `getdents' function. */
|
||||
#undef HAVE_GETDENTS
|
||||
|
||||
/* Define to 1 if you have the `getdirentries' function. */
|
||||
#undef HAVE_GETDIRENTRIES
|
||||
|
||||
/* Define to 1 if you have the `getnetgrent' function. */
|
||||
#undef HAVE_GETNETGRENT
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#undef HAVE_GETOPT_H
|
||||
|
||||
/* Define to 1 if you have the `getpagesize' function. */
|
||||
#undef HAVE_GETPAGESIZE
|
||||
|
||||
/* Define to 1 if you have the `getpgrp' function. */
|
||||
#undef HAVE_GETPGRP
|
||||
|
||||
/* Define to 1 if you have the <grp.h> header file. */
|
||||
#undef HAVE_GRP_H
|
||||
|
||||
/* Whether the compiler supports immediate structures */
|
||||
#undef HAVE_IMMEDIATE_STRUCTURES
|
||||
|
||||
/* Define to 1 if you have the `initgroups' function. */
|
||||
#undef HAVE_INITGROUPS
|
||||
|
||||
/* Define to 1 if you have the `innetgr' function. */
|
||||
#undef HAVE_INNETGR
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#undef HAVE_LOCALE_H
|
||||
|
||||
/* Define to 1 if the system has the type `long long'. */
|
||||
#undef HAVE_LONG_LONG
|
||||
|
||||
/* Define to 1 if you have the `lstat' function. */
|
||||
#undef HAVE_LSTAT
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#undef HAVE_MEMCPY
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
#undef HAVE_MEMMOVE
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#undef HAVE_MEMSET
|
||||
|
||||
/* Define if target mkdir supports mode option */
|
||||
#undef HAVE_MKDIR_MODE
|
||||
|
||||
/* Define to 1 if you have the `mkdtemp' function. */
|
||||
#undef HAVE_MKDTEMP
|
||||
|
||||
/* Define to 1 if you have the `mktime' function. */
|
||||
#undef HAVE_MKTIME
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#undef HAVE_NETDB_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/in_ip.h> header file. */
|
||||
#undef HAVE_NETINET_IN_IP_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/in_systm.h> header file. */
|
||||
#undef HAVE_NETINET_IN_SYSTM_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/ip.h> header file. */
|
||||
#undef HAVE_NETINET_IP_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
||||
#undef HAVE_NETINET_TCP_H
|
||||
|
||||
/* usability of net/if.h */
|
||||
#undef HAVE_NET_IF_H
|
||||
|
||||
/* Whether the open(2) accepts O_DIRECT */
|
||||
#undef HAVE_OPEN_O_DIRECT
|
||||
|
||||
/* Define to 1 if you have the `pipe' function. */
|
||||
#undef HAVE_PIPE
|
||||
|
||||
/* Define to 1 if you have the `pread' function. */
|
||||
#undef HAVE_PREAD
|
||||
|
||||
/* Whether pread() is available */
|
||||
#undef HAVE_PREAD_DECL
|
||||
|
||||
/* Define to 1 if you have the `printf' function. */
|
||||
#undef HAVE_PRINTF
|
||||
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#undef HAVE_PWD_H
|
||||
|
||||
/* Define to 1 if you have the `pwrite' function. */
|
||||
#undef HAVE_PWRITE
|
||||
|
||||
/* Whether pwrite() is available */
|
||||
#undef HAVE_PWRITE_DECL
|
||||
|
||||
/* Define to 1 if you have the `rand' function. */
|
||||
#undef HAVE_RAND
|
||||
|
||||
/* Define to 1 if you have the `random' function. */
|
||||
#undef HAVE_RANDOM
|
||||
|
||||
/* Define to 1 if you have the `rename' function. */
|
||||
#undef HAVE_RENAME
|
||||
|
||||
/* Whether mkstemp is secure */
|
||||
#undef HAVE_SECURE_MKSTEMP
|
||||
|
||||
/* Define to 1 if you have the `setbuffer' function. */
|
||||
#undef HAVE_SETBUFFER
|
||||
|
||||
/* Define to 1 if you have the `setegid' function. */
|
||||
#undef HAVE_SETEGID
|
||||
|
||||
/* Define to 1 if you have the `setenv' function. */
|
||||
#undef HAVE_SETENV
|
||||
|
||||
/* Define to 1 if you have the `seteuid' function. */
|
||||
#undef HAVE_SETEUID
|
||||
|
||||
/* Define to 1 if you have the `setlinebuf' function. */
|
||||
#undef HAVE_SETLINEBUF
|
||||
|
||||
/* Define to 1 if you have the `setnetgrent' function. */
|
||||
#undef HAVE_SETNETGRENT
|
||||
|
||||
/* Define to 1 if you have the `setresgid' function. */
|
||||
#undef HAVE_SETRESGID
|
||||
|
||||
/* Whether setresgid() is available */
|
||||
#undef HAVE_SETRESGID_DECL
|
||||
|
||||
/* Define to 1 if you have the `setresuid' function. */
|
||||
#undef HAVE_SETRESUID
|
||||
|
||||
/* Whether setresuid() is available */
|
||||
#undef HAVE_SETRESUID_DECL
|
||||
|
||||
/* Define to 1 if you have the <shadow.h> header file. */
|
||||
#undef HAVE_SHADOW_H
|
||||
|
||||
/* Whether we have the atomic_t variable type */
|
||||
#undef HAVE_SIG_ATOMIC_T_TYPE
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#undef HAVE_SNPRINTF
|
||||
|
||||
/* Define to 1 if you have the `socketpair' function. */
|
||||
#undef HAVE_SOCKETPAIR
|
||||
|
||||
/* Define to 1 if you have the `srand' function. */
|
||||
#undef HAVE_SRAND
|
||||
|
||||
/* Define to 1 if you have the `srandom' function. */
|
||||
#undef HAVE_SRANDOM
|
||||
|
||||
/* Define to 1 if you have the <standards.h> header file. */
|
||||
#undef HAVE_STANDARDS_H
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#undef HAVE_STDARG_H
|
||||
|
||||
/* Define to 1 if you have the <stdbool.h> header file. */
|
||||
#undef HAVE_STDBOOL_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#undef HAVE_STDIO_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strcasestr' function. */
|
||||
#undef HAVE_STRCASESTR
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#undef HAVE_STRDUP
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strlcat' function. */
|
||||
#undef HAVE_STRLCAT
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
/* Define to 1 if you have the `strndup' function. */
|
||||
#undef HAVE_STRNDUP
|
||||
|
||||
/* Define to 1 if you have the `strnlen' function. */
|
||||
#undef HAVE_STRNLEN
|
||||
|
||||
/* Define to 1 if you have the `strtok_r' function. */
|
||||
#undef HAVE_STRTOK_R
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#undef HAVE_STRTOLL
|
||||
|
||||
/* Define to 1 if you have the `strtoq' function. */
|
||||
#undef HAVE_STRTOQ
|
||||
|
||||
/* Define to 1 if you have the `strtoull' function. */
|
||||
#undef HAVE_STRTOULL
|
||||
|
||||
/* Define to 1 if you have the `strtouq' function. */
|
||||
#undef HAVE_STRTOUQ
|
||||
|
||||
/* Define to 1 if `st_rdev' is member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_RDEV
|
||||
|
||||
/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
|
||||
`HAVE_STRUCT_STAT_ST_RDEV' instead. */
|
||||
#undef HAVE_ST_RDEV
|
||||
|
||||
/* Define to 1 if you have the `syslog' function. */
|
||||
#undef HAVE_SYSLOG
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#undef HAVE_SYSLOG_H
|
||||
|
||||
/* Define to 1 if you have the <sys/acl.h> header file. */
|
||||
#undef HAVE_SYS_ACL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/capability.h> header file. */
|
||||
#undef HAVE_SYS_CAPABILITY_H
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#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
|
||||
|
||||
/* Define to 1 if you have the <sys/filio.h> header file. */
|
||||
#undef HAVE_SYS_FILIO_H
|
||||
|
||||
/* Define to 1 if you have the <sys/filsys.h> header file. */
|
||||
#undef HAVE_SYS_FILSYS_H
|
||||
|
||||
/* Define to 1 if you have the <sys/fs/s5param.h> header file. */
|
||||
#undef HAVE_SYS_FS_S5PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/id.h> header file. */
|
||||
#undef HAVE_SYS_ID_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#undef HAVE_SYS_IOCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ipc.h> header file. */
|
||||
#undef HAVE_SYS_IPC_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mode.h> header file. */
|
||||
#undef HAVE_SYS_MODE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/priv.h> header file. */
|
||||
#undef HAVE_SYS_PRIV_H
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#undef HAVE_SYS_RESOURCE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/security.h> header file. */
|
||||
#undef HAVE_SYS_SECURITY_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/shm.h> header file. */
|
||||
#undef HAVE_SYS_SHM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
||||
#undef HAVE_SYS_SOCKIO_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/syslog.h> header file. */
|
||||
#undef HAVE_SYS_SYSLOG_H
|
||||
|
||||
/* Define to 1 if you have the <sys/termio.h> header file. */
|
||||
#undef HAVE_SYS_TERMIO_H
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/un.h> header file. */
|
||||
#undef HAVE_SYS_UN_H
|
||||
|
||||
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#undef HAVE_TERMIOS_H
|
||||
|
||||
/* Define to 1 if you have the <termio.h> header file. */
|
||||
#undef HAVE_TERMIO_H
|
||||
|
||||
/* Define to 1 if you have the `timegm' function. */
|
||||
#undef HAVE_TIMEGM
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#undef HAVE_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#undef HAVE_USLEEP
|
||||
|
||||
/* Define to 1 if you have the `utime' function. */
|
||||
#undef HAVE_UTIME
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#undef HAVE_UTIME_H
|
||||
|
||||
/* Define to 1 if you have the <vararg.h> header file. */
|
||||
#undef HAVE_VARARG_H
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
#undef HAVE_VASPRINTF
|
||||
|
||||
/* Whether va_copy() is available */
|
||||
#undef HAVE_VA_COPY
|
||||
|
||||
/* Whether the C compiler understands volatile */
|
||||
#undef HAVE_VOLATILE
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
/* Define to 1 if you have the `vsyslog' function. */
|
||||
#undef HAVE_VSYSLOG
|
||||
|
||||
/* Define to 1 if you have the `waitpid' function. */
|
||||
#undef HAVE_WAITPID
|
||||
|
||||
/* Define to 1 if you have the <windows.h> header file. */
|
||||
#undef HAVE_WINDOWS_H
|
||||
|
||||
/* Define to 1 if you have the <winsock2.h> header file. */
|
||||
#undef HAVE_WINSOCK2_H
|
||||
|
||||
/* Define to 1 if you have the <ws2tcpip.h> header file. */
|
||||
#undef HAVE_WS2TCPIP_H
|
||||
|
||||
/* Whether the _Bool type is available */
|
||||
#undef HAVE__Bool
|
||||
|
||||
/* Whether the __VA_ARGS__ macro is available */
|
||||
#undef HAVE__VA_ARGS__MACRO
|
||||
|
||||
/* Define to 1 if you have the `__strtoll' function. */
|
||||
#undef HAVE___STRTOLL
|
||||
|
||||
/* Define to 1 if you have the `__strtoull' function. */
|
||||
#undef HAVE___STRTOULL
|
||||
|
||||
/* Whether __va_copy() is available */
|
||||
#undef HAVE___VA_COPY
|
||||
|
||||
/* Whether there is a __func__ macro */
|
||||
#undef HAVE_func_MACRO
|
||||
|
||||
/* Whether MMAP is broken */
|
||||
#undef MMAP_BLACKLIST
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Whether getpass should be replaced */
|
||||
#undef REPLACE_GETPASS
|
||||
|
||||
/* Whether inet_ntoa should be replaced */
|
||||
#undef REPLACE_INET_NTOA
|
||||
|
||||
/* replace readdir */
|
||||
#undef REPLACE_READDIR
|
||||
|
||||
/* replace readdir using getdents() */
|
||||
#undef REPLACE_READDIR_GETDENTS
|
||||
|
||||
/* replace readdir using getdirentries() */
|
||||
#undef REPLACE_READDIR_GETDIRENTRIES
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* Whether seekdir returns an int */
|
||||
#undef SEEKDIR_RETURNS_INT
|
||||
|
||||
/* The size of `char', as computed by sizeof. */
|
||||
#undef SIZEOF_CHAR
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#undef SIZEOF_INT
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG
|
||||
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG_LONG
|
||||
|
||||
/* The size of `off_t', as computed by sizeof. */
|
||||
#undef SIZEOF_OFF_T
|
||||
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
#undef SIZEOF_SHORT
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#undef SIZEOF_SIZE_T
|
||||
|
||||
/* The size of `ssize_t', as computed by sizeof. */
|
||||
#undef SIZEOF_SSIZE_T
|
||||
|
||||
/* The size of `void *', as computed by sizeof. */
|
||||
#undef SIZEOF_VOID_P
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Whether telldir takes a const pointer */
|
||||
#undef TELLDIR_TAKES_CONST_DIR
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#undef TIME_WITH_SYS_TIME
|
||||
|
||||
/* Define to 1 if your processor stores words with the most significant byte
|
||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
#undef WORDS_BIGENDIAN
|
||||
|
||||
/* Define to 1 if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
#ifndef _OSF_SOURCE
|
||||
# define _OSF_SOURCE 1
|
||||
#endif
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Whether to enable POSIX support */
|
||||
#undef _POSIX_C_SOURCE
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Whether to enable System V compatibility */
|
||||
#undef _SYSV
|
||||
|
||||
#ifndef _XOPEN_SOURCE_EXTENDED
|
||||
# define _XOPEN_SOURCE_EXTENDED 1
|
||||
#endif
|
||||
|
||||
/* Enable extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef gid_t
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#undef ino_t
|
||||
|
||||
/* Define to `short' if <sys/types.h> does not define. */
|
||||
#undef int16_t
|
||||
|
||||
/* Define to `long' if <sys/types.h> does not define. */
|
||||
#undef int32_t
|
||||
|
||||
/* Define to `long long' if <sys/types.h> does not define. */
|
||||
#undef int64_t
|
||||
|
||||
/* Define to `char' if <sys/types.h> does not define. */
|
||||
#undef int8_t
|
||||
|
||||
/* Define to `unsigned long long' if <sys/types.h> does not define. */
|
||||
#undef intptr_t
|
||||
|
||||
/* Define to `off_t' if <sys/types.h> does not define. */
|
||||
#undef loff_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef mode_t
|
||||
|
||||
/* Define to `long int' if <sys/types.h> does not define. */
|
||||
#undef off_t
|
||||
|
||||
/* Define to `loff_t' if <sys/types.h> does not define. */
|
||||
#undef offset_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define to `unsigned long long' if <sys/types.h> does not define. */
|
||||
#undef ptrdiff_t
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* Socket length type */
|
||||
#undef socklen_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef ssize_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef uid_t
|
||||
|
||||
/* Define to `unsigned short' if <sys/types.h> does not define. */
|
||||
#undef uint16_t
|
||||
|
||||
/* Define to `unsigned long' if <sys/types.h> does not define. */
|
||||
#undef uint32_t
|
||||
|
||||
/* Define to `unsigned long long' if <sys/types.h> does not define. */
|
||||
#undef uint64_t
|
||||
|
||||
/* Define to `unsigned char' if <sys/types.h> does not define. */
|
||||
#undef uint8_t
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef uint_t
|
1021
ctdb/config.status
Executable file
1021
ctdb/config.status
Executable file
File diff suppressed because it is too large
Load Diff
1579
ctdb/config.sub
vendored
Executable file
1579
ctdb/config.sub
vendored
Executable file
File diff suppressed because it is too large
Load Diff
22878
ctdb/configure
vendored
Executable file
22878
ctdb/configure
vendored
Executable file
File diff suppressed because it is too large
Load Diff
32
ctdb/configure.ac
Normal file
32
ctdb/configure.ac
Normal file
@ -0,0 +1,32 @@
|
||||
AC_PREREQ(2.50)
|
||||
AC_DEFUN([AC_CHECK_LIB_EXT], [
|
||||
AC_CHECK_LIB([$1],[$3],[$4],[$5],[$7])
|
||||
ac_cv_lib_ext_$1_$3=$ac_cv_lib_$1_$3
|
||||
])
|
||||
AC_DEFUN([AC_CHECK_FUNC_EXT], [
|
||||
AC_CHECK_FUNC([$1],[$3],[$4])
|
||||
ac_cv_func_ext_$1=$ac_cv_func_$1
|
||||
])
|
||||
AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""])
|
||||
AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""])
|
||||
AC_DEFUN([SMB_EXT_LIB], [echo -n ""])
|
||||
AC_DEFUN([SMB_ENABLE], [echo -n ""])
|
||||
AC_INIT(ctdb.h)
|
||||
AC_CONFIG_SRCDIR([ctdb_daemon.c])
|
||||
|
||||
AC_LIBREPLACE_ALL_CHECKS
|
||||
|
||||
if test "$ac_cv_prog_gcc" = yes; then
|
||||
CFLAGS="$CFLAGS -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings"
|
||||
fi
|
||||
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
EXTRA_OBJ=""
|
||||
|
||||
m4_include(libtalloc.m4)
|
||||
m4_include(libtdb.m4)
|
||||
|
||||
AC_SUBST(EXTRA_OBJ)
|
||||
|
||||
AC_OUTPUT(Makefile)
|
74
ctdb/ctdb.h
Normal file
74
ctdb/ctdb.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
ctdb database library
|
||||
|
||||
Copyright (C) Andrew Tridgell 2006
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
structure passed to a ctdb call function
|
||||
*/
|
||||
struct ctdb_call {
|
||||
TDB_DATA key; /* record key */
|
||||
TDB_DATA record_data; /* current data in the record */
|
||||
TDB_DATA *new_data; /* optionally updated record data */
|
||||
TDB_DATA *call_data; /* optionally passed from caller */
|
||||
TDB_DATA *reply_data; /* optionally returned by function */
|
||||
};
|
||||
|
||||
#define CTDB_ERR_INVALID 1
|
||||
#define CTDB_ERR_NOMEM 2
|
||||
|
||||
|
||||
/*
|
||||
initialise ctdb subsystem
|
||||
*/
|
||||
struct ctdb_context *ctdb_init(TALLOC_CTX *mem_ctx);
|
||||
|
||||
/*
|
||||
tell ctdb what nodes are available. This takes a filename, which will contain
|
||||
1 node address per line, in a transport specific format
|
||||
*/
|
||||
int ctdb_set_nlist(struct ctdb_context *ctdb, const char *nlist);
|
||||
|
||||
|
||||
/*
|
||||
error string for last ctdb error
|
||||
*/
|
||||
const char *ctdb_errstr(struct ctdb_context *);
|
||||
|
||||
/* a ctdb call function */
|
||||
typedef int (*ctdb_fn_t)(struct ctdb_call *);
|
||||
|
||||
/*
|
||||
setup a ctdb call function
|
||||
*/
|
||||
int ctdb_set_call(struct ctdb_context *ctdb, ctdb_fn_t fn, int id);
|
||||
|
||||
/*
|
||||
attach to a ctdb database
|
||||
*/
|
||||
int ctdb_attach(struct ctdb_context *ctdb, const char *name, int tdb_flags,
|
||||
int open_flags, mode_t mode);
|
||||
|
||||
|
||||
/*
|
||||
make a ctdb call. The associated ctdb call function will be called on the DMASTER
|
||||
for the given record
|
||||
*/
|
||||
int ctdb_call(struct ctdb_context *ctdb, TDB_DATA key, int call_id,
|
||||
TDB_DATA *call_data, TDB_DATA *reply_data);
|
20
ctdb/ctdb_daemon.c
Normal file
20
ctdb/ctdb_daemon.c
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
ctdb database library
|
||||
|
||||
Copyright (C) Andrew Tridgell 2006
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
59
ctdb/ctdb_private.h
Normal file
59
ctdb/ctdb_private.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
ctdb database library
|
||||
|
||||
Copyright (C) Andrew Tridgell 2006
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
a pending ctdb request
|
||||
*/
|
||||
struct ctdb_request {
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
an installed ctdb remote call
|
||||
*/
|
||||
struct ctdb_registered_call {
|
||||
struct ctdb_registered_call *next, *prev;
|
||||
uint32_t id;
|
||||
ctdb_fn_t fn;
|
||||
};
|
||||
|
||||
/*
|
||||
state associated with one node
|
||||
*/
|
||||
struct ctdb_node {
|
||||
struct ctdb_context *ctdb;
|
||||
struct ctdb_node *next, *prev;
|
||||
const char *address;
|
||||
int port;
|
||||
int fd;
|
||||
};
|
||||
|
||||
/* main state of the ctdb daemon */
|
||||
struct ctdb_context {
|
||||
struct event_context *ev;
|
||||
struct ctdb_node *nodes; /* list of nodes in the cluster */
|
||||
struct ctdb_registered_call *calls; /* list of registered calls */
|
||||
char *err_msg;
|
||||
struct tdb_context *ltdb;
|
||||
};
|
||||
|
||||
|
||||
#define CTDB_SOCKET "/tmp/ctdb.sock"
|
218
ctdb/ctdb_tcp.c
Normal file
218
ctdb/ctdb_tcp.c
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
ctdb over TCP
|
||||
|
||||
Copyright (C) Andrew Tridgell 2006
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "system/network.h"
|
||||
#include "system/filesys.h"
|
||||
#include "ctdb_private.h"
|
||||
|
||||
/*
|
||||
initialise the ctdb daemon.
|
||||
|
||||
if the ctdb dispatcher daemon has already been started then this
|
||||
does nothing. Otherwise it forks the ctdb dispatcher daemon and
|
||||
starts the daemons connecting to each other
|
||||
|
||||
NOTE: In current code the daemon does not fork. This is for testing purposes only
|
||||
and to simplify the code.
|
||||
*/
|
||||
|
||||
struct ctdb_context *ctdb_init(TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
struct ctdb_context *ctdb;
|
||||
|
||||
ctdb = talloc_zero(mem_ctx, struct ctdb_context);
|
||||
return ctdb;
|
||||
}
|
||||
|
||||
const char *ctdb_errstr(struct ctdb_context *ctdb)
|
||||
{
|
||||
return ctdb->err_msg;
|
||||
}
|
||||
|
||||
/*
|
||||
remember an error message
|
||||
*/
|
||||
static void ctdb_set_error(struct ctdb_context *ctdb, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
talloc_free(ctdb->err_msg);
|
||||
va_start(ap, fmt);
|
||||
ctdb->err_msg = talloc_vasprintf(ctdb, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*
|
||||
called when socket becomes readable
|
||||
*/
|
||||
static void ctdb_node_read(struct event_context *ev, struct fd_event *fde,
|
||||
uint16_t flags, void *private)
|
||||
{
|
||||
struct ctdb_node *node = talloc_get_type(private, struct ctdb_node);
|
||||
printf("connection to node %s:%u is readable\n", node->address, node->port);
|
||||
event_set_fd_flags(fde, 0);
|
||||
}
|
||||
|
||||
static void ctdb_node_connect(struct event_context *ev, struct timed_event *te,
|
||||
struct timeval t, void *private);
|
||||
|
||||
/*
|
||||
called when socket becomes writeable on connect
|
||||
*/
|
||||
static void ctdb_node_connect_write(struct event_context *ev, struct fd_event *fde,
|
||||
uint16_t flags, void *private)
|
||||
{
|
||||
struct ctdb_node *node = talloc_get_type(private, struct ctdb_node);
|
||||
struct ctdb_context *ctdb = node->ctdb;
|
||||
int error;
|
||||
socklen_t len;
|
||||
|
||||
if (getsockopt(node->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0 ||
|
||||
errno != 0) {
|
||||
close(node->fd);
|
||||
event_add_timed(ctdb->ev, node, timeval_current_ofs(1, 0),
|
||||
ctdb_node_connect, node);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Established connection to %s:%u\n", node->address, node->port);
|
||||
talloc_free(fde);
|
||||
event_add_fd(node->ctdb->ev, node, node->fd, EVENT_FD_READ,
|
||||
ctdb_node_read, node);
|
||||
}
|
||||
|
||||
/*
|
||||
called when we should try and establish a tcp connection to a node
|
||||
*/
|
||||
static void ctdb_node_connect(struct event_context *ev, struct timed_event *te,
|
||||
struct timeval t, void *private)
|
||||
{
|
||||
struct ctdb_node *node = talloc_get_type(node, struct ctdb_node);
|
||||
struct ctdb_context *ctdb = node->ctdb;
|
||||
unsigned v;
|
||||
struct sockaddr_in sock_out;
|
||||
|
||||
node->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
v = fcntl(node->fd, F_GETFL, 0);
|
||||
fcntl(node->fd, F_SETFL, v | O_NONBLOCK);
|
||||
|
||||
inet_pton(AF_INET, node->address, &sock_out.sin_addr);
|
||||
sock_out.sin_port = htons(node->port);
|
||||
sock_out.sin_family = PF_INET;
|
||||
|
||||
if (connect(node->fd, &sock_out, sizeof(sock_out)) != 0 &&
|
||||
errno != EINPROGRESS) {
|
||||
/* try again once a second */
|
||||
close(node->fd);
|
||||
event_add_timed(ctdb->ev, node, timeval_current_ofs(1, 0),
|
||||
ctdb_node_connect, node);
|
||||
return;
|
||||
}
|
||||
|
||||
/* non-blocking connect - wait for write event */
|
||||
event_add_fd(node->ctdb->ev, node, node->fd, EVENT_FD_WRITE,
|
||||
ctdb_node_connect_write, node);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
add a node to the list of active nodes
|
||||
*/
|
||||
static int ctdb_add_node(struct ctdb_context *ctdb, char *nstr)
|
||||
{
|
||||
struct ctdb_node *node;
|
||||
|
||||
/* expected to be in IP:port format */
|
||||
char *p;
|
||||
p = strchr(nstr, ':');
|
||||
if (p == NULL) {
|
||||
ctdb_set_error(ctdb, "Badly formed node '%s'\n", nstr);
|
||||
return -1;
|
||||
}
|
||||
*p++ = 0;
|
||||
|
||||
node = talloc(ctdb, struct ctdb_node);
|
||||
node->address = talloc_strdup(node, nstr);
|
||||
node->port = strtoul(p, NULL, 0);
|
||||
node->fd = -1;
|
||||
node->ctdb = ctdb;
|
||||
|
||||
DLIST_ADD(ctdb->nodes, node);
|
||||
event_add_timed(ctdb->ev, node, timeval_zero(), ctdb_node_connect, node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
setup the node list from a file
|
||||
*/
|
||||
int ctdb_set_nlist(struct ctdb_context *ctdb, const char *nlist)
|
||||
{
|
||||
char **lines;
|
||||
int nlines;
|
||||
int i;
|
||||
|
||||
lines = file_lines_load(nlist, &nlines, ctdb);
|
||||
if (lines == NULL) {
|
||||
ctdb_set_error(ctdb, "Failed to load nlist '%s'\n", nlist);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0;i<nlines;i++) {
|
||||
if (ctdb_add_node(ctdb, lines[i]) != 0) {
|
||||
talloc_free(lines);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
talloc_free(lines);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
add a node to the list of active nodes
|
||||
*/
|
||||
int ctdb_set_call(struct ctdb_context *ctdb, ctdb_fn_t fn, int id)
|
||||
{
|
||||
struct ctdb_registered_call *call;
|
||||
|
||||
call = talloc(ctdb, struct ctdb_registered_call);
|
||||
call->fn = fn;
|
||||
call->id = id;
|
||||
|
||||
DLIST_ADD(ctdb->calls, call);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
attach to a specific database
|
||||
*/
|
||||
int ctdb_attach(struct ctdb_context *ctdb, const char *name, int tdb_flags,
|
||||
int open_flags, mode_t mode)
|
||||
{
|
||||
ctdb->ltdb = tdb_open(name, 0, TDB_INTERNAL, 0, 0);
|
||||
if (ctdb->ltdb == NULL) {
|
||||
ctdb_set_error(ctdb, "Failed to open tdb %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
70
ctdb/ctdb_tcp_child.c
Normal file
70
ctdb/ctdb_tcp_child.c
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
ctdb over TCP
|
||||
|
||||
Copyright (C) Andrew Tridgell 2006
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/network.h"
|
||||
#include "system/filesys.h"
|
||||
#include "ctdb_private.h"
|
||||
|
||||
struct ctdb_child_state {
|
||||
int sock;
|
||||
struct event_context *ev;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
create a unix domain socket and bind it
|
||||
return a file descriptor open on the socket
|
||||
*/
|
||||
static int ux_socket_bind(const char *name)
|
||||
{
|
||||
int fd;
|
||||
struct sockaddr_un addr;
|
||||
|
||||
/* get rid of any old socket */
|
||||
unlink(name);
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
||||
if (fd == -1) return -1;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, name, sizeof(addr.sun_path));
|
||||
|
||||
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/*
|
||||
start the ctdb tcp child daemon
|
||||
*/
|
||||
int ctdb_tcp_child(void)
|
||||
{
|
||||
struct ctdb_child_state *state;
|
||||
|
||||
state = talloc(NULL, struct ctdb_child_state);
|
||||
state->sock = ux_socket_bind(CTDB_SOCKET);
|
||||
|
||||
return 0;
|
||||
}
|
166
ctdb/ctdb_test.c
Normal file
166
ctdb/ctdb_test.c
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
ctdb test harness
|
||||
|
||||
Copyright (C) Andrew Tridgell 2006
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "replace.h"
|
||||
#include "system/filesys.h"
|
||||
#include "tdb.h"
|
||||
#include "talloc.h"
|
||||
#include "ctdb.h"
|
||||
#include "popt.h"
|
||||
|
||||
enum my_functions {FUNC_SORT=1, FUNC_FETCH=2};
|
||||
|
||||
static int int_compare(int *i1, int *i2)
|
||||
{
|
||||
return *i1 - *i2;
|
||||
}
|
||||
|
||||
/*
|
||||
add an integer into a record in sorted order
|
||||
*/
|
||||
static int sort_func(struct ctdb_call *call)
|
||||
{
|
||||
if (call->call_data == NULL ||
|
||||
call->call_data->dsize != sizeof(int)) {
|
||||
return CTDB_ERR_INVALID;
|
||||
}
|
||||
call->new_data = talloc(call, TDB_DATA);
|
||||
if (call->new_data == NULL) {
|
||||
return CTDB_ERR_NOMEM;
|
||||
}
|
||||
call->new_data->dptr = talloc_size(call,
|
||||
call->record_data.dsize +
|
||||
call->call_data->dsize);
|
||||
if (call->new_data->dptr == NULL) {
|
||||
return CTDB_ERR_NOMEM;
|
||||
}
|
||||
call->new_data->dsize = call->record_data.dsize + call->call_data->dsize;
|
||||
memcpy(call->new_data->dptr+call->record_data.dsize,
|
||||
call->call_data->dptr, call->call_data->dsize);
|
||||
qsort(call->new_data->dptr, call->new_data->dsize / sizeof(int),
|
||||
sizeof(int), (comparison_fn_t)int_compare);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
ctdb call function to fetch a record
|
||||
*/
|
||||
static int fetch_func(struct ctdb_call *call)
|
||||
{
|
||||
call->reply_data = &call->record_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
main program
|
||||
*/
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
struct ctdb_context *ctdb;
|
||||
const char *nlist = NULL;
|
||||
struct poptOption popt_options[] = {
|
||||
POPT_AUTOHELP
|
||||
{ "nlist", 0, POPT_ARG_STRING, &nlist, 0, "node list file", "filename" },
|
||||
};
|
||||
int opt;
|
||||
const char **extra_argv;
|
||||
int extra_argc = 0;
|
||||
int i, ret;
|
||||
TDB_DATA key, data;
|
||||
poptContext pc;
|
||||
|
||||
pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
|
||||
|
||||
while ((opt = poptGetNextOpt(pc)) != -1) {
|
||||
switch (opt) {
|
||||
default:
|
||||
fprintf(stderr, "Invalid option %s: %s\n",
|
||||
poptBadOption(pc, 0), poptStrerror(opt));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* setup the remaining options for the main program to use */
|
||||
extra_argv = poptGetArgs(pc);
|
||||
if (extra_argv) {
|
||||
extra_argv++;
|
||||
while (extra_argv[extra_argc]) extra_argc++;
|
||||
}
|
||||
|
||||
if (nlist == NULL) {
|
||||
printf("You must provide a node list with --nlist\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* initialise ctdb */
|
||||
ctdb = ctdb_init(NULL);
|
||||
if (ctdb == NULL) {
|
||||
printf("Failed to init ctdb\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* tell ctdb what nodes are available */
|
||||
ret = ctdb_set_nlist(ctdb, nlist);
|
||||
if (ret == -1) {
|
||||
printf("ctdb_set_nlist failed - %s\n", ctdb_errstr(ctdb));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* setup a ctdb call function */
|
||||
ret = ctdb_set_call(ctdb, sort_func, FUNC_SORT);
|
||||
ret = ctdb_set_call(ctdb, fetch_func, FUNC_FETCH);
|
||||
|
||||
/* attach to a specific database */
|
||||
ret = ctdb_attach(ctdb, "test.tdb", TDB_DEFAULT, O_RDWR|O_CREAT|O_TRUNC, 0666);
|
||||
if (ret == -1) {
|
||||
printf("ctdb_attach failed - %s\n", ctdb_errstr(ctdb));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
key.dptr = "test";
|
||||
key.dsize = strlen("test")+1;
|
||||
|
||||
/* add some random data */
|
||||
for (i=0;i<100;i++) {
|
||||
int v = random();
|
||||
data.dptr = (uint8_t *)&v;
|
||||
data.dsize = sizeof(v);
|
||||
ret = ctdb_call(ctdb, key, FUNC_SORT, &data, NULL);
|
||||
if (ret == -1) {
|
||||
printf("ctdb_call FUNC_SORT failed - %s\n", ctdb_errstr(ctdb));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* fetch the record */
|
||||
ret = ctdb_call(ctdb, key, FUNC_FETCH, NULL, &data);
|
||||
if (ret == -1) {
|
||||
printf("ctdb_call FUNC_FETCH failed - %s\n", ctdb_errstr(ctdb));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i=0;i<data.dsize/sizeof(int);i++) {
|
||||
printf("%3d\n", ((int *)data.dptr)[i]);
|
||||
}
|
||||
|
||||
/* shut it down */
|
||||
talloc_free(ctdb);
|
||||
return 0;
|
||||
}
|
29
ctdb/includes.h
Normal file
29
ctdb/includes.h
Normal file
@ -0,0 +1,29 @@
|
||||
#define HAVE_UNIXSOCKET 1
|
||||
|
||||
#include "replace.h"
|
||||
#include "talloc.h"
|
||||
#include "tdb.h"
|
||||
#include "ctdb.h"
|
||||
#include "dlinklist.h"
|
||||
|
||||
typedef bool BOOL;
|
||||
|
||||
#define True 1
|
||||
#define False 0
|
||||
|
||||
#define DEBUG(lvl, x) printf x
|
||||
|
||||
#define _PUBLIC_
|
||||
|
||||
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
|
||||
|
||||
struct timeval timeval_zero(void);
|
||||
bool timeval_is_zero(const struct timeval *tv);
|
||||
struct timeval timeval_current(void);
|
||||
struct timeval timeval_set(uint32_t secs, uint32_t usecs);
|
||||
int timeval_compare(const struct timeval *tv1, const struct timeval *tv2);
|
||||
struct timeval timeval_until(const struct timeval *tv1,
|
||||
const struct timeval *tv2);
|
||||
_PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs);
|
||||
char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx);
|
||||
|
238
ctdb/install-sh
Executable file
238
ctdb/install-sh
Executable file
@ -0,0 +1,238 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
#
|
||||
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
transformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd="$cpprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd="$stripprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "install: no input file specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
instcmd=mkdir
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
then
|
||||
true
|
||||
else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# If destination is a directory, append the input filename; if your system
|
||||
# does not like double slashes in filenames, you may need to add some logic
|
||||
|
||||
if [ -d $dst ]
|
||||
then
|
||||
dst="$dst"/`basename $src`
|
||||
else
|
||||
true
|
||||
fi
|
||||
fi
|
||||
|
||||
## this sed command emulates the dirname command
|
||||
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
oIFS="${IFS}"
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS="${oIFS}"
|
||||
|
||||
pathcomp=''
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
pathcomp="${pathcomp}${1}"
|
||||
shift
|
||||
|
||||
if [ ! -d "${pathcomp}" ] ;
|
||||
then
|
||||
$mkdirprog "${pathcomp}"
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
pathcomp="${pathcomp}/"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd $dst &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
|
||||
else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# Make a temp file name in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
$doit $instcmd $src $dsttmp &&
|
||||
|
||||
trap "rm -f ${dsttmp}" 0 &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits
|
||||
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
exit 0
|
7
ctdb/lib/events/.svn/dir-prop-base
Normal file
7
ctdb/lib/events/.svn/dir-prop-base
Normal file
@ -0,0 +1,7 @@
|
||||
K 10
|
||||
svn:ignore
|
||||
V 14
|
||||
.sconsign
|
||||
*.d
|
||||
|
||||
END
|
112
ctdb/lib/events/.svn/entries
Normal file
112
ctdb/lib/events/.svn/entries
Normal file
@ -0,0 +1,112 @@
|
||||
8
|
||||
|
||||
dir
|
||||
19729
|
||||
svn+ssh://tridge@cvs.samba.org/home/svn/samba/branches/SAMBA_4_0/source/lib/events
|
||||
svn+ssh://tridge@cvs.samba.org/home/svn/samba
|
||||
|
||||
|
||||
|
||||
2006-08-30T11:29:34.384714Z
|
||||
17930
|
||||
jelmer
|
||||
has-props
|
||||
|
||||
svn:special svn:externals svn:needs-lock
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
0c0555d6-39d7-0310-84fc-f1cc0bd64818
|
||||
|
||||
config.m4
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2005-02-15T10:04:21.000000Z
|
||||
1282a085894097e490c4362dd2bfc4bb
|
||||
2005-02-03T11:56:03.346078Z
|
||||
5197
|
||||
tridge
|
||||
|
||||
events_standard.c
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2006-09-01T04:14:43.000000Z
|
||||
5c3eae22143044dbb2bcba2a5eaafca2
|
||||
2006-08-30T11:29:34.384714Z
|
||||
17930
|
||||
jelmer
|
||||
|
||||
events.c
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2006-03-08T00:18:09.000000Z
|
||||
5cb1576c79a1680a1439c07e5cd84079
|
||||
2006-03-05T17:44:16.286806Z
|
||||
13842
|
||||
jelmer
|
||||
|
||||
events_internal.h
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2005-12-09T23:46:11.000000Z
|
||||
c77ab0d0a4b0db529ccf1175e50d7ff2
|
||||
2005-12-09T16:43:19.753634Z
|
||||
12140
|
||||
metze
|
||||
|
||||
events_liboop.c
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2006-05-24T07:14:55.000000Z
|
||||
26a6f3a336c876daad780ed71dd8018a
|
||||
2006-05-24T07:34:11.364684Z
|
||||
15854
|
||||
tridge
|
||||
|
||||
events.h
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2006-03-20T03:25:13.000000Z
|
||||
576e09771a89f8540d0314e5b81e74a8
|
||||
2006-03-18T15:42:57.807892Z
|
||||
14542
|
||||
jelmer
|
||||
|
||||
config.mk
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2006-04-29T08:13:02.000000Z
|
||||
c3df7aca33e0005d86c389a8f5a04441
|
||||
2006-04-24T15:47:59.920131Z
|
||||
15207
|
||||
jelmer
|
||||
|
1
ctdb/lib/events/.svn/format
Normal file
1
ctdb/lib/events/.svn/format
Normal file
@ -0,0 +1 @@
|
||||
8
|
2
ctdb/lib/events/.svn/text-base/config.m4.svn-base
Normal file
2
ctdb/lib/events/.svn/text-base/config.m4.svn-base
Normal file
@ -0,0 +1,2 @@
|
||||
AC_CHECK_HEADERS(sys/epoll.h)
|
||||
AC_CHECK_FUNCS(epoll_create)
|
7
ctdb/lib/events/.svn/text-base/config.mk.svn-base
Normal file
7
ctdb/lib/events/.svn/text-base/config.mk.svn-base
Normal file
@ -0,0 +1,7 @@
|
||||
##############################
|
||||
# Start SUBSYSTEM LIBEVENTS
|
||||
[SUBSYSTEM::LIBEVENTS]
|
||||
OBJ_FILES = events.o events_standard.o
|
||||
PUBLIC_DEPENDENCIES = LIBTALLOC
|
||||
# End SUBSYSTEM LIBEVENTS
|
||||
##############################
|
175
ctdb/lib/events/.svn/text-base/events.c.svn-base
Normal file
175
ctdb/lib/events/.svn/text-base/events.c.svn-base
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
main select loop and event handling
|
||||
Copyright (C) Andrew Tridgell 2003
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
PLEASE READ THIS BEFORE MODIFYING!
|
||||
|
||||
This module is a general abstraction for the main select loop and
|
||||
event handling. Do not ever put any localised hacks in here, instead
|
||||
register one of the possible event types and implement that event
|
||||
somewhere else.
|
||||
|
||||
There are 2 types of event handling that are handled in this module:
|
||||
|
||||
1) a file descriptor becoming readable or writeable. This is mostly
|
||||
used for network sockets, but can be used for any type of file
|
||||
descriptor. You may only register one handler for each file
|
||||
descriptor/io combination or you will get unpredictable results
|
||||
(this means that you can have a handler for read events, and a
|
||||
separate handler for write events, but not two handlers that are
|
||||
both handling read events)
|
||||
|
||||
2) a timed event. You can register an event that happens at a
|
||||
specific time. You can register as many of these as you
|
||||
like. They are single shot - add a new timed event in the event
|
||||
handler to get another event.
|
||||
|
||||
To setup a set of events you first need to create a event_context
|
||||
structure using the function event_context_init(); This returns a
|
||||
'struct event_context' that you use in all subsequent calls.
|
||||
|
||||
After that you can add/remove events that you are interested in
|
||||
using event_add_*() and talloc_free()
|
||||
|
||||
Finally, you call event_loop_wait_once() to block waiting for one of the
|
||||
events to occor or event_loop_wait() which will loop
|
||||
forever.
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "lib/events/events_internal.h"
|
||||
|
||||
/*
|
||||
create a event_context structure for a specific implemementation.
|
||||
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.
|
||||
|
||||
This function is for allowing third-party-applications to hook in gluecode
|
||||
to their own event loop code, so that they can make async usage of our client libs
|
||||
|
||||
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)
|
||||
{
|
||||
struct event_context *ev;
|
||||
int ret;
|
||||
|
||||
ev = talloc_zero(mem_ctx, struct event_context);
|
||||
if (!ev) return NULL;
|
||||
|
||||
ev->ops = ops;
|
||||
|
||||
ret = ev->ops->context_init(ev, private_data);
|
||||
if (ret != 0) {
|
||||
talloc_free(ev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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(TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
const struct event_ops *ops = event_standard_get_ops();
|
||||
return event_context_init_ops(mem_ctx, ops, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
add a fd based event
|
||||
return NULL on failure (memory allocation error)
|
||||
*/
|
||||
struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
int fd, uint16_t flags, event_fd_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data);
|
||||
}
|
||||
|
||||
/*
|
||||
return the fd event flags
|
||||
*/
|
||||
uint16_t event_get_fd_flags(struct fd_event *fde)
|
||||
{
|
||||
if (!fde) return 0;
|
||||
return fde->event_ctx->ops->get_fd_flags(fde);
|
||||
}
|
||||
|
||||
/*
|
||||
set the fd event flags
|
||||
*/
|
||||
void event_set_fd_flags(struct fd_event *fde, uint16_t flags)
|
||||
{
|
||||
if (!fde) return;
|
||||
fde->event_ctx->ops->set_fd_flags(fde, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
add a timed event
|
||||
return NULL on failure
|
||||
*/
|
||||
struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
struct timeval next_event,
|
||||
event_timed_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
return ev->ops->add_timed(ev, mem_ctx, next_event, handler, private_data);
|
||||
}
|
||||
|
||||
/*
|
||||
do a single event loop using the events defined in ev
|
||||
*/
|
||||
_PUBLIC_ int event_loop_once(struct event_context *ev)
|
||||
{
|
||||
return ev->ops->loop_once(ev);
|
||||
}
|
||||
|
||||
/*
|
||||
return on failure or (with 0) if all fd events are removed
|
||||
*/
|
||||
int event_loop_wait(struct event_context *ev)
|
||||
{
|
||||
return ev->ops->loop_wait(ev);
|
||||
}
|
||||
|
||||
/*
|
||||
find an event context that is a parent of the given memory context,
|
||||
or create a new event context as a child of the given context if
|
||||
none is found
|
||||
|
||||
This should be used in preference to event_context_init() in places
|
||||
where you would prefer to use the existing event context if possible
|
||||
(which is most situations)
|
||||
*/
|
||||
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) {
|
||||
ev = event_context_init(mem_ctx);
|
||||
}
|
||||
return ev;
|
||||
}
|
71
ctdb/lib/events/.svn/text-base/events.h.svn-base
Normal file
71
ctdb/lib/events/.svn/text-base/events.h.svn-base
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
generalised event loop handling
|
||||
|
||||
Copyright (C) Andrew Tridgell 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __EVENTS_H__
|
||||
#define __EVENTS_H__
|
||||
|
||||
struct event_context;
|
||||
struct event_ops;
|
||||
struct fd_event;
|
||||
struct timed_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 *);
|
||||
|
||||
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 fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
int fd, uint16_t flags, event_fd_handler_t handler,
|
||||
void *private);
|
||||
|
||||
struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
struct timeval next_event,
|
||||
event_timed_handler_t handler,
|
||||
void *private);
|
||||
|
||||
int event_loop_once(struct event_context *ev);
|
||||
int event_loop_wait(struct event_context *ev);
|
||||
|
||||
uint16_t event_get_fd_flags(struct fd_event *fde);
|
||||
void event_set_fd_flags(struct fd_event *fde, uint16_t flags);
|
||||
|
||||
struct event_context *event_context_find(TALLOC_CTX *mem_ctx);
|
||||
|
||||
/* bits for file descriptor event flags */
|
||||
#define EVENT_FD_READ 1
|
||||
#define EVENT_FD_WRITE 2
|
||||
|
||||
#define EVENT_FD_WRITEABLE(fde) \
|
||||
event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_WRITE)
|
||||
#define EVENT_FD_READABLE(fde) \
|
||||
event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_READ)
|
||||
|
||||
#define EVENT_FD_NOT_WRITEABLE(fde) \
|
||||
event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_WRITE)
|
||||
#define EVENT_FD_NOT_READABLE(fde) \
|
||||
event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_READ)
|
||||
|
||||
#endif /* __EVENTS_H__ */
|
81
ctdb/lib/events/.svn/text-base/events_internal.h.svn-base
Normal file
81
ctdb/lib/events/.svn/text-base/events_internal.h.svn-base
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
generalised event loop handling
|
||||
|
||||
Internal structs
|
||||
|
||||
Copyright (C) Stefan Metzmacher 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
struct event_ops {
|
||||
/* conntext init */
|
||||
int (*context_init)(struct event_context *ev, void *private_data);
|
||||
|
||||
/* fd_event functions */
|
||||
struct fd_event *(*add_fd)(struct event_context *ev,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
int fd, uint16_t flags,
|
||||
event_fd_handler_t handler,
|
||||
void *private_data);
|
||||
uint16_t (*get_fd_flags)(struct fd_event *fde);
|
||||
void (*set_fd_flags)(struct fd_event *fde, uint16_t flags);
|
||||
|
||||
/* timed_event functions */
|
||||
struct timed_event *(*add_timed)(struct event_context *ev,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct timeval next_event,
|
||||
event_timed_handler_t handler,
|
||||
void *private_data);
|
||||
|
||||
/* loop functions */
|
||||
int (*loop_once)(struct event_context *ev);
|
||||
int (*loop_wait)(struct event_context *ev);
|
||||
};
|
||||
|
||||
struct fd_event {
|
||||
struct fd_event *prev, *next;
|
||||
struct event_context *event_ctx;
|
||||
int fd;
|
||||
uint16_t flags; /* see EVENT_FD_* flags */
|
||||
event_fd_handler_t handler;
|
||||
/* this is private for the specific handler */
|
||||
void *private_data;
|
||||
/* this is private for the events_ops implementation */
|
||||
uint16_t additional_flags;
|
||||
void *additional_data;
|
||||
};
|
||||
|
||||
struct timed_event {
|
||||
struct timed_event *prev, *next;
|
||||
struct event_context *event_ctx;
|
||||
struct timeval next_event;
|
||||
event_timed_handler_t handler;
|
||||
/* this is private for the specific handler */
|
||||
void *private_data;
|
||||
/* this is private for the events_ops implementation */
|
||||
void *additional_data;
|
||||
};
|
||||
|
||||
struct event_context {
|
||||
/* the specific events implementation */
|
||||
const struct event_ops *ops;
|
||||
/* this is private for the events_ops implementation */
|
||||
void *additional_data;
|
||||
};
|
||||
|
||||
const struct event_ops *event_standard_get_ops(void);
|
284
ctdb/lib/events/.svn/text-base/events_liboop.c.svn-base
Normal file
284
ctdb/lib/events/.svn/text-base/events_liboop.c.svn-base
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
main select loop and event handling
|
||||
wrapper for http://liboop.org/
|
||||
|
||||
Copyright (C) Stefan Metzmacher 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "lib/events/events_internal.h"
|
||||
|
||||
#include <oop.h>
|
||||
|
||||
/*
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
NOTE: this code compiles fine, but is completly *UNTESTED*
|
||||
and is only commited as example
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
*/
|
||||
|
||||
static int oop_event_context_destructor(struct event_context *ev)
|
||||
{
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
|
||||
oop_sys_delete(oop_sys);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
create a oop_event_context structure.
|
||||
*/
|
||||
static int oop_event_context_init(struct event_context *ev, void *private_data)
|
||||
{
|
||||
oop_source_sys *oop_sys = private_data;
|
||||
|
||||
if (!oop_sys) {
|
||||
oop_sys = oop_sys_new();
|
||||
if (!oop_sys) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
talloc_set_destructor(ev, oop_event_context_destructor);
|
||||
}
|
||||
|
||||
ev->additional_data = oop_sys;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *oop_event_fd_handler(oop_source *oop, int fd, oop_event oop_type, void *ptr)
|
||||
{
|
||||
struct fd_event *fde = ptr;
|
||||
|
||||
if (fd != fde->fd) return OOP_ERROR;
|
||||
|
||||
switch(oop_type) {
|
||||
case OOP_READ:
|
||||
fde->handler(fde->event_ctx, fde, EVENT_FD_READ, fde->private_data);
|
||||
return OOP_CONTINUE;
|
||||
case OOP_WRITE:
|
||||
fde->handler(fde->event_ctx, fde, EVENT_FD_WRITE, fde->private_data);
|
||||
return OOP_CONTINUE;
|
||||
case OOP_EXCEPTION:
|
||||
return OOP_ERROR;
|
||||
case OOP_NUM_EVENTS:
|
||||
return OOP_ERROR;
|
||||
}
|
||||
|
||||
return OOP_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
destroy an fd_event
|
||||
*/
|
||||
static int oop_event_fd_destructor(struct fd_event *fde)
|
||||
{
|
||||
struct event_context *ev = fde->event_ctx;
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
oop_source *oop = oop_sys_source(oop_sys);
|
||||
|
||||
if (fde->flags & EVENT_FD_READ)
|
||||
oop->cancel_fd(oop, fde->fd, OOP_READ);
|
||||
if (fde->flags & EVENT_FD_WRITE)
|
||||
oop->cancel_fd(oop, fde->fd, OOP_WRITE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
add a fd based event
|
||||
return NULL on failure (memory allocation error)
|
||||
*/
|
||||
static struct fd_event *oop_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
int fd, uint16_t flags,
|
||||
event_fd_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
struct fd_event *fde;
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
oop_source *oop = oop_sys_source(oop_sys);
|
||||
|
||||
fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
|
||||
if (!fde) return NULL;
|
||||
|
||||
fde->event_ctx = ev;
|
||||
fde->fd = fd;
|
||||
fde->flags = flags;
|
||||
fde->handler = handler;
|
||||
fde->private_data = private_data;
|
||||
fde->additional_flags = 0;
|
||||
fde->additional_data = NULL;
|
||||
|
||||
if (fde->flags & EVENT_FD_READ)
|
||||
oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde);
|
||||
if (fde->flags & EVENT_FD_WRITE)
|
||||
oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde);
|
||||
|
||||
talloc_set_destructor(fde, oop_event_fd_destructor);
|
||||
|
||||
return fde;
|
||||
}
|
||||
|
||||
/*
|
||||
return the fd event flags
|
||||
*/
|
||||
static uint16_t oop_event_get_fd_flags(struct fd_event *fde)
|
||||
{
|
||||
return fde->flags;
|
||||
}
|
||||
|
||||
/*
|
||||
set the fd event flags
|
||||
*/
|
||||
static void oop_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
|
||||
{
|
||||
oop_source_sys *oop_sys;
|
||||
oop_source *oop;
|
||||
|
||||
oop_sys = fde->event_ctx->additional_data;
|
||||
oop = oop_sys_source(oop_sys);
|
||||
|
||||
if ((fde->flags & EVENT_FD_READ)&&(!(flags & EVENT_FD_READ)))
|
||||
oop->cancel_fd(oop, fde->fd, OOP_READ);
|
||||
|
||||
if ((!(fde->flags & EVENT_FD_READ))&&(flags & EVENT_FD_READ))
|
||||
oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde);
|
||||
|
||||
if ((fde->flags & EVENT_FD_WRITE)&&(!(flags & EVENT_FD_WRITE)))
|
||||
oop->cancel_fd(oop, fde->fd, OOP_WRITE);
|
||||
|
||||
if ((!(fde->flags & EVENT_FD_WRITE))&&(flags & EVENT_FD_WRITE))
|
||||
oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde);
|
||||
|
||||
fde->flags = flags;
|
||||
}
|
||||
|
||||
static int oop_event_timed_destructor(struct timed_event *te);
|
||||
|
||||
static int oop_event_timed_deny_destructor(struct timed_event *te)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void *oop_event_timed_handler(oop_source *oop, struct timeval t, void *ptr)
|
||||
{
|
||||
struct timed_event *te = ptr;
|
||||
|
||||
/* deny the handler to free the event */
|
||||
talloc_set_destructor(te, oop_event_timed_deny_destructor);
|
||||
te->handler(te->event_ctx, te, t, te->private_data);
|
||||
|
||||
talloc_set_destructor(te, oop_event_timed_destructor);
|
||||
talloc_free(te);
|
||||
|
||||
return OOP_CONTINUE;
|
||||
}
|
||||
|
||||
/*
|
||||
destroy a timed event
|
||||
*/
|
||||
static int oop_event_timed_destructor(struct timed_event *te)
|
||||
{
|
||||
struct event_context *ev = te->event_ctx;
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
oop_source *oop = oop_sys_source(oop_sys);
|
||||
|
||||
oop->cancel_time(oop, te->next_event, oop_event_timed_handler, te);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
add a timed event
|
||||
return NULL on failure (memory allocation error)
|
||||
*/
|
||||
static struct timed_event *oop_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
struct timeval next_event,
|
||||
event_timed_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
oop_source *oop = oop_sys_source(oop_sys);
|
||||
struct timed_event *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;
|
||||
|
||||
oop->on_time(oop, te->next_event, oop_event_timed_handler, te);
|
||||
|
||||
talloc_set_destructor(te, oop_event_timed_destructor);
|
||||
|
||||
return te;
|
||||
}
|
||||
|
||||
/*
|
||||
do a single event loop using the events defined in ev
|
||||
*/
|
||||
static int oop_event_loop_once(struct event_context *ev)
|
||||
{
|
||||
void *oop_ret;
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
|
||||
oop_ret = oop_sys_run_once(oop_sys);
|
||||
if (oop_ret == OOP_CONTINUE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
return on failure or (with 0) if all fd events are removed
|
||||
*/
|
||||
static int oop_event_loop_wait(struct event_context *ev)
|
||||
{
|
||||
void *oop_ret;
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
|
||||
oop_ret = oop_sys_run(oop_sys);
|
||||
if (oop_ret == OOP_CONTINUE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const struct event_ops event_oop_ops = {
|
||||
.context_init = oop_event_context_init,
|
||||
.add_fd = oop_event_add_fd,
|
||||
.get_fd_flags = oop_event_get_fd_flags,
|
||||
.set_fd_flags = oop_event_set_fd_flags,
|
||||
.add_timed = oop_event_add_timed,
|
||||
.loop_once = oop_event_loop_once,
|
||||
.loop_wait = oop_event_loop_wait,
|
||||
};
|
||||
|
||||
const struct event_ops *event_liboop_get_ops(void)
|
||||
{
|
||||
return &event_oop_ops;
|
||||
}
|
633
ctdb/lib/events/.svn/text-base/events_standard.c.svn-base
Normal file
633
ctdb/lib/events/.svn/text-base/events_standard.c.svn-base
Normal file
@ -0,0 +1,633 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
main select loop and event handling
|
||||
Copyright (C) Andrew Tridgell 2003-2005
|
||||
Copyright (C) Stefan Metzmacher 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
This is SAMBA's default event loop code
|
||||
|
||||
- we try to use epoll if configure detected support for it
|
||||
otherwise we use select()
|
||||
- if epoll is broken on the system or the kernel doesn't support it
|
||||
at runtime we fallback to select()
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/filesys.h"
|
||||
#include "system/select.h" /* needed for WITH_EPOLL */
|
||||
#include "lib/util/dlinklist.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "lib/events/events_internal.h"
|
||||
|
||||
struct std_event_context {
|
||||
/* a pointer back to the generic event_context */
|
||||
struct event_context *ev;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* information for exiting from the event loop */
|
||||
int exit_code;
|
||||
|
||||
/* this is changed by the destructors for the fd event
|
||||
type. It is used to detect event destruction by event
|
||||
handlers, which means the code that is calling the event
|
||||
handler needs to assume that the linked list is no longer
|
||||
valid
|
||||
*/
|
||||
uint32_t destruction_count;
|
||||
|
||||
/* when using epoll this is the handle from epoll_create */
|
||||
int epoll_fd;
|
||||
};
|
||||
|
||||
static void std_event_loop_timer(struct std_event_context *std_ev);
|
||||
|
||||
/* use epoll if it is available */
|
||||
#if WITH_EPOLL
|
||||
/*
|
||||
called when a epoll call fails, and we should fallback
|
||||
to using select
|
||||
*/
|
||||
static void epoll_fallback_to_select(struct std_event_context *std_ev, const char *reason)
|
||||
{
|
||||
DEBUG(0,("%s (%s) - falling back to select()\n", reason, strerror(errno)));
|
||||
close(std_ev->epoll_fd);
|
||||
std_ev->epoll_fd = -1;
|
||||
talloc_set_destructor(std_ev, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
map from EVENT_FD_* to EPOLLIN/EPOLLOUT
|
||||
*/
|
||||
static uint32_t epoll_map_flags(uint16_t flags)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
if (flags & EVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
|
||||
if (flags & EVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
free the epoll fd
|
||||
*/
|
||||
static int epoll_ctx_destructor(struct std_event_context *std_ev)
|
||||
{
|
||||
close(std_ev->epoll_fd);
|
||||
std_ev->epoll_fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
init the epoll fd
|
||||
*/
|
||||
static void epoll_init_ctx(struct std_event_context *std_ev, BOOL try_epoll)
|
||||
{
|
||||
if (!try_epoll) return;
|
||||
std_ev->epoll_fd = epoll_create(64);
|
||||
talloc_set_destructor(std_ev, epoll_ctx_destructor);
|
||||
}
|
||||
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
|
||||
|
||||
/*
|
||||
add the epoll event to the given fd_event
|
||||
*/
|
||||
static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *fde)
|
||||
{
|
||||
struct epoll_event event;
|
||||
if (std_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
|
||||
/* if we don't want events yet, don't add an epoll_event */
|
||||
if (fde->flags == 0) return;
|
||||
|
||||
ZERO_STRUCT(event);
|
||||
event.events = epoll_map_flags(fde->flags);
|
||||
event.data.ptr = fde;
|
||||
if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) {
|
||||
epoll_fallback_to_select(std_ev, "EPOLL_CTL_ADD failed");
|
||||
}
|
||||
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
|
||||
|
||||
/* only if we want to read we want to tell the event handler about errors */
|
||||
if (fde->flags & EVENT_FD_READ) {
|
||||
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
delete the epoll event for given fd_event
|
||||
*/
|
||||
static void epoll_del_event(struct std_event_context *std_ev, struct fd_event *fde)
|
||||
{
|
||||
struct epoll_event event;
|
||||
if (std_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
|
||||
/* if there's no epoll_event, we don't need to delete it */
|
||||
if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return;
|
||||
|
||||
ZERO_STRUCT(event);
|
||||
event.events = epoll_map_flags(fde->flags);
|
||||
event.data.ptr = fde;
|
||||
epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event);
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
|
||||
}
|
||||
|
||||
/*
|
||||
change the epoll event to the given fd_event
|
||||
*/
|
||||
static void epoll_mod_event(struct std_event_context *std_ev, struct fd_event *fde)
|
||||
{
|
||||
struct epoll_event event;
|
||||
if (std_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
|
||||
ZERO_STRUCT(event);
|
||||
event.events = epoll_map_flags(fde->flags);
|
||||
event.data.ptr = fde;
|
||||
if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) {
|
||||
epoll_fallback_to_select(std_ev, "EPOLL_CTL_MOD failed");
|
||||
}
|
||||
|
||||
/* only if we want to read we want to tell the event handler about errors */
|
||||
if (fde->flags & EVENT_FD_READ) {
|
||||
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (std_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
|
||||
/* there's already an event */
|
||||
if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) {
|
||||
if (want_read || (want_write && !got_error)) {
|
||||
epoll_mod_event(std_ev, fde);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* if we want to match the select behavior, we need to remove the epoll_event
|
||||
* when the caller isn't interested in events.
|
||||
*
|
||||
* this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them
|
||||
*/
|
||||
epoll_del_event(std_ev, fde);
|
||||
return;
|
||||
}
|
||||
|
||||
/* there's no epoll_event attached to the fde */
|
||||
if (want_read || (want_write && !got_error)) {
|
||||
epoll_add_event(std_ev, fde);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
event loop handling using epoll
|
||||
*/
|
||||
static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tvalp)
|
||||
{
|
||||
int ret, i;
|
||||
#define MAXEVENTS 8
|
||||
struct epoll_event events[MAXEVENTS];
|
||||
uint32_t destruction_count = std_ev->destruction_count;
|
||||
int timeout = -1;
|
||||
|
||||
if (std_ev->epoll_fd == -1) return -1;
|
||||
|
||||
if (tvalp) {
|
||||
/* it's better to trigger timed events a bit later than to early */
|
||||
timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000);
|
||||
}
|
||||
|
||||
ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=0;i<ret;i++) {
|
||||
struct fd_event *fde = talloc_get_type(events[i].data.ptr,
|
||||
struct fd_event);
|
||||
uint16_t flags = 0;
|
||||
|
||||
if (fde == NULL) {
|
||||
epoll_fallback_to_select(std_ev, "epoll_wait() gave bad data");
|
||||
return -1;
|
||||
}
|
||||
if (events[i].events & (EPOLLHUP|EPOLLERR)) {
|
||||
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR;
|
||||
/*
|
||||
* if we only wait for EVENT_FD_WRITE, we should not tell the
|
||||
* event handler about it, and remove the epoll_event,
|
||||
* as we only report errors when waiting for read events,
|
||||
* to match the select() behavior
|
||||
*/
|
||||
if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) {
|
||||
epoll_del_event(std_ev, fde);
|
||||
continue;
|
||||
}
|
||||
flags |= EVENT_FD_READ;
|
||||
}
|
||||
if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ;
|
||||
if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
|
||||
if (flags) {
|
||||
fde->handler(std_ev->ev, fde, flags, fde->private_data);
|
||||
if (destruction_count != std_ev->destruction_count) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define epoll_init_ctx(std_ev,try_epoll) if (try_epoll) {/* fix unused variable warning*/}
|
||||
#define epoll_add_event(std_ev,fde)
|
||||
#define epoll_del_event(std_ev,fde)
|
||||
#define epoll_change_event(std_ev,fde)
|
||||
#define epoll_event_loop(std_ev,tvalp) (-1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
create a std_event_context structure.
|
||||
*/
|
||||
static int std_event_context_init(struct event_context *ev, void *private_data)
|
||||
{
|
||||
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);
|
||||
|
||||
ev->additional_data = std_ev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
recalculate the maxfd
|
||||
*/
|
||||
static void calc_maxfd(struct std_event_context *std_ev)
|
||||
{
|
||||
struct fd_event *fde;
|
||||
|
||||
std_ev->maxfd = 0;
|
||||
for (fde = std_ev->fd_events; fde; fde = fde->next) {
|
||||
if (fde->fd > std_ev->maxfd) {
|
||||
std_ev->maxfd = fde->fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* to mark the ev->maxfd invalid
|
||||
* this means we need to recalculate it
|
||||
*/
|
||||
#define EVENT_INVALID_MAXFD (-1)
|
||||
|
||||
/*
|
||||
destroy an fd_event
|
||||
*/
|
||||
static int std_event_fd_destructor(struct fd_event *fde)
|
||||
{
|
||||
struct event_context *ev = fde->event_ctx;
|
||||
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
|
||||
struct std_event_context);
|
||||
|
||||
if (std_ev->maxfd == fde->fd) {
|
||||
std_ev->maxfd = EVENT_INVALID_MAXFD;
|
||||
}
|
||||
|
||||
DLIST_REMOVE(std_ev->fd_events, fde);
|
||||
std_ev->destruction_count++;
|
||||
|
||||
epoll_del_event(std_ev, fde);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
add a fd based event
|
||||
return NULL on failure (memory allocation error)
|
||||
*/
|
||||
static struct fd_event *std_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
int fd, uint16_t flags,
|
||||
event_fd_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
|
||||
struct std_event_context);
|
||||
struct fd_event *fde;
|
||||
|
||||
fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
|
||||
if (!fde) return NULL;
|
||||
|
||||
fde->event_ctx = ev;
|
||||
fde->fd = fd;
|
||||
fde->flags = flags;
|
||||
fde->handler = handler;
|
||||
fde->private_data = private_data;
|
||||
fde->additional_flags = 0;
|
||||
fde->additional_data = NULL;
|
||||
|
||||
DLIST_ADD(std_ev->fd_events, fde);
|
||||
if (fde->fd > std_ev->maxfd) {
|
||||
std_ev->maxfd = fde->fd;
|
||||
}
|
||||
talloc_set_destructor(fde, std_event_fd_destructor);
|
||||
|
||||
epoll_add_event(std_ev, fde);
|
||||
|
||||
return fde;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
return the fd event flags
|
||||
*/
|
||||
static uint16_t std_event_get_fd_flags(struct fd_event *fde)
|
||||
{
|
||||
return fde->flags;
|
||||
}
|
||||
|
||||
/*
|
||||
set the fd event flags
|
||||
*/
|
||||
static void std_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
|
||||
{
|
||||
struct event_context *ev;
|
||||
struct std_event_context *std_ev;
|
||||
|
||||
if (fde->flags == flags) return;
|
||||
|
||||
ev = fde->event_ctx;
|
||||
std_ev = talloc_get_type(ev->additional_data, struct std_event_context);
|
||||
|
||||
fde->flags = 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()
|
||||
*/
|
||||
static int std_event_loop_select(struct std_event_context *std_ev, struct timeval *tvalp)
|
||||
{
|
||||
fd_set r_fds, w_fds;
|
||||
struct fd_event *fde;
|
||||
int selrtn;
|
||||
uint32_t destruction_count = std_ev->destruction_count;
|
||||
|
||||
/* we maybe need to recalculate the maxfd */
|
||||
if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
|
||||
calc_maxfd(std_ev);
|
||||
}
|
||||
|
||||
FD_ZERO(&r_fds);
|
||||
FD_ZERO(&w_fds);
|
||||
|
||||
/* setup any fd events */
|
||||
for (fde = std_ev->fd_events; fde; fde = fde->next) {
|
||||
if (fde->flags & EVENT_FD_READ) {
|
||||
FD_SET(fde->fd, &r_fds);
|
||||
}
|
||||
if (fde->flags & EVENT_FD_WRITE) {
|
||||
FD_SET(fde->fd, &w_fds);
|
||||
}
|
||||
}
|
||||
|
||||
selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
|
||||
|
||||
if (selrtn == -1 && errno == EBADF) {
|
||||
/* the socket is dead! this should never
|
||||
happen as the socket should have first been
|
||||
made readable and that should have removed
|
||||
the event, so this must be a bug. This is a
|
||||
fatal error. */
|
||||
DEBUG(0,("ERROR: EBADF on std_event_loop_once\n"));
|
||||
std_ev->exit_code = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (selrtn == 0 && tvalp) {
|
||||
std_event_loop_timer(std_ev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (selrtn > 0) {
|
||||
/* at least one file descriptor is ready - check
|
||||
which ones and call the handler, being careful to allow
|
||||
the handler to remove itself when called */
|
||||
for (fde = std_ev->fd_events; fde; fde = fde->next) {
|
||||
uint16_t flags = 0;
|
||||
|
||||
if (FD_ISSET(fde->fd, &r_fds)) flags |= EVENT_FD_READ;
|
||||
if (FD_ISSET(fde->fd, &w_fds)) flags |= EVENT_FD_WRITE;
|
||||
if (flags) {
|
||||
fde->handler(std_ev->ev, fde, flags, fde->private_data);
|
||||
if (destruction_count != std_ev->destruction_count) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
do a single event loop using the events defined in ev
|
||||
*/
|
||||
static int std_event_loop_once(struct event_context *ev)
|
||||
{
|
||||
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
|
||||
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);
|
||||
}
|
||||
|
||||
if (epoll_event_loop(std_ev, &tval) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return std_event_loop_select(std_ev, &tval);
|
||||
}
|
||||
|
||||
/*
|
||||
return on failure or (with 0) if all fd events are removed
|
||||
*/
|
||||
static int std_event_loop_wait(struct event_context *ev)
|
||||
{
|
||||
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
|
||||
struct std_event_context);
|
||||
std_ev->exit_code = 0;
|
||||
|
||||
while (std_ev->fd_events && std_ev->exit_code == 0) {
|
||||
if (std_event_loop_once(ev) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return std_ev->exit_code;
|
||||
}
|
||||
|
||||
static const struct event_ops std_event_ops = {
|
||||
.context_init = std_event_context_init,
|
||||
.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,
|
||||
.loop_once = std_event_loop_once,
|
||||
.loop_wait = std_event_loop_wait,
|
||||
};
|
||||
|
||||
const struct event_ops *event_standard_get_ops(void)
|
||||
{
|
||||
return &std_event_ops;
|
||||
}
|
2
ctdb/lib/events/config.m4
Normal file
2
ctdb/lib/events/config.m4
Normal file
@ -0,0 +1,2 @@
|
||||
AC_CHECK_HEADERS(sys/epoll.h)
|
||||
AC_CHECK_FUNCS(epoll_create)
|
7
ctdb/lib/events/config.mk
Normal file
7
ctdb/lib/events/config.mk
Normal file
@ -0,0 +1,7 @@
|
||||
##############################
|
||||
# Start SUBSYSTEM LIBEVENTS
|
||||
[SUBSYSTEM::LIBEVENTS]
|
||||
OBJ_FILES = events.o events_standard.o
|
||||
PUBLIC_DEPENDENCIES = LIBTALLOC
|
||||
# End SUBSYSTEM LIBEVENTS
|
||||
##############################
|
175
ctdb/lib/events/events.c
Normal file
175
ctdb/lib/events/events.c
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
main select loop and event handling
|
||||
Copyright (C) Andrew Tridgell 2003
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
PLEASE READ THIS BEFORE MODIFYING!
|
||||
|
||||
This module is a general abstraction for the main select loop and
|
||||
event handling. Do not ever put any localised hacks in here, instead
|
||||
register one of the possible event types and implement that event
|
||||
somewhere else.
|
||||
|
||||
There are 2 types of event handling that are handled in this module:
|
||||
|
||||
1) a file descriptor becoming readable or writeable. This is mostly
|
||||
used for network sockets, but can be used for any type of file
|
||||
descriptor. You may only register one handler for each file
|
||||
descriptor/io combination or you will get unpredictable results
|
||||
(this means that you can have a handler for read events, and a
|
||||
separate handler for write events, but not two handlers that are
|
||||
both handling read events)
|
||||
|
||||
2) a timed event. You can register an event that happens at a
|
||||
specific time. You can register as many of these as you
|
||||
like. They are single shot - add a new timed event in the event
|
||||
handler to get another event.
|
||||
|
||||
To setup a set of events you first need to create a event_context
|
||||
structure using the function event_context_init(); This returns a
|
||||
'struct event_context' that you use in all subsequent calls.
|
||||
|
||||
After that you can add/remove events that you are interested in
|
||||
using event_add_*() and talloc_free()
|
||||
|
||||
Finally, you call event_loop_wait_once() to block waiting for one of the
|
||||
events to occor or event_loop_wait() which will loop
|
||||
forever.
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "lib/events/events_internal.h"
|
||||
|
||||
/*
|
||||
create a event_context structure for a specific implemementation.
|
||||
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.
|
||||
|
||||
This function is for allowing third-party-applications to hook in gluecode
|
||||
to their own event loop code, so that they can make async usage of our client libs
|
||||
|
||||
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)
|
||||
{
|
||||
struct event_context *ev;
|
||||
int ret;
|
||||
|
||||
ev = talloc_zero(mem_ctx, struct event_context);
|
||||
if (!ev) return NULL;
|
||||
|
||||
ev->ops = ops;
|
||||
|
||||
ret = ev->ops->context_init(ev, private_data);
|
||||
if (ret != 0) {
|
||||
talloc_free(ev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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(TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
const struct event_ops *ops = event_standard_get_ops();
|
||||
return event_context_init_ops(mem_ctx, ops, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
add a fd based event
|
||||
return NULL on failure (memory allocation error)
|
||||
*/
|
||||
struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
int fd, uint16_t flags, event_fd_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data);
|
||||
}
|
||||
|
||||
/*
|
||||
return the fd event flags
|
||||
*/
|
||||
uint16_t event_get_fd_flags(struct fd_event *fde)
|
||||
{
|
||||
if (!fde) return 0;
|
||||
return fde->event_ctx->ops->get_fd_flags(fde);
|
||||
}
|
||||
|
||||
/*
|
||||
set the fd event flags
|
||||
*/
|
||||
void event_set_fd_flags(struct fd_event *fde, uint16_t flags)
|
||||
{
|
||||
if (!fde) return;
|
||||
fde->event_ctx->ops->set_fd_flags(fde, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
add a timed event
|
||||
return NULL on failure
|
||||
*/
|
||||
struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
struct timeval next_event,
|
||||
event_timed_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
return ev->ops->add_timed(ev, mem_ctx, next_event, handler, private_data);
|
||||
}
|
||||
|
||||
/*
|
||||
do a single event loop using the events defined in ev
|
||||
*/
|
||||
_PUBLIC_ int event_loop_once(struct event_context *ev)
|
||||
{
|
||||
return ev->ops->loop_once(ev);
|
||||
}
|
||||
|
||||
/*
|
||||
return on failure or (with 0) if all fd events are removed
|
||||
*/
|
||||
int event_loop_wait(struct event_context *ev)
|
||||
{
|
||||
return ev->ops->loop_wait(ev);
|
||||
}
|
||||
|
||||
/*
|
||||
find an event context that is a parent of the given memory context,
|
||||
or create a new event context as a child of the given context if
|
||||
none is found
|
||||
|
||||
This should be used in preference to event_context_init() in places
|
||||
where you would prefer to use the existing event context if possible
|
||||
(which is most situations)
|
||||
*/
|
||||
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) {
|
||||
ev = event_context_init(mem_ctx);
|
||||
}
|
||||
return ev;
|
||||
}
|
71
ctdb/lib/events/events.h
Normal file
71
ctdb/lib/events/events.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
generalised event loop handling
|
||||
|
||||
Copyright (C) Andrew Tridgell 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __EVENTS_H__
|
||||
#define __EVENTS_H__
|
||||
|
||||
struct event_context;
|
||||
struct event_ops;
|
||||
struct fd_event;
|
||||
struct timed_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 *);
|
||||
|
||||
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 fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
int fd, uint16_t flags, event_fd_handler_t handler,
|
||||
void *private);
|
||||
|
||||
struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
struct timeval next_event,
|
||||
event_timed_handler_t handler,
|
||||
void *private);
|
||||
|
||||
int event_loop_once(struct event_context *ev);
|
||||
int event_loop_wait(struct event_context *ev);
|
||||
|
||||
uint16_t event_get_fd_flags(struct fd_event *fde);
|
||||
void event_set_fd_flags(struct fd_event *fde, uint16_t flags);
|
||||
|
||||
struct event_context *event_context_find(TALLOC_CTX *mem_ctx);
|
||||
|
||||
/* bits for file descriptor event flags */
|
||||
#define EVENT_FD_READ 1
|
||||
#define EVENT_FD_WRITE 2
|
||||
|
||||
#define EVENT_FD_WRITEABLE(fde) \
|
||||
event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_WRITE)
|
||||
#define EVENT_FD_READABLE(fde) \
|
||||
event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_READ)
|
||||
|
||||
#define EVENT_FD_NOT_WRITEABLE(fde) \
|
||||
event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_WRITE)
|
||||
#define EVENT_FD_NOT_READABLE(fde) \
|
||||
event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_READ)
|
||||
|
||||
#endif /* __EVENTS_H__ */
|
81
ctdb/lib/events/events_internal.h
Normal file
81
ctdb/lib/events/events_internal.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
generalised event loop handling
|
||||
|
||||
Internal structs
|
||||
|
||||
Copyright (C) Stefan Metzmacher 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
struct event_ops {
|
||||
/* conntext init */
|
||||
int (*context_init)(struct event_context *ev, void *private_data);
|
||||
|
||||
/* fd_event functions */
|
||||
struct fd_event *(*add_fd)(struct event_context *ev,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
int fd, uint16_t flags,
|
||||
event_fd_handler_t handler,
|
||||
void *private_data);
|
||||
uint16_t (*get_fd_flags)(struct fd_event *fde);
|
||||
void (*set_fd_flags)(struct fd_event *fde, uint16_t flags);
|
||||
|
||||
/* timed_event functions */
|
||||
struct timed_event *(*add_timed)(struct event_context *ev,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct timeval next_event,
|
||||
event_timed_handler_t handler,
|
||||
void *private_data);
|
||||
|
||||
/* loop functions */
|
||||
int (*loop_once)(struct event_context *ev);
|
||||
int (*loop_wait)(struct event_context *ev);
|
||||
};
|
||||
|
||||
struct fd_event {
|
||||
struct fd_event *prev, *next;
|
||||
struct event_context *event_ctx;
|
||||
int fd;
|
||||
uint16_t flags; /* see EVENT_FD_* flags */
|
||||
event_fd_handler_t handler;
|
||||
/* this is private for the specific handler */
|
||||
void *private_data;
|
||||
/* this is private for the events_ops implementation */
|
||||
uint16_t additional_flags;
|
||||
void *additional_data;
|
||||
};
|
||||
|
||||
struct timed_event {
|
||||
struct timed_event *prev, *next;
|
||||
struct event_context *event_ctx;
|
||||
struct timeval next_event;
|
||||
event_timed_handler_t handler;
|
||||
/* this is private for the specific handler */
|
||||
void *private_data;
|
||||
/* this is private for the events_ops implementation */
|
||||
void *additional_data;
|
||||
};
|
||||
|
||||
struct event_context {
|
||||
/* the specific events implementation */
|
||||
const struct event_ops *ops;
|
||||
/* this is private for the events_ops implementation */
|
||||
void *additional_data;
|
||||
};
|
||||
|
||||
const struct event_ops *event_standard_get_ops(void);
|
284
ctdb/lib/events/events_liboop.c
Normal file
284
ctdb/lib/events/events_liboop.c
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
main select loop and event handling
|
||||
wrapper for http://liboop.org/
|
||||
|
||||
Copyright (C) Stefan Metzmacher 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "lib/events/events_internal.h"
|
||||
|
||||
#include <oop.h>
|
||||
|
||||
/*
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
NOTE: this code compiles fine, but is completly *UNTESTED*
|
||||
and is only commited as example
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
*/
|
||||
|
||||
static int oop_event_context_destructor(struct event_context *ev)
|
||||
{
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
|
||||
oop_sys_delete(oop_sys);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
create a oop_event_context structure.
|
||||
*/
|
||||
static int oop_event_context_init(struct event_context *ev, void *private_data)
|
||||
{
|
||||
oop_source_sys *oop_sys = private_data;
|
||||
|
||||
if (!oop_sys) {
|
||||
oop_sys = oop_sys_new();
|
||||
if (!oop_sys) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
talloc_set_destructor(ev, oop_event_context_destructor);
|
||||
}
|
||||
|
||||
ev->additional_data = oop_sys;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *oop_event_fd_handler(oop_source *oop, int fd, oop_event oop_type, void *ptr)
|
||||
{
|
||||
struct fd_event *fde = ptr;
|
||||
|
||||
if (fd != fde->fd) return OOP_ERROR;
|
||||
|
||||
switch(oop_type) {
|
||||
case OOP_READ:
|
||||
fde->handler(fde->event_ctx, fde, EVENT_FD_READ, fde->private_data);
|
||||
return OOP_CONTINUE;
|
||||
case OOP_WRITE:
|
||||
fde->handler(fde->event_ctx, fde, EVENT_FD_WRITE, fde->private_data);
|
||||
return OOP_CONTINUE;
|
||||
case OOP_EXCEPTION:
|
||||
return OOP_ERROR;
|
||||
case OOP_NUM_EVENTS:
|
||||
return OOP_ERROR;
|
||||
}
|
||||
|
||||
return OOP_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
destroy an fd_event
|
||||
*/
|
||||
static int oop_event_fd_destructor(struct fd_event *fde)
|
||||
{
|
||||
struct event_context *ev = fde->event_ctx;
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
oop_source *oop = oop_sys_source(oop_sys);
|
||||
|
||||
if (fde->flags & EVENT_FD_READ)
|
||||
oop->cancel_fd(oop, fde->fd, OOP_READ);
|
||||
if (fde->flags & EVENT_FD_WRITE)
|
||||
oop->cancel_fd(oop, fde->fd, OOP_WRITE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
add a fd based event
|
||||
return NULL on failure (memory allocation error)
|
||||
*/
|
||||
static struct fd_event *oop_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
int fd, uint16_t flags,
|
||||
event_fd_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
struct fd_event *fde;
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
oop_source *oop = oop_sys_source(oop_sys);
|
||||
|
||||
fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
|
||||
if (!fde) return NULL;
|
||||
|
||||
fde->event_ctx = ev;
|
||||
fde->fd = fd;
|
||||
fde->flags = flags;
|
||||
fde->handler = handler;
|
||||
fde->private_data = private_data;
|
||||
fde->additional_flags = 0;
|
||||
fde->additional_data = NULL;
|
||||
|
||||
if (fde->flags & EVENT_FD_READ)
|
||||
oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde);
|
||||
if (fde->flags & EVENT_FD_WRITE)
|
||||
oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde);
|
||||
|
||||
talloc_set_destructor(fde, oop_event_fd_destructor);
|
||||
|
||||
return fde;
|
||||
}
|
||||
|
||||
/*
|
||||
return the fd event flags
|
||||
*/
|
||||
static uint16_t oop_event_get_fd_flags(struct fd_event *fde)
|
||||
{
|
||||
return fde->flags;
|
||||
}
|
||||
|
||||
/*
|
||||
set the fd event flags
|
||||
*/
|
||||
static void oop_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
|
||||
{
|
||||
oop_source_sys *oop_sys;
|
||||
oop_source *oop;
|
||||
|
||||
oop_sys = fde->event_ctx->additional_data;
|
||||
oop = oop_sys_source(oop_sys);
|
||||
|
||||
if ((fde->flags & EVENT_FD_READ)&&(!(flags & EVENT_FD_READ)))
|
||||
oop->cancel_fd(oop, fde->fd, OOP_READ);
|
||||
|
||||
if ((!(fde->flags & EVENT_FD_READ))&&(flags & EVENT_FD_READ))
|
||||
oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde);
|
||||
|
||||
if ((fde->flags & EVENT_FD_WRITE)&&(!(flags & EVENT_FD_WRITE)))
|
||||
oop->cancel_fd(oop, fde->fd, OOP_WRITE);
|
||||
|
||||
if ((!(fde->flags & EVENT_FD_WRITE))&&(flags & EVENT_FD_WRITE))
|
||||
oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde);
|
||||
|
||||
fde->flags = flags;
|
||||
}
|
||||
|
||||
static int oop_event_timed_destructor(struct timed_event *te);
|
||||
|
||||
static int oop_event_timed_deny_destructor(struct timed_event *te)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void *oop_event_timed_handler(oop_source *oop, struct timeval t, void *ptr)
|
||||
{
|
||||
struct timed_event *te = ptr;
|
||||
|
||||
/* deny the handler to free the event */
|
||||
talloc_set_destructor(te, oop_event_timed_deny_destructor);
|
||||
te->handler(te->event_ctx, te, t, te->private_data);
|
||||
|
||||
talloc_set_destructor(te, oop_event_timed_destructor);
|
||||
talloc_free(te);
|
||||
|
||||
return OOP_CONTINUE;
|
||||
}
|
||||
|
||||
/*
|
||||
destroy a timed event
|
||||
*/
|
||||
static int oop_event_timed_destructor(struct timed_event *te)
|
||||
{
|
||||
struct event_context *ev = te->event_ctx;
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
oop_source *oop = oop_sys_source(oop_sys);
|
||||
|
||||
oop->cancel_time(oop, te->next_event, oop_event_timed_handler, te);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
add a timed event
|
||||
return NULL on failure (memory allocation error)
|
||||
*/
|
||||
static struct timed_event *oop_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
struct timeval next_event,
|
||||
event_timed_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
oop_source *oop = oop_sys_source(oop_sys);
|
||||
struct timed_event *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;
|
||||
|
||||
oop->on_time(oop, te->next_event, oop_event_timed_handler, te);
|
||||
|
||||
talloc_set_destructor(te, oop_event_timed_destructor);
|
||||
|
||||
return te;
|
||||
}
|
||||
|
||||
/*
|
||||
do a single event loop using the events defined in ev
|
||||
*/
|
||||
static int oop_event_loop_once(struct event_context *ev)
|
||||
{
|
||||
void *oop_ret;
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
|
||||
oop_ret = oop_sys_run_once(oop_sys);
|
||||
if (oop_ret == OOP_CONTINUE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
return on failure or (with 0) if all fd events are removed
|
||||
*/
|
||||
static int oop_event_loop_wait(struct event_context *ev)
|
||||
{
|
||||
void *oop_ret;
|
||||
oop_source_sys *oop_sys = ev->additional_data;
|
||||
|
||||
oop_ret = oop_sys_run(oop_sys);
|
||||
if (oop_ret == OOP_CONTINUE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const struct event_ops event_oop_ops = {
|
||||
.context_init = oop_event_context_init,
|
||||
.add_fd = oop_event_add_fd,
|
||||
.get_fd_flags = oop_event_get_fd_flags,
|
||||
.set_fd_flags = oop_event_set_fd_flags,
|
||||
.add_timed = oop_event_add_timed,
|
||||
.loop_once = oop_event_loop_once,
|
||||
.loop_wait = oop_event_loop_wait,
|
||||
};
|
||||
|
||||
const struct event_ops *event_liboop_get_ops(void)
|
||||
{
|
||||
return &event_oop_ops;
|
||||
}
|
633
ctdb/lib/events/events_standard.c
Normal file
633
ctdb/lib/events/events_standard.c
Normal file
@ -0,0 +1,633 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
main select loop and event handling
|
||||
Copyright (C) Andrew Tridgell 2003-2005
|
||||
Copyright (C) Stefan Metzmacher 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
This is SAMBA's default event loop code
|
||||
|
||||
- we try to use epoll if configure detected support for it
|
||||
otherwise we use select()
|
||||
- if epoll is broken on the system or the kernel doesn't support it
|
||||
at runtime we fallback to select()
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/filesys.h"
|
||||
#include "system/select.h" /* needed for WITH_EPOLL */
|
||||
#include "lib/util/dlinklist.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "lib/events/events_internal.h"
|
||||
|
||||
struct std_event_context {
|
||||
/* a pointer back to the generic event_context */
|
||||
struct event_context *ev;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* information for exiting from the event loop */
|
||||
int exit_code;
|
||||
|
||||
/* this is changed by the destructors for the fd event
|
||||
type. It is used to detect event destruction by event
|
||||
handlers, which means the code that is calling the event
|
||||
handler needs to assume that the linked list is no longer
|
||||
valid
|
||||
*/
|
||||
uint32_t destruction_count;
|
||||
|
||||
/* when using epoll this is the handle from epoll_create */
|
||||
int epoll_fd;
|
||||
};
|
||||
|
||||
static void std_event_loop_timer(struct std_event_context *std_ev);
|
||||
|
||||
/* use epoll if it is available */
|
||||
#if WITH_EPOLL
|
||||
/*
|
||||
called when a epoll call fails, and we should fallback
|
||||
to using select
|
||||
*/
|
||||
static void epoll_fallback_to_select(struct std_event_context *std_ev, const char *reason)
|
||||
{
|
||||
DEBUG(0,("%s (%s) - falling back to select()\n", reason, strerror(errno)));
|
||||
close(std_ev->epoll_fd);
|
||||
std_ev->epoll_fd = -1;
|
||||
talloc_set_destructor(std_ev, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
map from EVENT_FD_* to EPOLLIN/EPOLLOUT
|
||||
*/
|
||||
static uint32_t epoll_map_flags(uint16_t flags)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
if (flags & EVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
|
||||
if (flags & EVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
free the epoll fd
|
||||
*/
|
||||
static int epoll_ctx_destructor(struct std_event_context *std_ev)
|
||||
{
|
||||
close(std_ev->epoll_fd);
|
||||
std_ev->epoll_fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
init the epoll fd
|
||||
*/
|
||||
static void epoll_init_ctx(struct std_event_context *std_ev, BOOL try_epoll)
|
||||
{
|
||||
if (!try_epoll) return;
|
||||
std_ev->epoll_fd = epoll_create(64);
|
||||
talloc_set_destructor(std_ev, epoll_ctx_destructor);
|
||||
}
|
||||
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
|
||||
|
||||
/*
|
||||
add the epoll event to the given fd_event
|
||||
*/
|
||||
static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *fde)
|
||||
{
|
||||
struct epoll_event event;
|
||||
if (std_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
|
||||
/* if we don't want events yet, don't add an epoll_event */
|
||||
if (fde->flags == 0) return;
|
||||
|
||||
ZERO_STRUCT(event);
|
||||
event.events = epoll_map_flags(fde->flags);
|
||||
event.data.ptr = fde;
|
||||
if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) {
|
||||
epoll_fallback_to_select(std_ev, "EPOLL_CTL_ADD failed");
|
||||
}
|
||||
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
|
||||
|
||||
/* only if we want to read we want to tell the event handler about errors */
|
||||
if (fde->flags & EVENT_FD_READ) {
|
||||
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
delete the epoll event for given fd_event
|
||||
*/
|
||||
static void epoll_del_event(struct std_event_context *std_ev, struct fd_event *fde)
|
||||
{
|
||||
struct epoll_event event;
|
||||
if (std_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
|
||||
/* if there's no epoll_event, we don't need to delete it */
|
||||
if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return;
|
||||
|
||||
ZERO_STRUCT(event);
|
||||
event.events = epoll_map_flags(fde->flags);
|
||||
event.data.ptr = fde;
|
||||
epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event);
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
|
||||
}
|
||||
|
||||
/*
|
||||
change the epoll event to the given fd_event
|
||||
*/
|
||||
static void epoll_mod_event(struct std_event_context *std_ev, struct fd_event *fde)
|
||||
{
|
||||
struct epoll_event event;
|
||||
if (std_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
|
||||
ZERO_STRUCT(event);
|
||||
event.events = epoll_map_flags(fde->flags);
|
||||
event.data.ptr = fde;
|
||||
if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) {
|
||||
epoll_fallback_to_select(std_ev, "EPOLL_CTL_MOD failed");
|
||||
}
|
||||
|
||||
/* only if we want to read we want to tell the event handler about errors */
|
||||
if (fde->flags & EVENT_FD_READ) {
|
||||
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (std_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
|
||||
/* there's already an event */
|
||||
if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) {
|
||||
if (want_read || (want_write && !got_error)) {
|
||||
epoll_mod_event(std_ev, fde);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* if we want to match the select behavior, we need to remove the epoll_event
|
||||
* when the caller isn't interested in events.
|
||||
*
|
||||
* this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them
|
||||
*/
|
||||
epoll_del_event(std_ev, fde);
|
||||
return;
|
||||
}
|
||||
|
||||
/* there's no epoll_event attached to the fde */
|
||||
if (want_read || (want_write && !got_error)) {
|
||||
epoll_add_event(std_ev, fde);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
event loop handling using epoll
|
||||
*/
|
||||
static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tvalp)
|
||||
{
|
||||
int ret, i;
|
||||
#define MAXEVENTS 8
|
||||
struct epoll_event events[MAXEVENTS];
|
||||
uint32_t destruction_count = std_ev->destruction_count;
|
||||
int timeout = -1;
|
||||
|
||||
if (std_ev->epoll_fd == -1) return -1;
|
||||
|
||||
if (tvalp) {
|
||||
/* it's better to trigger timed events a bit later than to early */
|
||||
timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000);
|
||||
}
|
||||
|
||||
ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=0;i<ret;i++) {
|
||||
struct fd_event *fde = talloc_get_type(events[i].data.ptr,
|
||||
struct fd_event);
|
||||
uint16_t flags = 0;
|
||||
|
||||
if (fde == NULL) {
|
||||
epoll_fallback_to_select(std_ev, "epoll_wait() gave bad data");
|
||||
return -1;
|
||||
}
|
||||
if (events[i].events & (EPOLLHUP|EPOLLERR)) {
|
||||
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR;
|
||||
/*
|
||||
* if we only wait for EVENT_FD_WRITE, we should not tell the
|
||||
* event handler about it, and remove the epoll_event,
|
||||
* as we only report errors when waiting for read events,
|
||||
* to match the select() behavior
|
||||
*/
|
||||
if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) {
|
||||
epoll_del_event(std_ev, fde);
|
||||
continue;
|
||||
}
|
||||
flags |= EVENT_FD_READ;
|
||||
}
|
||||
if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ;
|
||||
if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
|
||||
if (flags) {
|
||||
fde->handler(std_ev->ev, fde, flags, fde->private_data);
|
||||
if (destruction_count != std_ev->destruction_count) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define epoll_init_ctx(std_ev,try_epoll) if (try_epoll) {/* fix unused variable warning*/}
|
||||
#define epoll_add_event(std_ev,fde)
|
||||
#define epoll_del_event(std_ev,fde)
|
||||
#define epoll_change_event(std_ev,fde)
|
||||
#define epoll_event_loop(std_ev,tvalp) (-1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
create a std_event_context structure.
|
||||
*/
|
||||
static int std_event_context_init(struct event_context *ev, void *private_data)
|
||||
{
|
||||
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);
|
||||
|
||||
ev->additional_data = std_ev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
recalculate the maxfd
|
||||
*/
|
||||
static void calc_maxfd(struct std_event_context *std_ev)
|
||||
{
|
||||
struct fd_event *fde;
|
||||
|
||||
std_ev->maxfd = 0;
|
||||
for (fde = std_ev->fd_events; fde; fde = fde->next) {
|
||||
if (fde->fd > std_ev->maxfd) {
|
||||
std_ev->maxfd = fde->fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* to mark the ev->maxfd invalid
|
||||
* this means we need to recalculate it
|
||||
*/
|
||||
#define EVENT_INVALID_MAXFD (-1)
|
||||
|
||||
/*
|
||||
destroy an fd_event
|
||||
*/
|
||||
static int std_event_fd_destructor(struct fd_event *fde)
|
||||
{
|
||||
struct event_context *ev = fde->event_ctx;
|
||||
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
|
||||
struct std_event_context);
|
||||
|
||||
if (std_ev->maxfd == fde->fd) {
|
||||
std_ev->maxfd = EVENT_INVALID_MAXFD;
|
||||
}
|
||||
|
||||
DLIST_REMOVE(std_ev->fd_events, fde);
|
||||
std_ev->destruction_count++;
|
||||
|
||||
epoll_del_event(std_ev, fde);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
add a fd based event
|
||||
return NULL on failure (memory allocation error)
|
||||
*/
|
||||
static struct fd_event *std_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
|
||||
int fd, uint16_t flags,
|
||||
event_fd_handler_t handler,
|
||||
void *private_data)
|
||||
{
|
||||
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
|
||||
struct std_event_context);
|
||||
struct fd_event *fde;
|
||||
|
||||
fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
|
||||
if (!fde) return NULL;
|
||||
|
||||
fde->event_ctx = ev;
|
||||
fde->fd = fd;
|
||||
fde->flags = flags;
|
||||
fde->handler = handler;
|
||||
fde->private_data = private_data;
|
||||
fde->additional_flags = 0;
|
||||
fde->additional_data = NULL;
|
||||
|
||||
DLIST_ADD(std_ev->fd_events, fde);
|
||||
if (fde->fd > std_ev->maxfd) {
|
||||
std_ev->maxfd = fde->fd;
|
||||
}
|
||||
talloc_set_destructor(fde, std_event_fd_destructor);
|
||||
|
||||
epoll_add_event(std_ev, fde);
|
||||
|
||||
return fde;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
return the fd event flags
|
||||
*/
|
||||
static uint16_t std_event_get_fd_flags(struct fd_event *fde)
|
||||
{
|
||||
return fde->flags;
|
||||
}
|
||||
|
||||
/*
|
||||
set the fd event flags
|
||||
*/
|
||||
static void std_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
|
||||
{
|
||||
struct event_context *ev;
|
||||
struct std_event_context *std_ev;
|
||||
|
||||
if (fde->flags == flags) return;
|
||||
|
||||
ev = fde->event_ctx;
|
||||
std_ev = talloc_get_type(ev->additional_data, struct std_event_context);
|
||||
|
||||
fde->flags = 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()
|
||||
*/
|
||||
static int std_event_loop_select(struct std_event_context *std_ev, struct timeval *tvalp)
|
||||
{
|
||||
fd_set r_fds, w_fds;
|
||||
struct fd_event *fde;
|
||||
int selrtn;
|
||||
uint32_t destruction_count = std_ev->destruction_count;
|
||||
|
||||
/* we maybe need to recalculate the maxfd */
|
||||
if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
|
||||
calc_maxfd(std_ev);
|
||||
}
|
||||
|
||||
FD_ZERO(&r_fds);
|
||||
FD_ZERO(&w_fds);
|
||||
|
||||
/* setup any fd events */
|
||||
for (fde = std_ev->fd_events; fde; fde = fde->next) {
|
||||
if (fde->flags & EVENT_FD_READ) {
|
||||
FD_SET(fde->fd, &r_fds);
|
||||
}
|
||||
if (fde->flags & EVENT_FD_WRITE) {
|
||||
FD_SET(fde->fd, &w_fds);
|
||||
}
|
||||
}
|
||||
|
||||
selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
|
||||
|
||||
if (selrtn == -1 && errno == EBADF) {
|
||||
/* the socket is dead! this should never
|
||||
happen as the socket should have first been
|
||||
made readable and that should have removed
|
||||
the event, so this must be a bug. This is a
|
||||
fatal error. */
|
||||
DEBUG(0,("ERROR: EBADF on std_event_loop_once\n"));
|
||||
std_ev->exit_code = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (selrtn == 0 && tvalp) {
|
||||
std_event_loop_timer(std_ev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (selrtn > 0) {
|
||||
/* at least one file descriptor is ready - check
|
||||
which ones and call the handler, being careful to allow
|
||||
the handler to remove itself when called */
|
||||
for (fde = std_ev->fd_events; fde; fde = fde->next) {
|
||||
uint16_t flags = 0;
|
||||
|
||||
if (FD_ISSET(fde->fd, &r_fds)) flags |= EVENT_FD_READ;
|
||||
if (FD_ISSET(fde->fd, &w_fds)) flags |= EVENT_FD_WRITE;
|
||||
if (flags) {
|
||||
fde->handler(std_ev->ev, fde, flags, fde->private_data);
|
||||
if (destruction_count != std_ev->destruction_count) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
do a single event loop using the events defined in ev
|
||||
*/
|
||||
static int std_event_loop_once(struct event_context *ev)
|
||||
{
|
||||
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
|
||||
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);
|
||||
}
|
||||
|
||||
if (epoll_event_loop(std_ev, &tval) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return std_event_loop_select(std_ev, &tval);
|
||||
}
|
||||
|
||||
/*
|
||||
return on failure or (with 0) if all fd events are removed
|
||||
*/
|
||||
static int std_event_loop_wait(struct event_context *ev)
|
||||
{
|
||||
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
|
||||
struct std_event_context);
|
||||
std_ev->exit_code = 0;
|
||||
|
||||
while (std_ev->fd_events && std_ev->exit_code == 0) {
|
||||
if (std_event_loop_once(ev) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return std_ev->exit_code;
|
||||
}
|
||||
|
||||
static const struct event_ops std_event_ops = {
|
||||
.context_init = std_event_context_init,
|
||||
.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,
|
||||
.loop_once = std_event_loop_once,
|
||||
.loop_wait = std_event_loop_wait,
|
||||
};
|
||||
|
||||
const struct event_ops *event_standard_get_ops(void)
|
||||
{
|
||||
return &std_event_ops;
|
||||
}
|
114
ctdb/lib/util/dlinklist.h
Normal file
114
ctdb/lib/util/dlinklist.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
some simple double linked list macros
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* To use these macros you must have a structure containing a next and
|
||||
prev pointer */
|
||||
|
||||
#ifndef _DLINKLIST_H
|
||||
#define _DLINKLIST_H
|
||||
|
||||
|
||||
/* hook into the front of the list */
|
||||
#define DLIST_ADD(list, p) \
|
||||
do { \
|
||||
if (!(list)) { \
|
||||
(list) = (p); \
|
||||
(p)->next = (p)->prev = NULL; \
|
||||
} else { \
|
||||
(list)->prev = (p); \
|
||||
(p)->next = (list); \
|
||||
(p)->prev = NULL; \
|
||||
(list) = (p); \
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
/* remove an element from a list - element doesn't have to be in list. */
|
||||
#define DLIST_REMOVE(list, p) \
|
||||
do { \
|
||||
if ((p) == (list)) { \
|
||||
(list) = (p)->next; \
|
||||
if (list) (list)->prev = NULL; \
|
||||
} else { \
|
||||
if ((p)->prev) (p)->prev->next = (p)->next; \
|
||||
if ((p)->next) (p)->next->prev = (p)->prev; \
|
||||
} \
|
||||
if ((p) != (list)) (p)->next = (p)->prev = NULL; \
|
||||
} while (0)
|
||||
|
||||
/* promote an element to the top of the list */
|
||||
#define DLIST_PROMOTE(list, p) \
|
||||
do { \
|
||||
DLIST_REMOVE(list, p); \
|
||||
DLIST_ADD(list, p); \
|
||||
} while (0)
|
||||
|
||||
/* hook into the end of the list - needs a tmp pointer */
|
||||
#define DLIST_ADD_END(list, p, type) \
|
||||
do { \
|
||||
if (!(list)) { \
|
||||
(list) = (p); \
|
||||
(p)->next = (p)->prev = NULL; \
|
||||
} else { \
|
||||
type tmp; \
|
||||
for (tmp = (list); tmp->next; tmp = tmp->next) ; \
|
||||
tmp->next = (p); \
|
||||
(p)->next = NULL; \
|
||||
(p)->prev = tmp; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* insert 'p' after the given element 'el' in a list. If el is NULL then
|
||||
this is the same as a DLIST_ADD() */
|
||||
#define DLIST_ADD_AFTER(list, p, el) \
|
||||
do { \
|
||||
if (!(list) || !(el)) { \
|
||||
DLIST_ADD(list, p); \
|
||||
} else { \
|
||||
p->prev = el; \
|
||||
p->next = el->next; \
|
||||
el->next = p; \
|
||||
if (p->next) p->next->prev = p; \
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
/* demote an element to the end of the list, needs a tmp pointer */
|
||||
#define DLIST_DEMOTE(list, p, tmp) \
|
||||
do { \
|
||||
DLIST_REMOVE(list, p); \
|
||||
DLIST_ADD_END(list, p, tmp); \
|
||||
} while (0)
|
||||
|
||||
/* concatenate two lists - putting all elements of the 2nd list at the
|
||||
end of the first list */
|
||||
#define DLIST_CONCATENATE(list1, list2, type) \
|
||||
do { \
|
||||
if (!(list1)) { \
|
||||
(list1) = (list2); \
|
||||
} else { \
|
||||
type tmp; \
|
||||
for (tmp = (list1); tmp->next; tmp = tmp->next) ; \
|
||||
tmp->next = (list2); \
|
||||
if (list2) { \
|
||||
(list2)->prev = tmp; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* _DLINKLIST_H */
|
189
ctdb/util.c
Normal file
189
ctdb/util.c
Normal file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
functions taken from samba4 for quick prototyping of ctdb. These are
|
||||
not intended to remain part of ctdb
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/time.h"
|
||||
#include "system/filesys.h"
|
||||
|
||||
|
||||
/**
|
||||
return a zero timeval
|
||||
*/
|
||||
struct timeval timeval_zero(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
return tv;
|
||||
}
|
||||
|
||||
/**
|
||||
return True if a timeval is zero
|
||||
*/
|
||||
bool timeval_is_zero(const struct timeval *tv)
|
||||
{
|
||||
return tv->tv_sec == 0 && tv->tv_usec == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
return a timeval for the current time
|
||||
*/
|
||||
struct timeval timeval_current(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv;
|
||||
}
|
||||
|
||||
/**
|
||||
return a timeval struct with the given elements
|
||||
*/
|
||||
struct timeval timeval_set(uint32_t secs, uint32_t usecs)
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = secs;
|
||||
tv.tv_usec = usecs;
|
||||
return tv;
|
||||
}
|
||||
|
||||
int timeval_compare(const struct timeval *tv1, const struct timeval *tv2)
|
||||
{
|
||||
if (tv1->tv_sec > tv2->tv_sec) return 1;
|
||||
if (tv1->tv_sec < tv2->tv_sec) return -1;
|
||||
if (tv1->tv_usec > tv2->tv_usec) return 1;
|
||||
if (tv1->tv_usec < tv2->tv_usec) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct timeval timeval_until(const struct timeval *tv1,
|
||||
const struct timeval *tv2)
|
||||
{
|
||||
struct timeval t;
|
||||
if (timeval_compare(tv1, tv2) >= 0) {
|
||||
return timeval_zero();
|
||||
}
|
||||
t.tv_sec = tv2->tv_sec - tv1->tv_sec;
|
||||
if (tv1->tv_usec > tv2->tv_usec) {
|
||||
t.tv_sec--;
|
||||
t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec);
|
||||
} else {
|
||||
t.tv_usec = tv2->tv_usec - tv1->tv_usec;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
_PUBLIC_ struct timeval timeval_add(const struct timeval *tv,
|
||||
uint32_t secs, uint32_t usecs)
|
||||
{
|
||||
struct timeval tv2 = *tv;
|
||||
const unsigned int million = 1000000;
|
||||
tv2.tv_sec += secs;
|
||||
tv2.tv_usec += usecs;
|
||||
tv2.tv_sec += tv2.tv_usec / million;
|
||||
tv2.tv_usec = tv2.tv_usec % million;
|
||||
return tv2;
|
||||
}
|
||||
|
||||
|
||||
_PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs)
|
||||
{
|
||||
struct timeval tv = timeval_current();
|
||||
return timeval_add(&tv, secs, usecs);
|
||||
}
|
||||
|
||||
_PUBLIC_ char *fd_load(int fd, size_t *size, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
struct stat sbuf;
|
||||
char *p;
|
||||
|
||||
if (fstat(fd, &sbuf) != 0) return NULL;
|
||||
|
||||
p = (char *)talloc_size(mem_ctx, sbuf.st_size+1);
|
||||
if (!p) return NULL;
|
||||
|
||||
if (read(fd, p, sbuf.st_size) != sbuf.st_size) {
|
||||
talloc_free(p);
|
||||
return NULL;
|
||||
}
|
||||
p[sbuf.st_size] = 0;
|
||||
|
||||
if (size) *size = sbuf.st_size;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
_PUBLIC_ char *file_load(const char *fname, size_t *size, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
int fd;
|
||||
char *p;
|
||||
|
||||
if (!fname || !*fname) return NULL;
|
||||
|
||||
fd = open(fname,O_RDONLY);
|
||||
if (fd == -1) return NULL;
|
||||
|
||||
p = fd_load(fd, size, mem_ctx);
|
||||
|
||||
close(fd);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
parse a buffer into lines
|
||||
'p' will be freed on error, and otherwise will be made a child of the returned array
|
||||
**/
|
||||
static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
int i;
|
||||
char *s, **ret;
|
||||
|
||||
if (!p) return NULL;
|
||||
|
||||
for (s = p, i=0; s < p+size; s++) {
|
||||
if (s[0] == '\n') i++;
|
||||
}
|
||||
|
||||
ret = talloc_array(mem_ctx, char *, i+2);
|
||||
if (!ret) {
|
||||
talloc_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
talloc_steal(ret, p);
|
||||
|
||||
memset(ret, 0, sizeof(ret[0])*(i+2));
|
||||
if (numlines) *numlines = i;
|
||||
|
||||
ret[0] = p;
|
||||
for (s = p, i=0; s < p+size; s++) {
|
||||
if (s[0] == '\n') {
|
||||
s[0] = 0;
|
||||
i++;
|
||||
ret[i] = s+1;
|
||||
}
|
||||
if (s[0] == '\r') s[0] = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
load a file into memory and return an array of pointers to lines in the file
|
||||
must be freed with talloc_free().
|
||||
**/
|
||||
_PUBLIC_ char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
char *p;
|
||||
size_t size;
|
||||
|
||||
p = file_load(fname, &size, mem_ctx);
|
||||
if (!p) return NULL;
|
||||
|
||||
return file_lines_parse(p, size, numlines, mem_ctx);
|
||||
}
|
Loading…
Reference in New Issue
Block a user