summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/replace/test/os2_delete.c8
-rw-r--r--lib/tevent/config.mk46
-rw-r--r--lib/tevent/configure.ac7
-rw-r--r--lib/tevent/libtevent.m437
-rw-r--r--lib/tevent/pytevent.c39
-rw-r--r--lib/tevent/samba.m416
-rw-r--r--lib/tevent/tests.py8
-rw-r--r--lib/tevent/testsuite.c3
-rw-r--r--lib/tevent/tevent.c193
-rw-r--r--lib/tevent/tevent.h136
-rw-r--r--lib/tevent/tevent.mk11
-rw-r--r--lib/tevent/tevent.pc.in2
-rw-r--r--lib/tevent/tevent_aio.c94
-rw-r--r--lib/tevent/tevent_debug.c32
-rw-r--r--lib/tevent/tevent_epoll.c82
-rw-r--r--lib/tevent/tevent_fd.c42
-rw-r--r--lib/tevent/tevent_internal.h109
-rw-r--r--lib/tevent/tevent_select.c76
-rw-r--r--lib/tevent/tevent_signal.c44
-rw-r--r--lib/tevent/tevent_standard.c100
-rw-r--r--lib/tevent/tevent_timed.c27
-rw-r--r--librpc/gen_ndr/named_pipe_auth.h1
-rw-r--r--librpc/ndr/ndr_basic.c2
-rw-r--r--packaging/RHEL/samba.spec.tmpl10
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/Header.pm6
-rw-r--r--source3/Makefile.in2
-rwxr-xr-xsource3/autogen.sh4
-rw-r--r--source3/client/client.c13
-rw-r--r--source3/include/async_req.h30
-rw-r--r--source3/include/async_sock.h10
-rw-r--r--source3/include/packet.h6
-rw-r--r--source3/include/proto.h29
-rw-r--r--source3/include/smb.h3
-rw-r--r--source3/lib/async_req.c129
-rw-r--r--source3/lib/async_sock.c245
-rw-r--r--source3/lib/ctdbd_conn.c49
-rw-r--r--source3/lib/ldb/include/ldb.h2
-rw-r--r--source3/lib/ldb/tools/ldbadd.c13
-rw-r--r--source3/lib/ldb/tools/ldbmodify.c12
-rw-r--r--source3/lib/packet.c44
-rw-r--r--source3/lib/util_sock.c341
-rw-r--r--source3/lib/wb_reqtrans.c (renamed from source3/winbindd/winbindd_reqtrans.c)153
-rw-r--r--source3/lib/wbclient.c774
-rw-r--r--source3/libads/krb5_setpw.c31
-rw-r--r--source3/libsmb/async_smb.c2
-rw-r--r--source3/libsmb/cliconnect.c97
-rw-r--r--source3/libsmb/clidfs.c20
-rw-r--r--source3/libsmb/clireadwrite.c10
-rw-r--r--source3/libsmb/smb_share_modes.c43
-rw-r--r--source3/modules/onefs_open.c6
-rw-r--r--source3/modules/vfs_smb_traffic_analyzer.c5
-rw-r--r--source3/param/loadparm.c2
-rw-r--r--source3/rpc_client/cli_pipe.c5
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c6
-rw-r--r--source3/samba4.m411
-rw-r--r--source3/smbd/process.c2
-rw-r--r--source3/torture/nbio.c19
-rw-r--r--source3/torture/torture.c83
-rw-r--r--source3/torture/utable.c6
-rw-r--r--source3/utils/smbfilter.c5
-rw-r--r--source3/winbindd/idmap.c11
-rw-r--r--source3/winbindd/winbindd_proto.h9
-rw-r--r--source4/auth/kerberos/config.mk2
-rw-r--r--source4/auth/kerberos/krb5_init_context.c34
-rw-r--r--source4/build/m4/public.m48
-rw-r--r--source4/configure.ac9
-rw-r--r--source4/headermap.txt3
-rw-r--r--source4/lib/events/config.mk2
-rw-r--r--source4/lib/events/events.h2
-rw-r--r--source4/lib/events/events_internal.h5
-rw-r--r--source4/lib/events/tevent_s4.c38
-rw-r--r--source4/lib/registry/pyregistry.c2
-rw-r--r--source4/lib/registry/regf.c4
-rw-r--r--source4/lib/registry/tools/common.c2
-rw-r--r--source4/lib/registry/tools/regtree.c13
-rw-r--r--source4/lib/socket/socket.c9
-rw-r--r--source4/lib/socket/socket.h6
-rw-r--r--source4/libcli/ldap/config.mk2
-rw-r--r--source4/libcli/ldap/ldap_client.c33
-rw-r--r--source4/ntvfs/posix/config.m43
-rw-r--r--source4/ntvfs/posix/config.mk2
-rw-r--r--source4/ntvfs/sysdep/inotify.c20
-rwxr-xr-xsource4/selftest/tests.sh2
-rw-r--r--source4/smbd/config.mk3
-rw-r--r--source4/smbd/server.c20
-rw-r--r--source4/smbd/service_named_pipe.c6
-rw-r--r--source4/smbd/service_stream.c55
-rw-r--r--source4/smbd/service_task.c1
-rw-r--r--source4/torture/util_smb.c5
-rw-r--r--source4/winbind/wb_init_domain.c3
-rw-r--r--source4/winbind/wb_samba3_cmd.c2
91 files changed, 2515 insertions, 1144 deletions
diff --git a/lib/replace/test/os2_delete.c b/lib/replace/test/os2_delete.c
index b45c135355a..44efeea08a5 100644
--- a/lib/replace/test/os2_delete.c
+++ b/lib/replace/test/os2_delete.c
@@ -30,7 +30,9 @@ static int test_readdir_os2_delete_ret;
static void cleanup(void)
{
/* I'm a lazy bastard */
- system("rm -rf " TESTDIR);
+ if (system("rm -rf " TESTDIR)) {
+ FAILED("system");
+ }
mkdir(TESTDIR, 0700) == 0 || FAILED("mkdir");
}
@@ -118,7 +120,9 @@ int test_readdir_os2_delete(void)
rmdir(TESTDIR) == 0 || FAILED("rmdir");
- system("rm -rf " TESTDIR);
+ if (system("rm -rf " TESTDIR) == -1) {
+ FAILED("system");
+ }
return test_readdir_os2_delete_ret;
}
diff --git a/lib/tevent/config.mk b/lib/tevent/config.mk
deleted file mode 100644
index e4fb9a8088f..00000000000
--- a/lib/tevent/config.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-##############################
-[MODULE::TEVENT_AIO]
-PRIVATE_DEPENDENCIES = LIBAIO_LINUX
-OUTPUT_TYPE = MERGED_OBJ
-SUBSYSTEM = LIBTEVENT
-##############################
-
-TEVENT_AIO_OBJ_FILES = $(libteventsrcdir)/tevent_aio.o
-
-##############################
-[MODULE::TEVENT_EPOLL]
-OUTPUT_TYPE = MERGED_OBJ
-SUBSYSTEM = LIBTEVENT
-##############################
-
-TEVENT_EPOLL_OBJ_FILES = $(libteventsrcdir)/tevent_epoll.o
-
-##############################
-[MODULE::TEVENT_SELECT]
-OUTPUT_TYPE = MERGED_OBJ
-SUBSYSTEM = LIBTEVENT
-##############################
-
-TEVENT_SELECT_OBJ_FILES = $(libteventsrcdir)/tevent_select.o
-
-##############################
-[MODULE::TEVENT_STANDARD]
-OUTPUT_TYPE = MERGED_OBJ
-SUBSYSTEM = LIBTEVENT
-##############################
-
-TEVENT_STANDARD_OBJ_FILES = $(libteventsrcdir)/tevent_standard.o
-
-################################################
-# Start SUBSYSTEM LIBTEVENT
-[LIBRARY::LIBTEVENT]
-PUBLIC_DEPENDENCIES = LIBTALLOC
-OUTPUT_TYPE = MERGED_OBJ
-CFLAGS = -I../lib/tevent
-#
-# End SUBSYSTEM LIBTEVENT
-################################################
-
-LIBTEVENT_OBJ_FILES = $(addprefix $(libteventsrcdir)/, tevent.o tevent_timed.o tevent_signal.o tevent_debug.o tevent_util.o)
-
-PUBLIC_HEADERS += $(addprefix $(libteventsrcdir)/, tevent.h tevent_internal.h)
diff --git a/lib/tevent/configure.ac b/lib/tevent/configure.ac
index 22d306b0f65..3cc06a144a5 100644
--- a/lib/tevent/configure.ac
+++ b/lib/tevent/configure.ac
@@ -1,11 +1,8 @@
AC_PREREQ(2.50)
-AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""])
-AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""])
-AC_DEFUN([SMB_ENABLE], [echo -n ""])
-AC_DEFUN([SMB_EXT_LIB], [echo -n ""])
-AC_INIT(tevent, 0.9.0)
+AC_INIT(tevent, 0.9.2)
AC_CONFIG_SRCDIR([tevent.c])
AC_CONFIG_HEADER(config.h)
+
AC_LIBREPLACE_ALL_CHECKS
AC_LD_EXPORT_DYNAMIC
diff --git a/lib/tevent/libtevent.m4 b/lib/tevent/libtevent.m4
index 30105d9bef0..ec2ed9cd1fd 100644
--- a/lib/tevent/libtevent.m4
+++ b/lib/tevent/libtevent.m4
@@ -1,12 +1,14 @@
dnl find the tevent sources. This is meant to work both for
dnl standalone builds, and builds of packages using libtevent
+
+AC_SUBST(teventdir)
+
if test x"$teventdir" = "x"; then
teventdir=""
teventpaths="$srcdir $srcdir/../lib/tevent $srcdir/tevent $srcdir/../tevent"
for d in $teventpaths; do
if test -f "$d/tevent.c"; then
teventdir="$d"
- AC_SUBST(teventdir)
break;
fi
done
@@ -15,37 +17,32 @@ if test x"$teventdir" = "x"; then
fi
fi
-TEVENT_OBJ="tevent.o tevent_select.o tevent_signal.o tevent_timed.o tevent_standard.o tevent_debug.o tevent_util.o"
-AC_LIBREPLACE_NETWORK_CHECKS
+TEVENT_OBJ=""
+TEVENT_CFLAGS=""
+TEVENT_LIBS=""
+AC_SUBST(TEVENT_OBJ)
+AC_SUBST(TEVENT_CFLAGS)
+AC_SUBST(TEVENT_LIBS)
+
+TEVENT_CFLAGS="-I$teventdir"
+
+TEVENT_OBJ="tevent.o tevent_fd.o tevent_timed.o tevent_signal.o tevent_debug.o tevent_util.o"
+TEVENT_OBJ="$TEVENT_OBJ tevent_standard.o tevent_select.o"
-SMB_ENABLE(TEVENT_EPOLL, NO)
-SMB_ENABLE(TEVENT_AIO, NO)
+tevent_cv_aio_support=no
AC_CHECK_HEADERS(sys/epoll.h)
AC_CHECK_FUNCS(epoll_create)
if test x"$ac_cv_header_sys_epoll_h" = x"yes" -a x"$ac_cv_func_epoll_create" = x"yes"; then
TEVENT_OBJ="$TEVENT_OBJ tevent_epoll.o"
- SMB_ENABLE(TEVENT_EPOLL,YES)
AC_DEFINE(HAVE_EPOLL, 1, [Whether epoll available])
- #TODO: remove HAVE_EVENTS_EPOLL and use HAVE_EPOLL
- AC_DEFINE(HAVE_EVENTS_EPOLL, 1, [Whether epoll available])
# check for native Linux AIO interface
AC_CHECK_HEADERS(libaio.h)
- AC_CHECK_LIB_EXT(aio, AIO_LIBS, io_getevents)
+ AC_CHECK_LIB_EXT(aio, TEVENT_LIBS, io_getevents)
if test x"$ac_cv_header_libaio_h" = x"yes" -a x"$ac_cv_lib_ext_aio_io_getevents" = x"yes";then
TEVENT_OBJ="$TEVENT_OBJ tevent_aio.o"
- SMB_ENABLE(TEVENT_AIO,YES)
+ tevent_cv_aio_support=yes
AC_DEFINE(HAVE_LINUX_AIO, 1, [Whether Linux AIO is available])
fi
fi
-AC_SUBST(TEVENT_OBJ)
-SMB_EXT_LIB(LIBAIO_LINUX, $AIO_LIBS)
-
-TEVENT_CFLAGS="-I$teventdir"
-AC_SUBST(TEVENT_CFLAGS)
-
-TEVENT_LIBS="$AIO_LIBS"
-AC_SUBST(TEVENT_LIBS)
-
-
diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c
index a969373738c..3d71d783974 100644
--- a/lib/tevent/pytevent.c
+++ b/lib/tevent/pytevent.c
@@ -24,9 +24,9 @@
typedef struct {
PyObject_HEAD
struct tevent_context *ev_ctx;
-} PyEventContextObject;
+} PyTEventContextObject;
-PyAPI_DATA(PyTypeObject) PyEventContext;
+PyAPI_DATA(PyTypeObject) PyTEventContext;
static PyObject *py_set_default_backend(PyObject *self, PyObject *args)
{
@@ -34,13 +34,13 @@ static PyObject *py_set_default_backend(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
- event_set_default_backend(name);
+ tevent_set_default_backend(name);
return Py_None;
}
static PyObject *py_backend_list(PyObject *self)
{
- const char **backends = event_backend_list(NULL);
+ const char **backends = tevent_backend_list(NULL);
PyObject *ret;
int i, len;
@@ -66,28 +66,28 @@ static PyObject *py_event_ctx_new(PyTypeObject *type, PyObject *args, PyObject *
const char *kwnames[] = { "name", NULL };
char *name = NULL;
struct tevent_context *ev_ctx;
- PyEventContextObject *ret;
+ PyTEventContextObject *ret;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", (char **)kwnames, &name))
return NULL;
if (name == NULL)
- ev_ctx = event_context_init(NULL);
+ ev_ctx = tevent_context_init(NULL);
else
- ev_ctx = event_context_init_byname(NULL, name);
+ ev_ctx = tevent_context_init_byname(NULL, name);
- ret = (PyEventContextObject *)type->tp_alloc(type, 0);
+ ret = (PyTEventContextObject *)type->tp_alloc(type, 0);
ret->ev_ctx = ev_ctx;
return (PyObject *)ret;
}
-static PyObject *py_event_ctx_loop_once(PyEventContextObject *self)
+static PyObject *py_event_ctx_loop_once(PyTEventContextObject *self)
{
- return PyInt_FromLong(event_loop_once(self->ev_ctx));
+ return PyInt_FromLong(tevent_loop_once(self->ev_ctx));
}
-static PyObject *py_event_ctx_loop_wait(PyEventContextObject *self)
+static PyObject *py_event_ctx_loop_wait(PyTEventContextObject *self)
{
- return PyInt_FromLong(event_loop_wait(self->ev_ctx));
+ return PyInt_FromLong(tevent_loop_wait(self->ev_ctx));
}
static PyMethodDef py_event_ctx_methods[] = {
@@ -98,16 +98,17 @@ static PyMethodDef py_event_ctx_methods[] = {
{ NULL }
};
-static void py_event_ctx_dealloc(PyEventContextObject * self)
+static void py_event_ctx_dealloc(PyTEventContextObject * self)
{
talloc_free(self->ev_ctx);
self->ob_type->tp_free(self);
}
-PyTypeObject PyEventContext = {
- .tp_name = "EventContext",
+
+PyTypeObject PyTEventContext = {
+ .tp_name = "TEventContext",
.tp_methods = py_event_ctx_methods,
- .tp_basicsize = sizeof(PyEventContextObject),
+ .tp_basicsize = sizeof(PyTEventContextObject),
.tp_dealloc = (destructor)py_event_ctx_dealloc,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_new = py_event_ctx_new,
@@ -117,14 +118,14 @@ void inittevent(void)
{
PyObject *m;
- if (PyType_Ready(&PyEventContext) < 0)
+ if (PyType_Ready(&PyTEventContext) < 0)
return;
m = Py_InitModule3("tevent", tevent_methods, "Event management.");
if (m == NULL)
return;
- Py_INCREF(&PyEventContext);
- PyModule_AddObject(m, "EventContext", (PyObject *)&PyEventContext);
+ Py_INCREF(&PyTEventContext);
+ PyModule_AddObject(m, "TEventContext", (PyObject *)&PyTEventContext);
}
diff --git a/lib/tevent/samba.m4 b/lib/tevent/samba.m4
new file mode 100644
index 00000000000..89b0b705b49
--- /dev/null
+++ b/lib/tevent/samba.m4
@@ -0,0 +1,16 @@
+
+teventdir="\$(libteventsrcdir)"
+m4_include(../lib/tevent/libtevent.m4)
+
+SMB_EXT_LIB(LIBTEVENT_EXT, [${TEVENT_LIBS}])
+SMB_ENABLE(LIBTEVENT_EXT)
+
+SMB_SUBSYSTEM(LIBTEVENT,
+ [\$(addprefix \$(libteventsrcdir)/, ${TEVENT_OBJ})],
+ [LIBTEVENT_EXT],
+ [${TEVENT_CFLAGS}])
+
+SMB_MAKE_SETTINGS([
+PUBLIC_HEADERS += \$(addprefix \$(libteventsrcdir)/, tevent.h tevent_internal.h)
+])
+
diff --git a/lib/tevent/tests.py b/lib/tevent/tests.py
index 0ec736b359a..bf594a14f6e 100644
--- a/lib/tevent/tests.py
+++ b/lib/tevent/tests.py
@@ -17,15 +17,15 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-import tevent as events
+import tevent
import unittest
# Just test the bindings are there and that calling them doesn't crash
# anything.
-class EventTestCase(unittest.TestCase):
+class TEventTestCase(unittest.TestCase):
def test_create(self):
- self.assertTrue(events.EventContext() is not None)
+ self.assertTrue(tevent.TEventContext() is not None)
def test_loop_wait(self):
- self.assertEquals(0, events.EventContext().loop_wait())
+ self.assertEquals(0, tevent.TEventContext().loop_wait())
diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c
index ec57c5ad2eb..1b811f5fa2e 100644
--- a/lib/tevent/testsuite.c
+++ b/lib/tevent/testsuite.c
@@ -81,8 +81,9 @@ static bool test_event_context(struct torture_context *test,
/* create a pipe */
pipe(fd);
- fde = event_add_fd(ev_ctx, ev_ctx, fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
+ fde = event_add_fd(ev_ctx, ev_ctx, fd[0], EVENT_FD_READ,
fde_handler, fd);
+ tevent_fd_set_auto_close(fde);
event_add_timed(ev_ctx, ev_ctx, timeval_current_ofs(2,0),
finished_handler, &finished);
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index e45a690c33a..5582b583e73 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -41,52 +41,53 @@
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
+ structure using the function tevent_context_init(); This returns a
'struct tevent_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()
+ using tevent_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
+ Finally, you call tevent_loop_wait_once() to block waiting for one of the
+ events to occor or tevent_loop_wait() which will loop
forever.
*/
#include "replace.h"
+#include "system/filesys.h"
#include "tevent.h"
#include "tevent_internal.h"
#include "tevent_util.h"
-struct event_ops_list {
- struct event_ops_list *next, *prev;
+struct tevent_ops_list {
+ struct tevent_ops_list *next, *prev;
const char *name;
- const struct event_ops *ops;
+ const struct tevent_ops *ops;
};
/* list of registered event backends */
-static struct event_ops_list *event_backends = NULL;
-static char *event_default_backend = NULL;
+static struct tevent_ops_list *tevent_backends = NULL;
+static char *tevent_default_backend = NULL;
/*
register an events backend
*/
-bool event_register_backend(const char *name, const struct event_ops *ops)
+bool tevent_register_backend(const char *name, const struct tevent_ops *ops)
{
- struct event_ops_list *e;
+ struct tevent_ops_list *e;
- for (e = event_backends; e != NULL; e = e->next) {
+ for (e = tevent_backends; e != NULL; e = e->next) {
if (0 == strcmp(e->name, name)) {
/* already registered, skip it */
return true;
}
}
- e = talloc(talloc_autofree_context(), struct event_ops_list);
+ e = talloc(talloc_autofree_context(), struct tevent_ops_list);
if (e == NULL) return false;
e->name = name;
e->ops = ops;
- DLIST_ADD(event_backends, e);
+ DLIST_ADD(tevent_backends, e);
return true;
}
@@ -94,38 +95,39 @@ bool event_register_backend(const char *name, const struct event_ops *ops)
/*
set the default event backend
*/
-void event_set_default_backend(const char *backend)
+void tevent_set_default_backend(const char *backend)
{
- if (event_default_backend) free(event_default_backend);
- event_default_backend = strdup(backend);
+ talloc_free(tevent_default_backend);
+ tevent_default_backend = talloc_strdup(talloc_autofree_context(),
+ backend);
}
/*
initialise backends if not already done
*/
-static void event_backend_init(void)
+static void tevent_backend_init(void)
{
- events_select_init();
- events_standard_init();
-#if HAVE_EVENTS_EPOLL
- events_epoll_init();
+ tevent_select_init();
+ tevent_standard_init();
+#ifdef HAVE_EPOLL
+ tevent_epoll_init();
#endif
-#if HAVE_LINUX_AIO
- events_aio_init();
+#ifdef HAVE_LINUX_AIO
+ tevent_aio_init();
#endif
}
/*
list available backends
*/
-const char **event_backend_list(TALLOC_CTX *mem_ctx)
+const char **tevent_backend_list(TALLOC_CTX *mem_ctx)
{
const char **list = NULL;
- struct event_ops_list *e;
+ struct tevent_ops_list *e;
- event_backend_init();
+ tevent_backend_init();
- for (e=event_backends;e;e=e->next) {
+ for (e=tevent_backends;e;e=e->next) {
list = ev_str_list_add(list, e->name);
}
@@ -143,10 +145,10 @@ const char **event_backend_list(TALLOC_CTX *mem_ctx)
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!
+ NOTE: use tevent_context_init() inside of samba!
*/
-static struct tevent_context *event_context_init_ops(TALLOC_CTX *mem_ctx,
- const struct event_ops *ops)
+static struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx,
+ const struct tevent_ops *ops)
{
struct tevent_context *ev;
int ret;
@@ -170,22 +172,23 @@ static struct tevent_context *event_context_init_ops(TALLOC_CTX *mem_ctx,
call, and all subsequent calls pass this event_context as the first
element. Event handlers also receive this as their first argument.
*/
-struct tevent_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name)
+struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx,
+ const char *name)
{
- struct event_ops_list *e;
+ struct tevent_ops_list *e;
- event_backend_init();
+ tevent_backend_init();
if (name == NULL) {
- name = event_default_backend;
+ name = tevent_default_backend;
}
if (name == NULL) {
name = "standard";
}
- for (e=event_backends;e;e=e->next) {
+ for (e=tevent_backends;e;e=e->next) {
if (strcmp(name, e->name) == 0) {
- return event_context_init_ops(mem_ctx, e->ops);
+ return tevent_context_init_ops(mem_ctx, e->ops);
}
}
return NULL;
@@ -197,42 +200,74 @@ struct tevent_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char
call, and all subsequent calls pass this event_context as the first
element. Event handlers also receive this as their first argument.
*/
-struct tevent_context *event_context_init(TALLOC_CTX *mem_ctx)
+struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx)
{
- return event_context_init_byname(mem_ctx, NULL);
+ return tevent_context_init_byname(mem_ctx, NULL);
}
/*
add a fd based event
return NULL on failure (memory allocation error)
- if flags contains EVENT_FD_AUTOCLOSE then the fd will be closed when
+ if flags contains TEVENT_FD_AUTOCLOSE then the fd will be closed when
the returned fd_event context is freed
*/
-struct tevent_fd *event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags, event_fd_handler_t handler,
- void *private_data)
+struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ int fd,
+ uint16_t flags,
+ tevent_fd_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
{
- return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data);
+ return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data,
+ handler_name, location);
}
/*
add a disk aio event
*/
-struct aio_event *event_add_aio(struct tevent_context *ev,
- TALLOC_CTX *mem_ctx,
- struct iocb *iocb,
- event_aio_handler_t handler,
- void *private_data)
+struct tevent_aio *_tevent_add_aio(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ struct iocb *iocb,
+ tevent_aio_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
{
if (ev->ops->add_aio == NULL) return NULL;
- return ev->ops->add_aio(ev, mem_ctx, iocb, handler, private_data);
+ return ev->ops->add_aio(ev, mem_ctx, iocb, handler, private_data,
+ handler_name, location);
+}
+
+/*
+ set a close function on the fd event
+*/
+void tevent_fd_set_close_fn(struct tevent_fd *fde,
+ tevent_fd_close_fn_t close_fn)
+{
+ if (!fde) return;
+ fde->event_ctx->ops->set_fd_close_fn(fde, close_fn);
+}
+
+static void tevent_fd_auto_close_fn(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ int fd,
+ void *private_data)
+{
+ close(fd);
+}
+
+void tevent_fd_set_auto_close(struct tevent_fd *fde)
+{
+ tevent_fd_set_close_fn(fde, tevent_fd_auto_close_fn);
}
/*
return the fd event flags
*/
-uint16_t event_get_fd_flags(struct tevent_fd *fde)
+uint16_t tevent_fd_get_flags(struct tevent_fd *fde)
{
if (!fde) return 0;
return fde->event_ctx->ops->get_fd_flags(fde);
@@ -241,22 +276,26 @@ uint16_t event_get_fd_flags(struct tevent_fd *fde)
/*
set the fd event flags
*/
-void event_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
+void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags)
{
if (!fde) return;
fde->event_ctx->ops->set_fd_flags(fde, flags);
}
/*
- add a timed event
+ add a timer event
return NULL on failure
*/
-struct tevent_timer *event_add_timed(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
- struct timeval next_event,
- event_timed_handler_t handler,
- void *private_data)
+struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ struct timeval next_event,
+ tevent_timer_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
{
- return ev->ops->add_timer(ev, mem_ctx, next_event, handler, private_data);
+ return ev->ops->add_timer(ev, mem_ctx, next_event, handler, private_data,
+ handler_name, location);
}
/*
@@ -266,19 +305,23 @@ struct tevent_timer *event_add_timed(struct tevent_context *ev, TALLOC_CTX *mem_
return NULL on failure
*/
-struct signal_event *event_add_signal(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
- int signum,
- int sa_flags,
- event_signal_handler_t handler,
- void *private_data)
+struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ int signum,
+ int sa_flags,
+ tevent_signal_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
{
- return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data);
+ return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data,
+ handler_name, location);
}
/*
do a single event loop using the events defined in ev
*/
-int event_loop_once(struct tevent_context *ev)
+int tevent_loop_once(struct tevent_context *ev)
{
return ev->ops->loop_once(ev);
}
@@ -286,25 +329,7 @@ int event_loop_once(struct tevent_context *ev)
/*
return on failure or (with 0) if all fd events are removed
*/
-int event_loop_wait(struct tevent_context *ev)
+int tevent_loop_wait(struct tevent_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 tevent_context *event_context_find(TALLOC_CTX *mem_ctx)
-{
- struct tevent_context *ev = talloc_find_parent_bytype(mem_ctx, struct tevent_context);
- if (ev == NULL) {
- ev = event_context_init(mem_ctx);
- }
- return ev;
-}
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index f626de9d12a..b57d96f5fb9 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -33,59 +33,93 @@ struct tevent_aio;
struct tevent_signal;
/* event handler types */
-typedef void (*tevent_fd_handler_t)(struct tevent_context *,
- struct tevent_fd *,
- uint16_t , void *);
-typedef void (*tevent_timer_handler_t)(struct tevent_context *,
- struct tevent_timer *,
- struct timeval , void *);
-typedef void (*tevent_signal_handler_t)(struct tevent_context *,
- struct tevent_signal *,
- int , int, void *, void *);
-typedef void (*tevent_aio_handler_t)(struct tevent_context *,
- struct tevent_aio *,
- int, void *);
+typedef void (*tevent_fd_handler_t)(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data);
+typedef void (*tevent_fd_close_fn_t)(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ int fd,
+ void *private_data);
+typedef void (*tevent_timer_handler_t)(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval current_time,
+ void *private_data);
+typedef void (*tevent_signal_handler_t)(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data);
+typedef void (*tevent_aio_handler_t)(struct tevent_context *ev,
+ struct tevent_aio *ae,
+ int ret,
+ void *private_data);
struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx);
struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name);
const char **tevent_backend_list(TALLOC_CTX *mem_ctx);
void tevent_set_default_backend(const char *backend);
-struct tevent_fd *tevent_add_fd(struct tevent_context *ev,
- TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags,
- tevent_fd_handler_t handler,
- void *private_data);
-
-struct tevent_timer *tevent_add_timer(struct tevent_context *ev,
- TALLOC_CTX *mem_ctx,
- struct timeval next_event,
- tevent_timer_handler_t handler,
- void *private_data);
-
-struct tevent_signal *tevent_add_signal(struct tevent_context *ev,
- TALLOC_CTX *mem_ctx,
- int signum, int sa_flags,
- tevent_signal_handler_t handler,
- void *private_data);
+struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ int fd,
+ uint16_t flags,
+ tevent_fd_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location);
+#define tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \
+ _tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data, \
+ #handler, __location__)
+
+struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ struct timeval next_event,
+ tevent_timer_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location);
+#define tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) \
+ _tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \
+ #handler, __location__);
+
+struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ int signum,
+ int sa_flags,
+ tevent_signal_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location);
+#define tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \
+ _tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, \
+ #handler, __location__)
struct iocb;
-struct tevent_aio *tevent_add_aio(struct tevent_context *ev,
- TALLOC_CTX *mem_ctx,
- struct iocb *iocb,
- tevent_aio_handler_t handler,
- void *private_data);
+struct tevent_aio *_tevent_add_aio(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ struct iocb *iocb,
+ tevent_aio_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location);
+#define tevent_add_aio(ev, mem_ctx, iocb, handler, private_data) \
+ _tevent_add_aio(ev, mem_ctx, iocb, handler, private_data, \
+ #handler, __location__);
int tevent_loop_once(struct tevent_context *ev);
int tevent_loop_wait(struct tevent_context *ev);
+void tevent_fd_set_close_fn(struct tevent_fd *fde,
+ tevent_fd_close_fn_t close_fn);
+void tevent_fd_set_auto_close(struct tevent_fd *fde);
uint16_t tevent_fd_get_flags(struct tevent_fd *fde);
void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
/* bits for file descriptor event flags */
#define TEVENT_FD_READ 1
#define TEVENT_FD_WRITE 2
-#define TEVENT_FD_AUTOCLOSE 4
#define TEVENT_FD_WRITEABLE(fde) \
tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_WRITE)
@@ -97,10 +131,21 @@ void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
#define TEVENT_FD_NOT_READABLE(fde) \
tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_READ)
-/* for now always define the compat symbols */
-#ifndef TEVENT_COMPAT_DEFINES
-#define TEVENT_COMPAT_DEFINES 1
-#endif
+/* DEBUG */
+enum tevent_debug_level {
+ TEVENT_DEBUG_FATAL,
+ TEVENT_DEBUG_ERROR,
+ TEVENT_DEBUG_WARNING,
+ TEVENT_DEBUG_TRACE
+};
+
+int tevent_set_debug(struct tevent_context *ev,
+ void (*debug)(void *context,
+ enum tevent_debug_level level,
+ const char *fmt,
+ va_list ap) PRINTF_ATTRIBUTE(3,0),
+ void *context);
+int tevent_set_debug_stderr(struct tevent_context *ev);
#ifdef TEVENT_COMPAT_DEFINES
@@ -154,7 +199,6 @@ void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
#define EVENT_FD_READ TEVENT_FD_READ
#define EVENT_FD_WRITE TEVENT_FD_WRITE
-#define EVENT_FD_AUTOCLOSE TEVENT_FD_AUTOCLOSE
#define EVENT_FD_WRITEABLE(fde) \
TEVENT_FD_WRITEABLE(fde)
@@ -168,6 +212,18 @@ void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
#define EVENT_FD_NOT_READABLE(fde) \
TEVENT_FD_NOT_READABLE(fde)
+#define ev_debug_level tevent_debug_level
+
+#define EV_DEBUG_FATAL TEVENT_DEBUG_FATAL
+#define EV_DEBUG_ERROR TEVENT_DEBUG_ERROR
+#define EV_DEBUG_WARNING TEVENT_DEBUG_WARNING
+#define EV_DEBUG_TRACE TEVENT_DEBUG_TRACE
+
+#define ev_set_debug(ev, debug, context) \
+ tevent_set_debug(ev, debug, context)
+
+#define ev_set_debug_stderr(_ev) tevent_set_debug_stderr(ev)
+
#endif /* TEVENT_COMPAT_DEFINES */
#endif /* __TEVENT_H__ */
diff --git a/lib/tevent/tevent.mk b/lib/tevent/tevent.mk
index 6538362a060..be7e2982188 100644
--- a/lib/tevent/tevent.mk
+++ b/lib/tevent/tevent.mk
@@ -1,11 +1,12 @@
-TEVENT_SONAME = libtevent.$(SHLIBEXT).0
-TEVENT_SOLIB = libtevent.$(SHLIBEXT).$(PACKAGE_VERSION)
+TEVENT_SOBASE = libtevent.$(SHLIBEXT)
+TEVENT_SONAME = $(TEVENT_SOBASE).0
+TEVENT_SOLIB = $(TEVENT_SOBASE).$(PACKAGE_VERSION)
TEVENT_STLIB = libtevent.a
$(TEVENT_STLIB): $(TEVENT_OBJ)
ar -rv $(TEVENT_STLIB) $(TEVENT_OBJ)
-libtevent.$(SHLIBEXT): $(TEVENT_SOLIB)
+$(TEVENT_SOBASE): $(TEVENT_SOLIB)
ln -fs $< $@
$(TEVENT_SONAME): $(TEVENT_SOLIB)
@@ -31,7 +32,7 @@ installlibs:: installdirs
install:: all installdirs installheaders installlibs $(PYTHON_INSTALL_TARGET)
clean::
- rm -f $(TEVENT_SONAME) $(TEVENT_SOLIB) $(TEVENT_STLIB) libtevent.$(SHLIBEXT)
+ rm -f $(TEVENT_SOBASE) $(TEVENT_SONAME) $(TEVENT_SOLIB) $(TEVENT_STLIB)
rm -f tevent.pc
rm -f tevent.$(SHLIBEXT)
@@ -45,7 +46,7 @@ build-python:: tevent.$(SHLIBEXT)
pytevent.o: $(teventdir)/pytevent.c
$(CC) $(PICFLAG) -c $(teventdir)/pytevent.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags`
-tevent.$(SHLIBEXT): libtevent.$(SHLIBEXT) pytevent.o
+tevent.$(SHLIBEXT): $(TEVENT_SOBASE) $(TEVENT_SONAME) pytevent.o
$(SHLD) $(SHLD_FLAGS) -o $@ pytevent.o -L. -ltevent `$(PYTHON_CONFIG) --libs`
install-python:: build-python
diff --git a/lib/tevent/tevent.pc.in b/lib/tevent/tevent.pc.in
index afd9fcc2796..93d0cf5d8b7 100644
--- a/lib/tevent/tevent.pc.in
+++ b/lib/tevent/tevent.pc.in
@@ -3,7 +3,7 @@ exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
-Name: events
+Name: tevent
Description: An event system library
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -ltevent
diff --git a/lib/tevent/tevent_aio.c b/lib/tevent/tevent_aio.c
index 746e96060b3..b15dab3aaf3 100644
--- a/lib/tevent/tevent_aio.c
+++ b/lib/tevent/tevent_aio.c
@@ -30,12 +30,12 @@
this is _very_ experimental code
*/
-#include "system/filesys.h"
#include "replace.h"
+#include "system/filesys.h"
+#include "system/select.h"
#include "tevent.h"
#include "tevent_internal.h"
#include "tevent_util.h"
-#include <sys/epoll.h>
#include <libaio.h>
#define MAX_AIO_QUEUE_DEPTH 100
@@ -66,11 +66,11 @@ struct aio_event_context {
pid_t pid;
};
-struct aio_event {
+struct tevent_aio {
struct tevent_context *event_ctx;
struct iocb iocb;
void *private_data;
- event_aio_handler_t handler;
+ tevent_aio_handler_t handler;
};
/*
@@ -79,8 +79,8 @@ struct aio_event {
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);
+ if (flags & TEVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
+ if (flags & TEVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
return ret;
}
@@ -113,7 +113,8 @@ static void epoll_check_reopen(struct aio_event_context *aio_ev)
close(aio_ev->epoll_fd);
aio_ev->epoll_fd = epoll_create(MAX_AIO_QUEUE_DEPTH);
if (aio_ev->epoll_fd == -1) {
- ev_debug(aio_ev->ev, EV_DEBUG_FATAL, "Failed to recreate epoll handle after fork\n");
+ tevent_debug(aio_ev->ev, TEVENT_DEBUG_FATAL,
+ "Failed to recreate epoll handle after fork\n");
return;
}
aio_ev->pid = getpid();
@@ -146,7 +147,7 @@ static void epoll_add_event(struct aio_event_context *aio_ev, struct tevent_fd *
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) {
+ if (fde->flags & TEVENT_FD_READ) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
}
}
@@ -191,7 +192,7 @@ static void epoll_mod_event(struct aio_event_context *aio_ev, struct tevent_fd *
epoll_ctl(aio_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event);
/* only if we want to read we want to tell the event handler about errors */
- if (fde->flags & EVENT_FD_READ) {
+ if (fde->flags & TEVENT_FD_READ) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
}
}
@@ -199,8 +200,8 @@ static void epoll_mod_event(struct aio_event_context *aio_ev, struct tevent_fd *
static void epoll_change_event(struct aio_event_context *aio_ev, struct tevent_fd *fde)
{
bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
- bool want_read = (fde->flags & EVENT_FD_READ);
- bool want_write= (fde->flags & EVENT_FD_WRITE);
+ bool want_read = (fde->flags & TEVENT_FD_READ);
+ bool want_write= (fde->flags & TEVENT_FD_WRITE);
if (aio_ev->epoll_fd == -1) return;
@@ -260,7 +261,7 @@ static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tval
if (aio_ev->epoll_fd == -1) return -1;
if (aio_ev->ev->num_signal_handlers &&
- common_event_check_signal(aio_ev->ev)) {
+ tevent_common_check_signal(aio_ev->ev)) {
return 0;
}
@@ -278,14 +279,14 @@ static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tval
if (ret == -EINTR) {
if (aio_ev->ev->num_signal_handlers) {
- common_event_check_signal(aio_ev->ev);
+ tevent_common_check_signal(aio_ev->ev);
}
return 0;
}
if (ret == 0 && tvalp) {
/* we don't care about a possible delay here */
- common_event_loop_timer_delay(aio_ev->ev);
+ tevent_common_loop_timer_delay(aio_ev->ev);
return 0;
}
@@ -296,8 +297,8 @@ static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tval
switch (finished->aio_lio_opcode) {
case IO_CMD_PWRITE:
case IO_CMD_PREAD: {
- struct aio_event *ae = talloc_get_type(finished->data,
- struct aio_event);
+ struct tevent_aio *ae = talloc_get_type(finished->data,
+ struct tevent_aio);
if (ae) {
talloc_set_destructor(ae, NULL);
ae->handler(ae->event_ctx, ae,
@@ -326,10 +327,10 @@ static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tval
epoll_del_event(aio_ev, fde);
continue;
}
- flags |= EVENT_FD_READ;
+ flags |= TEVENT_FD_READ;
}
- if (ep->events & EPOLLIN) flags |= EVENT_FD_READ;
- if (ep->events & EPOLLOUT) flags |= EVENT_FD_WRITE;
+ if (ep->events & EPOLLIN) flags |= TEVENT_FD_READ;
+ if (ep->events & EPOLLOUT) flags |= TEVENT_FD_WRITE;
if (flags) {
fde->handler(aio_ev->ev, fde, flags, fde->private_data);
}
@@ -398,8 +399,8 @@ static int aio_event_fd_destructor(struct tevent_fd *fde)
epoll_del_event(aio_ev, fde);
- if (fde->flags & EVENT_FD_AUTOCLOSE) {
- close(fde->fd);
+ if (fde->close_fn) {
+ fde->close_fn(ev, fde, fde->fd, fde->private_data);
fde->fd = -1;
}
@@ -411,9 +412,11 @@ static int aio_event_fd_destructor(struct tevent_fd *fde)
return NULL on failure (memory allocation error)
*/
static struct tevent_fd *aio_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags,
- event_fd_handler_t handler,
- void *private_data)
+ int fd, uint16_t flags,
+ tevent_fd_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
{
struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data,
struct aio_event_context);
@@ -428,7 +431,10 @@ static struct tevent_fd *aio_event_add_fd(struct tevent_context *ev, TALLOC_CTX
fde->fd = fd;
fde->flags = flags;
fde->handler = handler;
+ fde->close_fn = NULL;
fde->private_data = private_data;
+ fde->handler_name = handler_name;
+ fde->location = location;
fde->additional_flags = 0;
fde->additional_data = NULL;
@@ -441,15 +447,6 @@ static struct tevent_fd *aio_event_add_fd(struct tevent_context *ev, TALLOC_CTX
return fde;
}
-
-/*
- return the fd event flags
-*/
-static uint16_t aio_event_get_fd_flags(struct tevent_fd *fde)
-{
- return fde->flags;
-}
-
/*
set the fd event flags
*/
@@ -479,7 +476,7 @@ static int aio_event_loop_once(struct tevent_context *ev)
struct aio_event_context);
struct timeval tval;
- tval = common_event_loop_timer_delay(ev);
+ tval = tevent_common_loop_timer_delay(ev);
if (ev_timeval_is_zero(&tval)) {
return 0;
}
@@ -508,7 +505,7 @@ static int aio_event_loop_wait(struct tevent_context *ev)
/*
called when a disk IO event needs to be cancelled
*/
-static int aio_destructor(struct aio_event *ae)
+static int aio_destructor(struct tevent_aio *ae)
{
struct tevent_context *ev = ae->event_ctx;
struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data,
@@ -520,16 +517,18 @@ static int aio_destructor(struct aio_event *ae)
}
/* submit an aio disk IO event */
-static struct aio_event *aio_event_add_aio(struct tevent_context *ev,
- TALLOC_CTX *mem_ctx,
- struct iocb *iocb,
- event_aio_handler_t handler,
- void *private_data)
+static struct tevent_aio *aio_event_add_aio(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ struct iocb *iocb,
+ tevent_aio_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
{
struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data,
struct aio_event_context);
struct iocb *iocbp;
- struct aio_event *ae = talloc(mem_ctx?mem_ctx:ev, struct aio_event);
+ struct tevent_aio *ae = talloc(mem_ctx?mem_ctx:ev, struct tevent_aio);
if (ae == NULL) return NULL;
ae->event_ctx = ev;
@@ -548,20 +547,21 @@ static struct aio_event *aio_event_add_aio(struct tevent_context *ev,
return ae;
}
-static const struct event_ops aio_event_ops = {
+static const struct tevent_ops aio_event_ops = {
.context_init = aio_event_context_init,
.add_fd = aio_event_add_fd,
.add_aio = aio_event_add_aio,
- .get_fd_flags = aio_event_get_fd_flags,
+ .set_fd_close_fn= tevent_common_fd_set_close_fn,
+ .get_fd_flags = tevent_common_fd_get_flags,
.set_fd_flags = aio_event_set_fd_flags,
- .add_timer = common_event_add_timed,
- .add_signal = common_event_add_signal,
+ .add_timer = tevent_common_add_timer,
+ .add_signal = tevent_common_add_signal,
.loop_once = aio_event_loop_once,
.loop_wait = aio_event_loop_wait,
};
-bool events_aio_init(void)
+bool tevent_aio_init(void)
{
- return event_register_backend("aio", &aio_event_ops);
+ return tevent_register_backend("aio", &aio_event_ops);
}
diff --git a/lib/tevent/tevent_debug.c b/lib/tevent/tevent_debug.c
index 4fa58534b45..841446bf6c9 100644
--- a/lib/tevent/tevent_debug.c
+++ b/lib/tevent/tevent_debug.c
@@ -30,10 +30,12 @@
/*
this allows the user to choose their own debug function
*/
-int ev_set_debug(struct tevent_context *ev,
- void (*debug)(void *context, enum ev_debug_level level,
- const char *fmt, va_list ap),
- void *context)
+int tevent_set_debug(struct tevent_context *ev,
+ void (*debug)(void *context,
+ enum tevent_debug_level level,
+ const char *fmt,
+ va_list ap) PRINTF_ATTRIBUTE(3,0),
+ void *context)
{
ev->debug_ops.debug = debug;
ev->debug_ops.context = context;
@@ -43,23 +45,26 @@ int ev_set_debug(struct tevent_context *ev,
/*
debug function for ev_set_debug_stderr
*/
-void ev_debug_stderr(void *context, enum ev_debug_level level,
- const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
-void ev_debug_stderr(void *context, enum ev_debug_level level,
- const char *fmt, va_list ap)
+static void tevent_debug_stderr(void *private_data,
+ enum tevent_debug_level level,
+ const char *fmt,
+ va_list ap) PRINTF_ATTRIBUTE(3,0);
+static void tevent_debug_stderr(void *private_data,
+ enum tevent_debug_level level,
+ const char *fmt, va_list ap)
{
- if (level <= EV_DEBUG_WARNING) {
+ if (level <= TEVENT_DEBUG_WARNING) {
vfprintf(stderr, fmt, ap);
}
}
/*
convenience function to setup debug messages on stderr
- messages of level EV_DEBUG_WARNING and higher are printed
+ messages of level TEVENT_DEBUG_WARNING and higher are printed
*/
-int ev_set_debug_stderr(struct tevent_context *ev)
+int tevent_set_debug_stderr(struct tevent_context *ev)
{
- return ev_set_debug(ev, ev_debug_stderr, ev);
+ return tevent_set_debug(ev, tevent_debug_stderr, ev);
}
/*
@@ -70,7 +75,8 @@ int ev_set_debug_stderr(struct tevent_context *ev)
* Applications using the library must decide where to
* redirect debugging messages
*/
-void ev_debug(struct tevent_context *ev, enum ev_debug_level level, const char *fmt, ...)
+void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level,
+ const char *fmt, ...)
{
va_list ap;
if (ev->debug_ops.debug == NULL) {
diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c
index 1ce666462cd..38357743499 100644
--- a/lib/tevent/tevent_epoll.c
+++ b/lib/tevent/tevent_epoll.c
@@ -22,11 +22,10 @@
#include "replace.h"
#include "system/filesys.h"
-#include "system/network.h"
+#include "system/select.h"
#include "tevent.h"
#include "tevent_internal.h"
#include "tevent_util.h"
-#include <sys/epoll.h>
struct epoll_event_context {
/* a pointer back to the generic event_context */
@@ -58,19 +57,19 @@ struct epoll_event_context {
*/
static void epoll_panic(struct epoll_event_context *epoll_ev, const char *reason)
{
- ev_debug(epoll_ev->ev, EV_DEBUG_FATAL,
+ tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL,
"%s (%s) - calling abort()\n", reason, strerror(errno));
abort();
}
/*
- map from EVENT_FD_* to EPOLLIN/EPOLLOUT
+ map from TEVENT_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);
+ if (flags & TEVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
+ if (flags & TEVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
return ret;
}
@@ -116,8 +115,8 @@ static void epoll_check_reopen(struct epoll_event_context *epoll_ev)
close(epoll_ev->epoll_fd);
epoll_ev->epoll_fd = epoll_create(64);
if (epoll_ev->epoll_fd == -1) {
- ev_debug(epoll_ev->ev, EV_DEBUG_FATAL,
- "Failed to recreate epoll handle after fork\n");
+ tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL,
+ "Failed to recreate epoll handle after fork\n");
return;
}
epoll_ev->pid = getpid();
@@ -153,7 +152,7 @@ static void epoll_add_event(struct epoll_event_context *epoll_ev, struct tevent_
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) {
+ if (fde->flags & TEVENT_FD_READ) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
}
}
@@ -176,9 +175,9 @@ static void epoll_del_event(struct epoll_event_context *epoll_ev, struct tevent_
event.events = epoll_map_flags(fde->flags);
event.data.ptr = fde;
if (epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event) != 0) {
- ev_debug(epoll_ev->ev, EV_DEBUG_FATAL,
- "epoll_del_event failed! probable early close bug (%s)\n",
- strerror(errno));
+ tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL,
+ "epoll_del_event failed! probable early close bug (%s)\n",
+ strerror(errno));
}
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
}
@@ -201,7 +200,7 @@ static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct tevent_
}
/* only if we want to read we want to tell the event handler about errors */
- if (fde->flags & EVENT_FD_READ) {
+ if (fde->flags & TEVENT_FD_READ) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
}
}
@@ -209,8 +208,8 @@ static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct tevent_
static void epoll_change_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde)
{
bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
- bool want_read = (fde->flags & EVENT_FD_READ);
- bool want_write= (fde->flags & EVENT_FD_WRITE);
+ bool want_read = (fde->flags & TEVENT_FD_READ);
+ bool want_write= (fde->flags & TEVENT_FD_WRITE);
if (epoll_ev->epoll_fd == -1) return;
@@ -258,14 +257,14 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
}
if (epoll_ev->ev->num_signal_handlers &&
- common_event_check_signal(epoll_ev->ev)) {
+ tevent_common_check_signal(epoll_ev->ev)) {
return 0;
}
ret = epoll_wait(epoll_ev->epoll_fd, events, MAXEVENTS, timeout);
if (ret == -1 && errno == EINTR && epoll_ev->ev->num_signal_handlers) {
- if (common_event_check_signal(epoll_ev->ev)) {
+ if (tevent_common_check_signal(epoll_ev->ev)) {
return 0;
}
}
@@ -277,7 +276,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
if (ret == 0 && tvalp) {
/* we don't care about a possible delay here */
- common_event_loop_timer_delay(epoll_ev->ev);
+ tevent_common_loop_timer_delay(epoll_ev->ev);
return 0;
}
@@ -293,7 +292,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
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
+ * if we only wait for TEVENT_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
@@ -302,10 +301,10 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
epoll_del_event(epoll_ev, fde);
continue;
}
- flags |= EVENT_FD_READ;
+ flags |= TEVENT_FD_READ;
}
- if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ;
- if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
+ if (events[i].events & EPOLLIN) flags |= TEVENT_FD_READ;
+ if (events[i].events & EPOLLOUT) flags |= TEVENT_FD_WRITE;
if (flags) {
fde->handler(epoll_ev->ev, fde, flags, fde->private_data);
if (destruction_count != epoll_ev->destruction_count) {
@@ -358,8 +357,8 @@ static int epoll_event_fd_destructor(struct tevent_fd *fde)
epoll_del_event(epoll_ev, fde);
- if (fde->flags & EVENT_FD_AUTOCLOSE) {
- close(fde->fd);
+ if (fde->close_fn) {
+ fde->close_fn(ev, fde, fde->fd, fde->private_data);
fde->fd = -1;
}
@@ -371,9 +370,11 @@ static int epoll_event_fd_destructor(struct tevent_fd *fde)
return NULL on failure (memory allocation error)
*/
static struct tevent_fd *epoll_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags,
- event_fd_handler_t handler,
- void *private_data)
+ int fd, uint16_t flags,
+ tevent_fd_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
{
struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data,
struct epoll_event_context);
@@ -388,7 +389,10 @@ static struct tevent_fd *epoll_event_add_fd(struct tevent_context *ev, TALLOC_CT
fde->fd = fd;
fde->flags = flags;
fde->handler = handler;
+ fde->close_fn = NULL;
fde->private_data = private_data;
+ fde->handler_name = handler_name;
+ fde->location = location;
fde->additional_flags = 0;
fde->additional_data = NULL;
@@ -401,15 +405,6 @@ static struct tevent_fd *epoll_event_add_fd(struct tevent_context *ev, TALLOC_CT
return fde;
}
-
-/*
- return the fd event flags
-*/
-static uint16_t epoll_event_get_fd_flags(struct tevent_fd *fde)
-{
- return fde->flags;
-}
-
/*
set the fd event flags
*/
@@ -439,7 +434,7 @@ static int epoll_event_loop_once(struct tevent_context *ev)
struct epoll_event_context);
struct timeval tval;
- tval = common_event_loop_timer_delay(ev);
+ tval = tevent_common_loop_timer_delay(ev);
if (ev_timeval_is_zero(&tval)) {
return 0;
}
@@ -465,18 +460,19 @@ static int epoll_event_loop_wait(struct tevent_context *ev)
return 0;
}
-static const struct event_ops epoll_event_ops = {
+static const struct tevent_ops epoll_event_ops = {
.context_init = epoll_event_context_init,
.add_fd = epoll_event_add_fd,
- .get_fd_flags = epoll_event_get_fd_flags,
+ .set_fd_close_fn= tevent_common_fd_set_close_fn,
+ .get_fd_flags = tevent_common_fd_get_flags,
.set_fd_flags = epoll_event_set_fd_flags,
- .add_timer = common_event_add_timed,
- .add_signal = common_event_add_signal,
+ .add_timer = tevent_common_add_timer,
+ .add_signal = tevent_common_add_signal,
.loop_once = epoll_event_loop_once,
.loop_wait = epoll_event_loop_wait,
};
-bool events_epoll_init(void)
+bool tevent_epoll_init(void)
{
- return event_register_backend("epoll", &epoll_event_ops);
+ return tevent_register_backend("epoll", &epoll_event_ops);
}
diff --git a/lib/tevent/tevent_fd.c b/lib/tevent/tevent_fd.c
new file mode 100644
index 00000000000..d450e2168de
--- /dev/null
+++ b/lib/tevent/tevent_fd.c
@@ -0,0 +1,42 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ common events code for fd events
+
+ Copyright (C) Stefan Metzmacher 2009
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "tevent.h"
+#include "tevent_internal.h"
+#include "tevent_util.h"
+
+uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde)
+{
+ return fde->flags;
+}
+
+void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags)
+{
+ if (fde->flags == flags) return;
+ fde->flags = flags;
+}
+
+void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
+ tevent_fd_close_fn_t close_fn)
+{
+ fde->close_fn = close_fn;
+}
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index 2d6909da366..f29e9c62f5b 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -30,7 +30,11 @@ struct tevent_ops {
TALLOC_CTX *mem_ctx,
int fd, uint16_t flags,
tevent_fd_handler_t handler,
- void *private_data);
+ void *private_data,
+ const char *handler_name,
+ const char *location);
+ void (*set_fd_close_fn)(struct tevent_fd *fde,
+ tevent_fd_close_fn_t close_fn);
uint16_t (*get_fd_flags)(struct tevent_fd *fde);
void (*set_fd_flags)(struct tevent_fd *fde, uint16_t flags);
@@ -39,19 +43,25 @@ struct tevent_ops {
TALLOC_CTX *mem_ctx,
struct timeval next_event,
tevent_timer_handler_t handler,
- void *private_data);
+ void *private_data,
+ const char *handler_name,
+ const char *location);
/* disk aio event functions */
struct tevent_aio *(*add_aio)(struct tevent_context *ev,
TALLOC_CTX *mem_ctx,
struct iocb *iocb,
tevent_aio_handler_t handler,
- void *private_data);
+ void *private_data,
+ const char *handler_name,
+ const char *location);
/* signal functions */
struct tevent_signal *(*add_signal)(struct tevent_context *ev,
TALLOC_CTX *mem_ctx,
int signum, int sa_flags,
tevent_signal_handler_t handler,
- void *private_data);
+ void *private_data,
+ const char *handler_name,
+ const char *location);
/* loop functions */
int (*loop_once)(struct tevent_context *ev);
@@ -62,10 +72,14 @@ struct tevent_fd {
struct tevent_fd *prev, *next;
struct tevent_context *event_ctx;
int fd;
- uint16_t flags; /* see EVENT_FD_* flags */
+ uint16_t flags; /* see TEVENT_FD_* flags */
tevent_fd_handler_t handler;
+ tevent_fd_close_fn_t close_fn;
/* this is private for the specific handler */
void *private_data;
+ /* this is for debugging only! */
+ const char *handler_name;
+ const char *location;
/* this is private for the events_ops implementation */
uint16_t additional_flags;
void *additional_data;
@@ -78,6 +92,9 @@ struct tevent_timer {
tevent_timer_handler_t handler;
/* this is private for the specific handler */
void *private_data;
+ /* this is for debugging only! */
+ const char *handler_name;
+ const char *location;
/* this is private for the events_ops implementation */
void *additional_data;
};
@@ -85,28 +102,26 @@ struct tevent_timer {
struct tevent_signal {
struct tevent_signal *prev, *next;
struct tevent_context *event_ctx;
- tevent_signal_handler_t handler;
- void *private_data;
int signum;
int sa_flags;
+ tevent_signal_handler_t handler;
+ /* this is private for the specific handler */
+ void *private_data;
+ /* this is for debugging only! */
+ const char *handler_name;
+ const char *location;
+ /* this is private for the events_ops implementation */
+ void *additional_data;
};
-/* DEBUG */
-enum ev_debug_level {EV_DEBUG_FATAL, EV_DEBUG_ERROR,
- EV_DEBUG_WARNING, EV_DEBUG_TRACE};
-
-struct ev_debug_ops {
- void (*debug)(void *context, enum ev_debug_level level,
+struct tevent_debug_ops {
+ void (*debug)(void *context, enum tevent_debug_level level,
const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
void *context;
};
-int ev_set_debug(struct tevent_context *ev,
- void (*debug)(void *context, enum ev_debug_level level,
- const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0),
- void *context);
-int ev_set_debug_stderr(struct tevent_context *ev);
-void ev_debug(struct tevent_context *ev, enum ev_debug_level level, const char *fmt, ...);
+void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level,
+ const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
/* aio event is private to the aio backend */
struct tevent_aio;
@@ -128,34 +143,42 @@ struct tevent_context {
struct tevent_fd *pipe_fde;
/* debugging operations */
- struct ev_debug_ops debug_ops;
+ struct tevent_debug_ops debug_ops;
};
-bool event_register_backend(const char *name, const struct tevent_ops *ops);
+bool tevent_register_backend(const char *name, const struct tevent_ops *ops);
+
+void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
+ tevent_fd_close_fn_t close_fn);
+uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde);
+void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
bool ev_timeval_is_zero(const struct timeval *tv);
-struct tevent_timer *common_event_add_timed(struct tevent_context *,
- TALLOC_CTX *,
- struct timeval,
- tevent_timer_handler_t,
- void *);
-struct timeval common_event_loop_timer_delay(struct tevent_context *);
-
-struct tevent_signal *common_event_add_signal(struct tevent_context *ev,
- TALLOC_CTX *mem_ctx,
- int signum,
- int sa_flags,
- tevent_signal_handler_t handler,
- void *private_data);
-int common_event_check_signal(struct tevent_context *ev);
-
-
-bool events_standard_init(void);
-bool events_select_init(void);
-#if HAVE_EVENTS_EPOLL
-bool events_epoll_init(void);
+struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ struct timeval next_event,
+ tevent_timer_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location);
+struct timeval tevent_common_loop_timer_delay(struct tevent_context *);
+
+struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ int signum,
+ int sa_flags,
+ tevent_signal_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location);
+int tevent_common_check_signal(struct tevent_context *ev);
+
+bool tevent_standard_init(void);
+bool tevent_select_init(void);
+#ifdef HAVE_EPOLL
+bool tevent_epoll_init(void);
#endif
-#if HAVE_LINUX_AIO
-bool events_aio_init(void);
+#ifdef HAVE_LINUX_AIO
+bool tevent_aio_init(void);
#endif
diff --git a/lib/tevent/tevent_select.c b/lib/tevent/tevent_select.c
index 3e72ce4943a..cf4453f64fa 100644
--- a/lib/tevent/tevent_select.c
+++ b/lib/tevent/tevent_select.c
@@ -103,8 +103,8 @@ static int select_event_fd_destructor(struct tevent_fd *fde)
DLIST_REMOVE(select_ev->fd_events, fde);
select_ev->destruction_count++;
- if (fde->flags & EVENT_FD_AUTOCLOSE) {
- close(fde->fd);
+ if (fde->close_fn) {
+ fde->close_fn(ev, fde, fde->fd, fde->private_data);
fde->fd = -1;
}
@@ -116,9 +116,11 @@ static int select_event_fd_destructor(struct tevent_fd *fde)
return NULL on failure (memory allocation error)
*/
static struct tevent_fd *select_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags,
- event_fd_handler_t handler,
- void *private_data)
+ int fd, uint16_t flags,
+ tevent_fd_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
{
struct select_event_context *select_ev = talloc_get_type(ev->additional_data,
struct select_event_context);
@@ -131,7 +133,10 @@ static struct tevent_fd *select_event_add_fd(struct tevent_context *ev, TALLOC_C
fde->fd = fd;
fde->flags = flags;
fde->handler = handler;
+ fde->close_fn = NULL;
fde->private_data = private_data;
+ fde->handler_name = handler_name;
+ fde->location = location;
fde->additional_flags = 0;
fde->additional_data = NULL;
@@ -144,31 +149,6 @@ static struct tevent_fd *select_event_add_fd(struct tevent_context *ev, TALLOC_C
return fde;
}
-
-/*
- return the fd event flags
-*/
-static uint16_t select_event_get_fd_flags(struct tevent_fd *fde)
-{
- return fde->flags;
-}
-
-/*
- set the fd event flags
-*/
-static void select_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
-{
- struct tevent_context *ev;
- struct select_event_context *select_ev;
-
- if (fde->flags == flags) return;
-
- ev = fde->event_ctx;
- select_ev = talloc_get_type(ev->additional_data, struct select_event_context);
-
- fde->flags = flags;
-}
-
/*
event loop handling using select()
*/
@@ -189,16 +169,16 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
/* setup any fd events */
for (fde = select_ev->fd_events; fde; fde = fde->next) {
- if (fde->flags & EVENT_FD_READ) {
+ if (fde->flags & TEVENT_FD_READ) {
FD_SET(fde->fd, &r_fds);
}
- if (fde->flags & EVENT_FD_WRITE) {
+ if (fde->flags & TEVENT_FD_WRITE) {
FD_SET(fde->fd, &w_fds);
}
}
if (select_ev->ev->num_signal_handlers &&
- common_event_check_signal(select_ev->ev)) {
+ tevent_common_check_signal(select_ev->ev)) {
return 0;
}
@@ -206,7 +186,7 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
if (selrtn == -1 && errno == EINTR &&
select_ev->ev->num_signal_handlers) {
- common_event_check_signal(select_ev->ev);
+ tevent_common_check_signal(select_ev->ev);
return 0;
}
@@ -216,15 +196,15 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
made readable and that should have removed
the event, so this must be a bug. This is a
fatal error. */
- ev_debug(select_ev->ev, EV_DEBUG_FATAL,
- "ERROR: EBADF on select_event_loop_once\n");
+ tevent_debug(select_ev->ev, TEVENT_DEBUG_FATAL,
+ "ERROR: EBADF on select_event_loop_once\n");
select_ev->exit_code = EBADF;
return -1;
}
if (selrtn == 0 && tvalp) {
/* we don't care about a possible delay here */
- common_event_loop_timer_delay(select_ev->ev);
+ tevent_common_loop_timer_delay(select_ev->ev);
return 0;
}
@@ -235,8 +215,8 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
for (fde = select_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 (FD_ISSET(fde->fd, &r_fds)) flags |= TEVENT_FD_READ;
+ if (FD_ISSET(fde->fd, &w_fds)) flags |= TEVENT_FD_WRITE;
if (flags) {
fde->handler(select_ev->ev, fde, flags, fde->private_data);
if (destruction_count != select_ev->destruction_count) {
@@ -258,7 +238,7 @@ static int select_event_loop_once(struct tevent_context *ev)
struct select_event_context);
struct timeval tval;
- tval = common_event_loop_timer_delay(ev);
+ tval = tevent_common_loop_timer_delay(ev);
if (ev_timeval_is_zero(&tval)) {
return 0;
}
@@ -284,19 +264,19 @@ static int select_event_loop_wait(struct tevent_context *ev)
return select_ev->exit_code;
}
-static const struct event_ops select_event_ops = {
+static const struct tevent_ops select_event_ops = {
.context_init = select_event_context_init,
.add_fd = select_event_add_fd,
- .get_fd_flags = select_event_get_fd_flags,
- .set_fd_flags = select_event_set_fd_flags,
- .add_timer = common_event_add_timed,
- .add_signal = common_event_add_signal,
+ .set_fd_close_fn= tevent_common_fd_set_close_fn,
+ .get_fd_flags = tevent_common_fd_get_flags,
+ .set_fd_flags = tevent_common_fd_set_flags,
+ .add_timer = tevent_common_add_timer,
+ .add_signal = tevent_common_add_signal,
.loop_once = select_event_loop_once,
.loop_wait = select_event_loop_wait,
};
-bool events_select_init(void)
+bool tevent_select_init(void)
{
- return event_register_backend("select", &select_event_ops);
+ return tevent_register_backend("select", &select_event_ops);
}
-
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index bb50480dd7f..031845927b9 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -19,10 +19,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <signal.h>
#include "replace.h"
#include "system/filesys.h"
-#include "system/select.h"
+#include "system/wait.h"
#include "tevent.h"
#include "tevent_internal.h"
#include "tevent_util.h"
@@ -46,7 +45,7 @@ struct sigcounter {
the poor design of signals means that this table must be static global
*/
static struct sig_state {
- struct signal_event *sig_handlers[NUM_SIGNALS+1];
+ struct tevent_signal *sig_handlers[NUM_SIGNALS+1];
struct sigaction *oldact[NUM_SIGNALS+1];
struct sigcounter signal_count[NUM_SIGNALS+1];
struct sigcounter got_signal;
@@ -108,7 +107,7 @@ static void signal_handler_info(int signum, siginfo_t *info, void *uctx)
/*
destroy a signal event
*/
-static int signal_event_destructor(struct signal_event *se)
+static int tevent_signal_destructor(struct tevent_signal *se)
{
se->event_ctx->num_signal_handlers--;
DLIST_REMOVE(sig_state->sig_handlers[se->signum], se);
@@ -141,14 +140,16 @@ static void signal_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde
add a signal event
return NULL on failure (memory allocation error)
*/
-struct signal_event *common_event_add_signal(struct tevent_context *ev,
- TALLOC_CTX *mem_ctx,
- int signum,
- int sa_flags,
- event_signal_handler_t handler,
- void *private_data)
+struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ int signum,
+ int sa_flags,
+ tevent_signal_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
{
- struct signal_event *se;
+ struct tevent_signal *se;
if (signum >= NUM_SIGNALS) {
return NULL;
@@ -163,15 +164,18 @@ struct signal_event *common_event_add_signal(struct tevent_context *ev,
}
}
- se = talloc(mem_ctx?mem_ctx:ev, struct signal_event);
+ se = talloc(mem_ctx?mem_ctx:ev, struct tevent_signal);
if (se == NULL) return NULL;
se->event_ctx = ev;
- se->handler = handler;
- se->private_data = private_data;
se->signum = signum;
se->sa_flags = sa_flags;
-
+ se->handler = handler;
+ se->private_data = private_data;
+ se->handler_name = handler_name;
+ se->location = location;
+ se->additional_data = NULL;
+
/* Ensure, no matter the destruction order, that we always have a handle on the global sig_state */
if (!talloc_reference(se, sig_state)) {
return NULL;
@@ -209,7 +213,7 @@ struct signal_event *common_event_add_signal(struct tevent_context *ev,
DLIST_ADD(sig_state->sig_handlers[signum], se);
- talloc_set_destructor(se, signal_event_destructor);
+ talloc_set_destructor(se, tevent_signal_destructor);
/* we need to setup the pipe hack handler if not already
setup */
@@ -220,8 +224,8 @@ struct signal_event *common_event_add_signal(struct tevent_context *ev,
ev_set_blocking(sig_state->pipe_hack[0], false);
ev_set_blocking(sig_state->pipe_hack[1], false);
}
- ev->pipe_fde = event_add_fd(ev, ev, sig_state->pipe_hack[0],
- EVENT_FD_READ, signal_pipe_handler, NULL);
+ ev->pipe_fde = tevent_add_fd(ev, ev, sig_state->pipe_hack[0],
+ TEVENT_FD_READ, signal_pipe_handler, NULL);
}
ev->num_signal_handlers++;
@@ -233,7 +237,7 @@ struct signal_event *common_event_add_signal(struct tevent_context *ev,
check if a signal is pending
return != 0 if a signal was pending
*/
-int common_event_check_signal(struct tevent_context *ev)
+int tevent_common_check_signal(struct tevent_context *ev)
{
int i;
@@ -242,7 +246,7 @@ int common_event_check_signal(struct tevent_context *ev)
}
for (i=0;i<NUM_SIGNALS+1;i++) {
- struct signal_event *se, *next;
+ struct tevent_signal *se, *next;
struct sigcounter counter = sig_state->signal_count[i];
uint32_t count = sig_count(counter);
diff --git a/lib/tevent/tevent_standard.c b/lib/tevent/tevent_standard.c
index 1c99408b8df..2a292a4c396 100644
--- a/lib/tevent/tevent_standard.c
+++ b/lib/tevent/tevent_standard.c
@@ -29,8 +29,7 @@
#include "replace.h"
#include "system/filesys.h"
-#include "system/network.h"
-#include "system/select.h" /* needed for HAVE_EVENTS_EPOLL */
+#include "system/select.h"
#include "tevent.h"
#include "tevent_util.h"
#include "tevent_internal.h"
@@ -64,29 +63,29 @@ struct std_event_context {
};
/* use epoll if it is available */
-#if HAVE_EVENTS_EPOLL
+#if HAVE_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)
{
- ev_debug(std_ev->ev, EV_DEBUG_FATAL,
- "%s (%s) - falling back to select()\n",
- reason, strerror(errno));
+ tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL,
+ "%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
+ map from TEVENT_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);
+ if (flags & TEVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
+ if (flags & TEVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
return ret;
}
@@ -130,8 +129,8 @@ static void epoll_check_reopen(struct std_event_context *std_ev)
close(std_ev->epoll_fd);
std_ev->epoll_fd = epoll_create(64);
if (std_ev->epoll_fd == -1) {
- ev_debug(std_ev->ev, EV_DEBUG_FATAL,
- "Failed to recreate epoll handle after fork\n");
+ tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL,
+ "Failed to recreate epoll handle after fork\n");
return;
}
std_ev->pid = getpid();
@@ -166,7 +165,7 @@ static void epoll_add_event(struct std_event_context *std_ev, struct tevent_fd *
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) {
+ if (fde->flags & TEVENT_FD_READ) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
}
}
@@ -209,7 +208,7 @@ static void epoll_mod_event(struct std_event_context *std_ev, struct tevent_fd *
}
/* only if we want to read we want to tell the event handler about errors */
- if (fde->flags & EVENT_FD_READ) {
+ if (fde->flags & TEVENT_FD_READ) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
}
}
@@ -217,8 +216,8 @@ static void epoll_mod_event(struct std_event_context *std_ev, struct tevent_fd *
static void epoll_change_event(struct std_event_context *std_ev, struct tevent_fd *fde)
{
bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
- bool want_read = (fde->flags & EVENT_FD_READ);
- bool want_write= (fde->flags & EVENT_FD_WRITE);
+ bool want_read = (fde->flags & TEVENT_FD_READ);
+ bool want_write= (fde->flags & TEVENT_FD_WRITE);
if (std_ev->epoll_fd == -1) return;
@@ -266,14 +265,14 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
}
if (std_ev->ev->num_signal_handlers &&
- common_event_check_signal(std_ev->ev)) {
+ tevent_common_check_signal(std_ev->ev)) {
return 0;
}
ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
if (ret == -1 && errno == EINTR && std_ev->ev->num_signal_handlers) {
- if (common_event_check_signal(std_ev->ev)) {
+ if (tevent_common_check_signal(std_ev->ev)) {
return 0;
}
}
@@ -285,7 +284,7 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
if (ret == 0 && tvalp) {
/* we don't care about a possible delay here */
- common_event_loop_timer_delay(std_ev->ev);
+ tevent_common_loop_timer_delay(std_ev->ev);
return 0;
}
@@ -301,7 +300,7 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
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
+ * if we only wait for TEVENT_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
@@ -310,10 +309,10 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
epoll_del_event(std_ev, fde);
continue;
}
- flags |= EVENT_FD_READ;
+ flags |= TEVENT_FD_READ;
}
- if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ;
- if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
+ if (events[i].events & EPOLLIN) flags |= TEVENT_FD_READ;
+ if (events[i].events & EPOLLOUT) flags |= TEVENT_FD_WRITE;
if (flags) {
fde->handler(std_ev->ev, fde, flags, fde->private_data);
if (destruction_count != std_ev->destruction_count) {
@@ -392,8 +391,8 @@ static int std_event_fd_destructor(struct tevent_fd *fde)
epoll_del_event(std_ev, fde);
- if (fde->flags & EVENT_FD_AUTOCLOSE) {
- close(fde->fd);
+ if (fde->close_fn) {
+ fde->close_fn(ev, fde, fde->fd, fde->private_data);
fde->fd = -1;
}
@@ -405,9 +404,11 @@ static int std_event_fd_destructor(struct tevent_fd *fde)
return NULL on failure (memory allocation error)
*/
static struct tevent_fd *std_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags,
- event_fd_handler_t handler,
- void *private_data)
+ int fd, uint16_t flags,
+ tevent_fd_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
{
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
struct std_event_context);
@@ -422,7 +423,10 @@ static struct tevent_fd *std_event_add_fd(struct tevent_context *ev, TALLOC_CTX
fde->fd = fd;
fde->flags = flags;
fde->handler = handler;
+ fde->close_fn = NULL;
fde->private_data = private_data;
+ fde->handler_name = handler_name;
+ fde->location = location;
fde->additional_flags = 0;
fde->additional_data = NULL;
@@ -438,15 +442,6 @@ static struct tevent_fd *std_event_add_fd(struct tevent_context *ev, TALLOC_CTX
return fde;
}
-
-/*
- return the fd event flags
-*/
-static uint16_t std_event_get_fd_flags(struct tevent_fd *fde)
-{
- return fde->flags;
-}
-
/*
set the fd event flags
*/
@@ -487,16 +482,16 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
/* setup any fd events */
for (fde = std_ev->fd_events; fde; fde = fde->next) {
- if (fde->flags & EVENT_FD_READ) {
+ if (fde->flags & TEVENT_FD_READ) {
FD_SET(fde->fd, &r_fds);
}
- if (fde->flags & EVENT_FD_WRITE) {
+ if (fde->flags & TEVENT_FD_WRITE) {
FD_SET(fde->fd, &w_fds);
}
}
if (std_ev->ev->num_signal_handlers &&
- common_event_check_signal(std_ev->ev)) {
+ tevent_common_check_signal(std_ev->ev)) {
return 0;
}
@@ -504,7 +499,7 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
if (selrtn == -1 && errno == EINTR &&
std_ev->ev->num_signal_handlers) {
- common_event_check_signal(std_ev->ev);
+ tevent_common_check_signal(std_ev->ev);
return 0;
}
@@ -514,15 +509,15 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
made readable and that should have removed
the event, so this must be a bug. This is a
fatal error. */
- ev_debug(std_ev->ev, EV_DEBUG_FATAL,
- "ERROR: EBADF on std_event_loop_once\n");
+ tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL,
+ "ERROR: EBADF on std_event_loop_once\n");
std_ev->exit_code = EBADF;
return -1;
}
if (selrtn == 0 && tvalp) {
/* we don't care about a possible delay here */
- common_event_loop_timer_delay(std_ev->ev);
+ tevent_common_loop_timer_delay(std_ev->ev);
return 0;
}
@@ -533,8 +528,8 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
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 (FD_ISSET(fde->fd, &r_fds)) flags |= TEVENT_FD_READ;
+ if (FD_ISSET(fde->fd, &w_fds)) flags |= TEVENT_FD_WRITE;
if (flags) {
fde->handler(std_ev->ev, fde, flags, fde->private_data);
if (destruction_count != std_ev->destruction_count) {
@@ -556,7 +551,7 @@ static int std_event_loop_once(struct tevent_context *ev)
struct std_event_context);
struct timeval tval;
- tval = common_event_loop_timer_delay(ev);
+ tval = tevent_common_loop_timer_delay(ev);
if (ev_timeval_is_zero(&tval)) {
return 0;
}
@@ -588,20 +583,21 @@ static int std_event_loop_wait(struct tevent_context *ev)
return std_ev->exit_code;
}
-static const struct event_ops std_event_ops = {
+static const struct tevent_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_close_fn= tevent_common_fd_set_close_fn,
+ .get_fd_flags = tevent_common_fd_get_flags,
.set_fd_flags = std_event_set_fd_flags,
- .add_timer = common_event_add_timed,
- .add_signal = common_event_add_signal,
+ .add_timer = tevent_common_add_timer,
+ .add_signal = tevent_common_add_signal,
.loop_once = std_event_loop_once,
.loop_wait = std_event_loop_wait,
};
-bool events_standard_init(void)
+bool tevent_standard_init(void)
{
- return event_register_backend("standard", &std_event_ops);
+ return tevent_register_backend("standard", &std_event_ops);
}
diff --git a/lib/tevent/tevent_timed.c b/lib/tevent/tevent_timed.c
index ce3fc8eb006..dadd3604164 100644
--- a/lib/tevent/tevent_timed.c
+++ b/lib/tevent/tevent_timed.c
@@ -20,11 +20,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sys/time.h>
-#include <time.h>
#include "replace.h"
-#include "system/filesys.h"
-#include "system/select.h"
+#include "system/time.h"
#include "tevent.h"
#include "tevent_internal.h"
#include "tevent_util.h"
@@ -109,7 +106,7 @@ bool ev_timeval_is_zero(const struct timeval *tv)
/*
destroy a timed event
*/
-static int common_event_timed_destructor(struct tevent_timer *te)
+static int tevent_common_timed_destructor(struct tevent_timer *te)
{
struct tevent_context *ev = talloc_get_type(te->event_ctx,
struct tevent_context);
@@ -117,7 +114,7 @@ static int common_event_timed_destructor(struct tevent_timer *te)
return 0;
}
-static int common_event_timed_deny_destructor(struct tevent_timer *te)
+static int tevent_common_timed_deny_destructor(struct tevent_timer *te)
{
return -1;
}
@@ -126,10 +123,12 @@ static int common_event_timed_deny_destructor(struct tevent_timer *te)
add a timed event
return NULL on failure (memory allocation error)
*/
-struct tevent_timer *common_event_add_timed(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
- struct timeval next_event,
- event_timed_handler_t handler,
- void *private_data)
+struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
+ struct timeval next_event,
+ tevent_timer_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
{
struct tevent_timer *te, *last_te, *cur_te;
@@ -140,6 +139,8 @@ struct tevent_timer *common_event_add_timed(struct tevent_context *ev, TALLOC_CT
te->next_event = next_event;
te->handler = handler;
te->private_data = private_data;
+ te->handler_name = handler_name;
+ te->location = location;
te->additional_data = NULL;
/* keep the list ordered */
@@ -155,7 +156,7 @@ struct tevent_timer *common_event_add_timed(struct tevent_context *ev, TALLOC_CT
DLIST_ADD_AFTER(ev->timer_events, te, last_te);
- talloc_set_destructor(te, common_event_timed_destructor);
+ talloc_set_destructor(te, tevent_common_timed_destructor);
return te;
}
@@ -166,7 +167,7 @@ struct tevent_timer *common_event_add_timed(struct tevent_context *ev, TALLOC_CT
return the delay untill the next timed event,
or zero if a timed event was triggered
*/
-struct timeval common_event_loop_timer_delay(struct tevent_context *ev)
+struct timeval tevent_common_loop_timer_delay(struct tevent_context *ev)
{
struct timeval current_time = ev_timeval_zero();
struct tevent_timer *te = ev->timer_events;
@@ -203,7 +204,7 @@ struct timeval common_event_loop_timer_delay(struct tevent_context *ev)
*/
/* deny the handler to free the event */
- talloc_set_destructor(te, common_event_timed_deny_destructor);
+ talloc_set_destructor(te, tevent_common_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
diff --git a/librpc/gen_ndr/named_pipe_auth.h b/librpc/gen_ndr/named_pipe_auth.h
index 87d4bfd712f..7ca7444c927 100644
--- a/librpc/gen_ndr/named_pipe_auth.h
+++ b/librpc/gen_ndr/named_pipe_auth.h
@@ -19,6 +19,7 @@ struct named_pipe_auth_req {
}/* [gensize,public] */;
union named_pipe_auth_rep_info {
+ int _dummy_element;
}/* [switch_type(uint32)] */;
struct named_pipe_auth_rep {
diff --git a/librpc/ndr/ndr_basic.c b/librpc/ndr/ndr_basic.c
index 921af15daeb..97f75051b7e 100644
--- a/librpc/ndr/ndr_basic.c
+++ b/librpc/ndr/ndr_basic.c
@@ -757,7 +757,7 @@ _PUBLIC_ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
ndr->depth++;
for (i=0;i<count;i++) {
char *idx=NULL;
- if (asprintf(&idx, "[%d]", i) == -1) {
+ if (asprintf(&idx, "[%d]", i) != -1) {
ndr_print_uint8(ndr, idx, data[i]);
free(idx);
}
diff --git a/packaging/RHEL/samba.spec.tmpl b/packaging/RHEL/samba.spec.tmpl
index 92030fcd6b7..f674e8386c9 100644
--- a/packaging/RHEL/samba.spec.tmpl
+++ b/packaging/RHEL/samba.spec.tmpl
@@ -178,12 +178,6 @@ fi
make CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE" %{?_smp_mflags} \
all modules pam_smbpass
-## build the cifs fs mount helper
-cd client
-gcc -o mount.cifs $RPM_OPT_FLAGS -D_GNU_SOURCE -Wall -D_GNU_SOURCE -D_LARGEFILE64_SOURCE mount.cifs.c
-gcc -o umount.cifs $RPM_OPT_FLAGS -D_GNU_SOURCE -Wall -D_GNU_SOURCE -D_LARGEFILE64_SOURCE umount.cifs.c
-cd ..
-
# Remove some permission bits to avoid to many dependencies
cd ..
find examples docs -type f | xargs -r chmod -x
@@ -238,8 +232,8 @@ install -m644 setup/samba.pamd $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/samba
install -m755 setup/smbprint $RPM_BUILD_ROOT%{_bindir}
install -m644 setup/smbusers $RPM_BUILD_ROOT%{_sysconfdir}/samba/smbusers
install -m644 setup/smb.conf $RPM_BUILD_ROOT%{_sysconfdir}/samba/smb.conf
-install -m755 source/client/mount.cifs $RPM_BUILD_ROOT/sbin/mount.cifs
-install -m755 source/client/umount.cifs $RPM_BUILD_ROOT/sbin/umount.cifs
+install -m755 source/bin/mount.cifs $RPM_BUILD_ROOT/sbin/mount.cifs
+install -m755 source/bin/umount.cifs $RPM_BUILD_ROOT/sbin/umount.cifs
install -m755 source/script/mksmbpasswd.sh $RPM_BUILD_ROOT%{_bindir}
/bin/rm $RPM_BUILD_ROOT%{_sbindir}/*mount.cifs
diff --git a/pidl/lib/Parse/Pidl/Samba4/Header.pm b/pidl/lib/Parse/Pidl/Samba4/Header.pm
index 94e1efbfe49..0411466c825 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Header.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Header.pm
@@ -183,14 +183,20 @@ sub HeaderUnion($$;$)
return if (not defined($union->{ELEMENTS}));
pidl " {\n";
$tab_depth++;
+ my $needed = 0;
foreach my $e (@{$union->{ELEMENTS}}) {
if ($e->{TYPE} ne "EMPTY") {
if (! defined $done{$e->{NAME}}) {
HeaderElement($e);
}
$done{$e->{NAME}} = 1;
+ $needed++;
}
}
+ if (!$needed) {
+ # sigh - some compilers don't like empty structures
+ pidl tabs()."int _dummy_element;\n";
+ }
$tab_depth--;
pidl "}";
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 49f576f507c..c13f5ae20a8 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -930,6 +930,7 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta
SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \
$(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
+ lib/wb_reqtrans.o lib/wbclient.o \
$(LIBNDR_GEN_OBJ0)
MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
@@ -1029,7 +1030,6 @@ IDMAP_ADEX_OBJ = \
WINBINDD_OBJ1 = \
winbindd/winbindd.o \
- winbindd/winbindd_reqtrans.o \
winbindd/winbindd_user.o \
winbindd/winbindd_group.o \
winbindd/winbindd_util.o \
diff --git a/source3/autogen.sh b/source3/autogen.sh
index 61316a8f70c..1a33eb22cc4 100755
--- a/source3/autogen.sh
+++ b/source3/autogen.sh
@@ -4,11 +4,11 @@
while true; do
case $1 in
- (--version-file)
+ --version-file)
VERSION_FILE=$2
shift 2
;;
- (*)
+ *)
break
;;
esac
diff --git a/source3/client/client.c b/source3/client/client.c
index c63921aa1af..529f21ab302 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -78,6 +78,7 @@ static bool showacls = false;
bool lowercase = false;
static struct sockaddr_storage dest_ss;
+static char dest_ss_str[INET6_ADDRSTRLEN];
#define SEPARATORS " \t\n\r"
@@ -4043,7 +4044,8 @@ static int process_command_string(const char *cmd_in)
/* establish the connection if not already */
if (!cli) {
- cli = cli_cm_open(talloc_tos(), NULL, desthost,
+ cli = cli_cm_open(talloc_tos(), NULL,
+ have_ip ? dest_ss_str : desthost,
service, true, smb_encrypt);
if (!cli) {
return 1;
@@ -4508,7 +4510,8 @@ static int process(const char *base_directory)
int rc = 0;
cli = cli_cm_open(talloc_tos(), NULL,
- desthost, service, true, smb_encrypt);
+ have_ip ? dest_ss_str : desthost,
+ service, true, smb_encrypt);
if (!cli) {
return 1;
}
@@ -4586,7 +4589,8 @@ static int do_tar_op(const char *base_directory)
/* do we already have a connection? */
if (!cli) {
cli = cli_cm_open(talloc_tos(), NULL,
- desthost, service, true, smb_encrypt);
+ have_ip ? dest_ss_str : desthost,
+ service, true, smb_encrypt);
if (!cli)
return 1;
}
@@ -4792,8 +4796,7 @@ static int do_message_op(struct user_auth_info *auth_info)
exit(1);
}
have_ip = true;
-
- cli_cm_set_dest_ss(&dest_ss);
+ print_sockaddr(dest_ss_str, sizeof(dest_ss_str), &dest_ss);
}
break;
case 'E':
diff --git a/source3/include/async_req.h b/source3/include/async_req.h
index 14a30696c4d..1b8dbf33468 100644
--- a/source3/include/async_req.h
+++ b/source3/include/async_req.h
@@ -97,13 +97,6 @@ struct async_req {
NTSTATUS status;
/**
- * @brief The event context we are using
- *
- * The event context that this async request works on.
- */
- struct event_context *event_ctx;
-
- /**
* @brief What to do on completion
*
* This is used for the user of an async request, fn is called when
@@ -122,7 +115,7 @@ struct async_req {
} async;
};
-struct async_req *async_req_new(TALLOC_CTX *mem_ctx, struct event_context *ev);
+struct async_req *async_req_new(TALLOC_CTX *mem_ctx);
char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req);
@@ -130,7 +123,8 @@ void async_req_done(struct async_req *req);
void async_req_error(struct async_req *req, NTSTATUS status);
-bool async_post_status(struct async_req *req, NTSTATUS status);
+bool async_post_status(struct async_req *req, struct event_context *ev,
+ NTSTATUS status);
bool async_req_nomem(const void *p, struct async_req *req);
@@ -138,4 +132,22 @@ bool async_req_is_error(struct async_req *req, NTSTATUS *status);
NTSTATUS async_req_simple_recv(struct async_req *req);
+bool async_req_set_timeout(struct async_req *req, struct event_context *ev,
+ struct timeval to);
+
+struct async_req *async_wait_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct timeval to);
+
+NTSTATUS async_wait_recv(struct async_req *req);
+
+struct async_req_queue;
+
+struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx);
+
+bool async_req_enqueue(struct async_req_queue *queue,
+ struct event_context *ev,
+ struct async_req *req,
+ void (*trigger)(struct async_req *req));
+
#endif
diff --git a/source3/include/async_sock.h b/source3/include/async_sock.h
index f0cd5fdaa4e..c6f95d64d55 100644
--- a/source3/include/async_sock.h
+++ b/source3/include/async_sock.h
@@ -24,7 +24,7 @@
ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno);
size_t async_syscall_result_size_t(struct async_req *req, int *perrno);
-ssize_t async_syscall_result_int(struct async_req *req, int *perrno);
+int async_syscall_result_int(struct async_req *req, int *perrno);
struct async_req *async_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
int fd, const void *buffer, size_t length,
@@ -32,9 +32,11 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct event_context *ev,
int fd, void *buffer, size_t length,
int flags);
-struct async_req *async_connect(TALLOC_CTX *mem_ctx, struct event_context *ev,
- int fd, const struct sockaddr *address,
- socklen_t address_len);
+struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ int fd, const struct sockaddr *address,
+ socklen_t address_len);
+NTSTATUS async_connect_recv(struct async_req *req, int *perrno);
struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
int fd, const void *buffer, size_t length,
diff --git a/source3/include/packet.h b/source3/include/packet.h
index 05974da8fc5..03331da7503 100644
--- a/source3/include/packet.h
+++ b/source3/include/packet.h
@@ -44,12 +44,14 @@ NTSTATUS packet_fd_read_sync(struct packet_context *ctx);
* Handle an incoming packet:
* Return False if none is available
* Otherwise return True and store the callback result in *status
+ * Callback must either talloc_move or talloc_free buf
*/
bool packet_handler(struct packet_context *ctx,
- bool (*full_req)(const DATA_BLOB *data,
+ bool (*full_req)(const uint8_t *buf,
+ size_t available,
size_t *length,
void *private_data),
- NTSTATUS (*callback)(const DATA_BLOB *data,
+ NTSTATUS (*callback)(uint8_t *buf, size_t length,
void *private_data),
void *private_data,
NTSTATUS *status);
diff --git a/source3/include/proto.h b/source3/include/proto.h
index e1e98eb125f..09f12ceb86e 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1457,10 +1457,21 @@ int open_socket_in(int type,
int dlevel,
const struct sockaddr_storage *psock,
bool rebind);
-int open_socket_out(int type,
- const struct sockaddr_storage *pss,
- uint16_t port,
- int timeout);
+NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
+ int timeout, int *pfd);
+struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ const struct sockaddr_storage *pss,
+ uint16_t port,
+ int timeout);
+NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd);
+struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct timeval wait_time,
+ const struct sockaddr_storage *pss,
+ uint16_t port,
+ int timeout);
+NTSTATUS open_socket_out_defer_recv(struct async_req *req, int *pfd);
bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs,
int timeout, int *fd_index, int *fd);
int open_udp_socket(const char *host, int port);
@@ -7970,4 +7981,14 @@ NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid);
NTSTATUS nss_info_template_init( void );
+/* Misc protos */
+
+struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+ struct wb_context *wb_ctx, bool need_priv,
+ const struct winbindd_request *wb_req);
+NTSTATUS wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+ struct winbindd_response **presponse);
+struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx);
+
+
#endif /* _PROTO_H_ */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index a8a2d981543..7fd4fbb553c 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -27,7 +27,7 @@
#define _SMB_H
/* logged when starting the various Samba daemons */
-#define COPYRIGHT_STARTUP_MESSAGE "Copyright Andrew Tridgell and the Samba Team 1992-2008"
+#define COPYRIGHT_STARTUP_MESSAGE "Copyright Andrew Tridgell and the Samba Team 1992-2009"
#if defined(LARGE_SMB_OFF_T)
@@ -369,6 +369,7 @@ struct share_mode_entry;
struct uuid;
struct named_mutex;
struct pcap_cache;
+struct wb_context;
struct vfs_fsp_data {
struct vfs_fsp_data *next;
diff --git a/source3/lib/async_req.c b/source3/lib/async_req.c
index 159666f15c8..ac06df65a3a 100644
--- a/source3/lib/async_req.c
+++ b/source3/lib/async_req.c
@@ -49,7 +49,7 @@ char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req)
* The new async request will be initialized in state ASYNC_REQ_IN_PROGRESS
*/
-struct async_req *async_req_new(TALLOC_CTX *mem_ctx, struct event_context *ev)
+struct async_req *async_req_new(TALLOC_CTX *mem_ctx)
{
struct async_req *result;
@@ -58,7 +58,6 @@ struct async_req *async_req_new(TALLOC_CTX *mem_ctx, struct event_context *ev)
return NULL;
}
result->state = ASYNC_REQ_IN_PROGRESS;
- result->event_ctx = ev;
result->print = async_req_print;
return result;
}
@@ -135,12 +134,12 @@ static void async_trigger(struct event_context *ev, struct timed_event *te,
* conventions, independent of whether the request was actually deferred.
*/
-bool async_post_status(struct async_req *req, NTSTATUS status)
+bool async_post_status(struct async_req *req, struct event_context *ev,
+ NTSTATUS status)
{
req->status = status;
- if (event_add_timed(req->event_ctx, req, timeval_zero(),
- "async_trigger",
+ if (event_add_timed(ev, req, timeval_zero(), "async_trigger",
async_trigger, req) == NULL) {
return false;
}
@@ -195,3 +194,123 @@ NTSTATUS async_req_simple_recv(struct async_req *req)
}
return NT_STATUS_OK;
}
+
+static void async_req_timedout(struct event_context *ev,
+ struct timed_event *te,
+ const struct timeval *now,
+ void *priv)
+{
+ struct async_req *req = talloc_get_type_abort(
+ priv, struct async_req);
+ TALLOC_FREE(te);
+ async_req_error(req, NT_STATUS_IO_TIMEOUT);
+}
+
+bool async_req_set_timeout(struct async_req *req, struct event_context *ev,
+ struct timeval to)
+{
+ return (event_add_timed(ev, req,
+ timeval_current_ofs(to.tv_sec, to.tv_usec),
+ "async_req_timedout", async_req_timedout, req)
+ != NULL);
+}
+
+struct async_req *async_wait_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct timeval to)
+{
+ struct async_req *result;
+
+ result = async_req_new(mem_ctx);
+ if (result == NULL) {
+ return result;
+ }
+ if (!async_req_set_timeout(result, ev, to)) {
+ TALLOC_FREE(result);
+ return NULL;
+ }
+ return result;
+}
+
+NTSTATUS async_wait_recv(struct async_req *req)
+{
+ return NT_STATUS_OK;
+}
+
+struct async_queue_entry {
+ struct async_queue_entry *prev, *next;
+ struct async_req_queue *queue;
+ struct async_req *req;
+ void (*trigger)(struct async_req *req);
+};
+
+struct async_req_queue {
+ struct async_queue_entry *queue;
+};
+
+struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx)
+{
+ return TALLOC_ZERO_P(mem_ctx, struct async_req_queue);
+}
+
+static int async_queue_entry_destructor(struct async_queue_entry *e)
+{
+ struct async_req_queue *queue = e->queue;
+
+ DLIST_REMOVE(queue->queue, e);
+
+ if (queue->queue != NULL) {
+ queue->queue->trigger(queue->queue->req);
+ }
+
+ return 0;
+}
+
+static void async_req_immediate_trigger(struct event_context *ev,
+ struct timed_event *te,
+ const struct timeval *now,
+ void *priv)
+{
+ struct async_queue_entry *e = talloc_get_type_abort(
+ priv, struct async_queue_entry);
+
+ TALLOC_FREE(te);
+ e->trigger(e->req);
+}
+
+bool async_req_enqueue(struct async_req_queue *queue, struct event_context *ev,
+ struct async_req *req,
+ void (*trigger)(struct async_req *req))
+{
+ struct async_queue_entry *e;
+ bool busy;
+
+ busy = (queue->queue != NULL);
+
+ e = talloc(req, struct async_queue_entry);
+ if (e == NULL) {
+ return false;
+ }
+
+ e->req = req;
+ e->trigger = trigger;
+ e->queue = queue;
+
+ DLIST_ADD_END(queue->queue, e, struct async_queue_entry *);
+ talloc_set_destructor(e, async_queue_entry_destructor);
+
+ if (!busy) {
+ struct timed_event *te;
+
+ te = event_add_timed(ev, e, timeval_zero(),
+ "async_req_immediate_trigger",
+ async_req_immediate_trigger,
+ e);
+ if (te == NULL) {
+ TALLOC_FREE(e);
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/source3/lib/async_sock.c b/source3/lib/async_sock.c
index 225cc7b195e..bb89a1353ae 100644
--- a/source3/lib/async_sock.c
+++ b/source3/lib/async_sock.c
@@ -106,7 +106,7 @@ static struct async_req *async_syscall_new(TALLOC_CTX *mem_ctx,
struct async_req *result;
struct async_syscall_state *state;
- result = async_req_new(mem_ctx, ev);
+ result = async_req_new(mem_ctx);
if (result == NULL) {
return NULL;
}
@@ -209,7 +209,7 @@ size_t async_syscall_result_size_t(struct async_req *req, int *perrno)
* @retval The return value from the asynchronously called syscall
*/
-ssize_t async_syscall_result_int(struct async_req *req, int *perrno)
+int async_syscall_result_int(struct async_req *req, int *perrno)
{
struct async_syscall_state *state = talloc_get_type_abort(
req->private_data, struct async_syscall_state);
@@ -236,7 +236,10 @@ static void async_send_callback(struct event_context *ev,
req->private_data, struct async_syscall_state);
struct param_send *p = &state->param.param_send;
- SMB_ASSERT(state->syscall_type == ASYNC_SYSCALL_SEND);
+ if (state->syscall_type != ASYNC_SYSCALL_SEND) {
+ async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+ return;
+ }
state->result.result_ssize_t = send(p->fd, p->buffer, p->length,
p->flags);
@@ -300,7 +303,10 @@ static void async_sendall_callback(struct event_context *ev,
req->private_data, struct async_syscall_state);
struct param_sendall *p = &state->param.param_sendall;
- SMB_ASSERT(state->syscall_type == ASYNC_SYSCALL_SENDALL);
+ if (state->syscall_type != ASYNC_SYSCALL_SENDALL) {
+ async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+ return;
+ }
state->result.result_ssize_t = send(p->fd, (char *)p->buffer + p->sent,
p->length - p->sent, p->flags);
@@ -317,7 +323,10 @@ static void async_sendall_callback(struct event_context *ev,
}
p->sent += state->result.result_ssize_t;
- SMB_ASSERT(p->sent <= p->length);
+ if (p->sent > p->length) {
+ async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+ return;
+ }
if (p->sent == p->length) {
TALLOC_FREE(state->fde);
@@ -385,7 +394,10 @@ static void async_recv_callback(struct event_context *ev,
req->private_data, struct async_syscall_state);
struct param_recv *p = &state->param.param_recv;
- SMB_ASSERT(state->syscall_type == ASYNC_SYSCALL_RECV);
+ if (state->syscall_type != ASYNC_SYSCALL_RECV) {
+ async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+ return;
+ }
state->result.result_ssize_t = recv(p->fd, p->buffer, p->length,
p->flags);
@@ -450,7 +462,10 @@ static void async_recvall_callback(struct event_context *ev,
req->private_data, struct async_syscall_state);
struct param_recvall *p = &state->param.param_recvall;
- SMB_ASSERT(state->syscall_type == ASYNC_SYSCALL_RECVALL);
+ if (state->syscall_type != ASYNC_SYSCALL_RECVALL) {
+ async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+ return;
+ }
state->result.result_ssize_t = recv(p->fd,
(char *)p->buffer + p->received,
@@ -468,7 +483,10 @@ static void async_recvall_callback(struct event_context *ev,
}
p->received += state->result.result_ssize_t;
- SMB_ASSERT(p->received <= p->length);
+ if (p->received > p->length) {
+ async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+ return;
+ }
if (p->received == p->length) {
TALLOC_FREE(state->fde);
@@ -517,60 +535,16 @@ NTSTATUS recvall_recv(struct async_req *req)
return async_req_simple_recv(req);
}
-/**
- * fde event handler for connect(2)
- * @param[in] ev The event context that sent us here
- * @param[in] fde The file descriptor event associated with the connect
- * @param[in] flags Indicate read/writeability of the socket
- * @param[in] priv private data, "struct async_req *" in this case
- */
-
-static void async_connect_callback(struct event_context *ev,
- struct fd_event *fde, uint16_t flags,
- void *priv)
-{
- struct async_req *req = talloc_get_type_abort(
- priv, struct async_req);
- struct async_syscall_state *state = talloc_get_type_abort(
- req->private_data, struct async_syscall_state);
- struct param_connect *p = &state->param.param_connect;
-
- SMB_ASSERT(state->syscall_type == ASYNC_SYSCALL_CONNECT);
-
- TALLOC_FREE(state->fde);
-
- /*
- * Stevens, Network Programming says that if there's a
- * successful connect, the socket is only writable. Upon an
- * error, it's both readable and writable.
- */
- if ((flags & (EVENT_FD_READ|EVENT_FD_WRITE))
- == (EVENT_FD_READ|EVENT_FD_WRITE)) {
- int sockerr;
- socklen_t err_len = sizeof(sockerr);
-
- if (getsockopt(p->fd, SOL_SOCKET, SO_ERROR,
- (void *)&sockerr, &err_len) == 0) {
- errno = sockerr;
- }
-
- state->sys_errno = errno;
-
- DEBUG(10, ("connect returned %s\n", strerror(errno)));
-
- sys_fcntl_long(p->fd, F_SETFL, p->old_sockflags);
-
- async_req_error(req, map_nt_error_from_unix(state->sys_errno));
- return;
- }
-
- sys_fcntl_long(p->fd, F_SETFL, p->old_sockflags);
-
- state->result.result_int = 0;
- state->sys_errno = 0;
+struct async_connect_state {
+ int fd;
+ int result;
+ int sys_errno;
+ long old_sockflags;
+};
- async_req_done(req);
-}
+static void async_connect_connected(struct event_context *ev,
+ struct fd_event *fde, uint16_t flags,
+ void *priv);
/**
* @brief async version of connect(2)
@@ -585,47 +559,46 @@ static void async_connect_callback(struct event_context *ev,
* connect in an async state. This will be reset when the request is finished.
*/
-struct async_req *async_connect(TALLOC_CTX *mem_ctx, struct event_context *ev,
- int fd, const struct sockaddr *address,
- socklen_t address_len)
+struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ int fd, const struct sockaddr *address,
+ socklen_t address_len)
{
struct async_req *result;
- struct async_syscall_state *state;
- struct param_connect *p;
+ struct async_connect_state *state;
+ struct fd_event *fde;
+ NTSTATUS status;
- result = async_syscall_new(mem_ctx, ev, ASYNC_SYSCALL_CONNECT, &state);
+ result = async_req_new(mem_ctx);
if (result == NULL) {
return NULL;
}
- p = &state->param.param_connect;
+ state = talloc(result, struct async_connect_state);
+ if (state == NULL) {
+ goto fail;
+ }
+ result->private_data = state;
/**
* We have to set the socket to nonblocking for async connect(2). Keep
* the old sockflags around.
*/
- p->old_sockflags = sys_fcntl_long(fd, F_GETFL, 0);
+ state->fd = fd;
+ state->sys_errno = 0;
- if (p->old_sockflags == -1) {
- if (async_post_status(result, map_nt_error_from_unix(errno))) {
- return result;
- }
- TALLOC_FREE(result);
- return NULL;
+ state->old_sockflags = sys_fcntl_long(fd, F_GETFL, 0);
+ if (state->old_sockflags == -1) {
+ goto post_errno;
}
- set_blocking(fd, true);
+ set_blocking(fd, false);
- state->result.result_int = connect(fd, address, address_len);
-
- if (state->result.result_int == 0) {
+ state->result = connect(fd, address, address_len);
+ if (state->result == 0) {
state->sys_errno = 0;
- if (async_post_status(result, NT_STATUS_OK)) {
- return result;
- }
- sys_fcntl_long(fd, F_SETFL, p->old_sockflags);
- TALLOC_FREE(result);
- return NULL;
+ status = NT_STATUS_OK;
+ goto post_status;
}
/**
@@ -640,31 +613,93 @@ struct async_req *async_connect(TALLOC_CTX *mem_ctx, struct event_context *ev,
errno == EISCONN ||
#endif
errno == EAGAIN || errno == EINTR)) {
+ goto post_errno;
+ }
- state->sys_errno = errno;
-
- if (async_post_status(result, map_nt_error_from_unix(errno))) {
- return result;
- }
- sys_fcntl_long(fd, F_SETFL, p->old_sockflags);
- TALLOC_FREE(result);
- return NULL;
+ fde = event_add_fd(ev, state, fd, EVENT_FD_READ | EVENT_FD_WRITE,
+ async_connect_connected, result);
+ if (fde == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto post_status;
}
+ return result;
- state->fde = event_add_fd(ev, state, fd,
- EVENT_FD_READ | EVENT_FD_WRITE,
- async_connect_callback, result);
- if (state->fde == NULL) {
- sys_fcntl_long(fd, F_SETFL, p->old_sockflags);
- TALLOC_FREE(result);
- return NULL;
+ post_errno:
+ state->sys_errno = errno;
+ status = map_nt_error_from_unix(state->sys_errno);
+ post_status:
+ sys_fcntl_long(fd, F_SETFL, state->old_sockflags);
+ if (!async_post_status(result, ev, status)) {
+ goto fail;
}
- result->private_data = state;
+ return result;
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+/**
+ * fde event handler for connect(2)
+ * @param[in] ev The event context that sent us here
+ * @param[in] fde The file descriptor event associated with the connect
+ * @param[in] flags Indicate read/writeability of the socket
+ * @param[in] priv private data, "struct async_req *" in this case
+ */
- state->param.param_connect.fd = fd;
- state->param.param_connect.address = address;
- state->param.param_connect.address_len = address_len;
+static void async_connect_connected(struct event_context *ev,
+ struct fd_event *fde, uint16_t flags,
+ void *priv)
+{
+ struct async_req *req = talloc_get_type_abort(
+ priv, struct async_req);
+ struct async_connect_state *state = talloc_get_type_abort(
+ req->private_data, struct async_connect_state);
- return result;
+ TALLOC_FREE(fde);
+
+ /*
+ * Stevens, Network Programming says that if there's a
+ * successful connect, the socket is only writable. Upon an
+ * error, it's both readable and writable.
+ */
+ if ((flags & (EVENT_FD_READ|EVENT_FD_WRITE))
+ == (EVENT_FD_READ|EVENT_FD_WRITE)) {
+ int sockerr;
+ socklen_t err_len = sizeof(sockerr);
+
+ if (getsockopt(state->fd, SOL_SOCKET, SO_ERROR,
+ (void *)&sockerr, &err_len) == 0) {
+ errno = sockerr;
+ }
+
+ state->sys_errno = errno;
+
+ DEBUG(10, ("connect returned %s\n", strerror(errno)));
+
+ sys_fcntl_long(state->fd, F_SETFL, state->old_sockflags);
+ async_req_error(req, map_nt_error_from_unix(state->sys_errno));
+ return;
+ }
+
+ state->sys_errno = 0;
+ async_req_done(req);
}
+NTSTATUS async_connect_recv(struct async_req *req, int *perrno)
+{
+ struct async_connect_state *state = talloc_get_type_abort(
+ req->private_data, struct async_connect_state);
+ NTSTATUS status;
+
+ sys_fcntl_long(state->fd, F_SETFL, state->old_sockflags);
+
+ *perrno = state->sys_errno;
+
+ if (async_req_is_error(req, &status)) {
+ return status;
+ }
+ if (state->sys_errno == 0) {
+ return NT_STATUS_OK;
+ }
+ return map_nt_error_from_unix(state->sys_errno);
+}
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index 8d97606b856..75a513312e2 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -155,17 +155,17 @@ static NTSTATUS ctdbd_connect(TALLOC_CTX *mem_ctx,
* Do we have a complete ctdb packet in the queue?
*/
-static bool ctdb_req_complete(const DATA_BLOB *data,
+static bool ctdb_req_complete(const uint8_t *buf, size_t available,
size_t *length,
void *private_data)
{
uint32 msglen;
- if (data->length < sizeof(msglen)) {
+ if (available < sizeof(msglen)) {
return False;
}
- msglen = *((uint32 *)data->data);
+ msglen = *((uint32 *)buf);
DEBUG(10, ("msglen = %d\n", msglen));
@@ -176,12 +176,12 @@ static bool ctdb_req_complete(const DATA_BLOB *data,
cluster_fatal("ctdbd protocol error\n");
}
- if (data->length >= msglen) {
- *length = msglen;
- return True;
+ if (available < msglen) {
+ return false;
}
- return False;
+ *length = msglen;
+ return true;
}
/*
@@ -220,16 +220,13 @@ struct req_pull_state {
* Pull a ctdb request out of the incoming packet queue
*/
-static NTSTATUS ctdb_req_pull(const DATA_BLOB *data,
+static NTSTATUS ctdb_req_pull(uint8_t *buf, size_t length,
void *private_data)
{
struct req_pull_state *state = (struct req_pull_state *)private_data;
- state->req = data_blob_talloc(state->mem_ctx, data->data,
- data->length);
- if (state->req.data == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
+ state->req.data = talloc_move(state->mem_ctx, &buf);
+ state->req.length = length;
return NT_STATUS_OK;
}
@@ -497,7 +494,7 @@ NTSTATUS ctdbd_messaging_connection(TALLOC_CTX *mem_ctx,
/*
* Packet handler to receive and handle a ctdb message
*/
-static NTSTATUS ctdb_handle_message(const DATA_BLOB *data,
+static NTSTATUS ctdb_handle_message(uint8_t *buf, size_t length,
void *private_data)
{
struct ctdbd_connection *conn = talloc_get_type_abort(
@@ -505,11 +502,12 @@ static NTSTATUS ctdb_handle_message(const DATA_BLOB *data,
struct ctdb_req_message *msg;
struct messaging_rec *msg_rec;
- msg = (struct ctdb_req_message *)data->data;
+ msg = (struct ctdb_req_message *)buf;
if (msg->hdr.operation != CTDB_REQ_MESSAGE) {
DEBUG(0, ("Received async msg of type %u, discarding\n",
msg->hdr.operation));
+ TALLOC_FREE(buf);
return NT_STATUS_INVALID_PARAMETER;
}
@@ -519,6 +517,7 @@ static NTSTATUS ctdb_handle_message(const DATA_BLOB *data,
DEBUG(10, ("received CTDB_SRVID_RELEASE_IP\n"));
conn->release_ip_handler((const char *)msg->data,
conn->release_ip_priv);
+ TALLOC_FREE(buf);
return NT_STATUS_OK;
}
@@ -540,6 +539,8 @@ static NTSTATUS ctdb_handle_message(const DATA_BLOB *data,
*/
message_send_all(conn->msg_ctx, MSG_SMB_UNLOCK, NULL, 0, NULL);
+ TALLOC_FREE(buf);
+
return NT_STATUS_OK;
}
@@ -548,17 +549,20 @@ static NTSTATUS ctdb_handle_message(const DATA_BLOB *data,
if (msg->srvid != sys_getpid() && msg->srvid != MSG_SRVID_SAMBA) {
DEBUG(0,("Got unexpected message with srvid=%llu\n",
(unsigned long long)msg->srvid));
+ TALLOC_FREE(buf);
return NT_STATUS_OK;
}
- if (!(msg_rec = ctdb_pull_messaging_rec(NULL, data->length, msg))) {
+ if (!(msg_rec = ctdb_pull_messaging_rec(NULL, length, msg))) {
DEBUG(10, ("ctdb_pull_messaging_rec failed\n"));
+ TALLOC_FREE(buf);
return NT_STATUS_NO_MEMORY;
}
messaging_dispatch_rec(conn->msg_ctx, msg_rec);
TALLOC_FREE(msg_rec);
+ TALLOC_FREE(buf);
return NT_STATUS_OK;
}
@@ -1025,7 +1029,7 @@ struct ctdbd_traverse_state {
* Handle a traverse record coming in on the ctdbd connection
*/
-static NTSTATUS ctdb_traverse_handler(const DATA_BLOB *blob,
+static NTSTATUS ctdb_traverse_handler(uint8_t *buf, size_t length,
void *private_data)
{
struct ctdbd_traverse_state *state =
@@ -1035,11 +1039,11 @@ static NTSTATUS ctdb_traverse_handler(const DATA_BLOB *blob,
struct ctdb_rec_data *d;
TDB_DATA key, data;
- m = (struct ctdb_req_message *)blob->data;
+ m = (struct ctdb_req_message *)buf;
- if (blob->length < sizeof(*m) || m->hdr.length != blob->length) {
- DEBUG(0, ("Got invalid message of length %d\n",
- (int)blob->length));
+ if (length < sizeof(*m) || m->hdr.length != length) {
+ DEBUG(0, ("Got invalid message of length %d\n", (int)length));
+ TALLOC_FREE(buf);
return NT_STATUS_UNEXPECTED_IO_ERROR;
}
@@ -1047,6 +1051,7 @@ static NTSTATUS ctdb_traverse_handler(const DATA_BLOB *blob,
if (m->datalen < sizeof(uint32_t) || m->datalen != d->length) {
DEBUG(0, ("Got invalid traverse data of length %d\n",
(int)m->datalen));
+ TALLOC_FREE(buf);
return NT_STATUS_UNEXPECTED_IO_ERROR;
}
@@ -1063,6 +1068,7 @@ static NTSTATUS ctdb_traverse_handler(const DATA_BLOB *blob,
if (data.dsize < sizeof(struct ctdb_ltdb_header)) {
DEBUG(0, ("Got invalid ltdb header length %d\n",
(int)data.dsize));
+ TALLOC_FREE(buf);
return NT_STATUS_UNEXPECTED_IO_ERROR;
}
data.dsize -= sizeof(struct ctdb_ltdb_header);
@@ -1072,6 +1078,7 @@ static NTSTATUS ctdb_traverse_handler(const DATA_BLOB *blob,
state->fn(key, data, state->private_data);
}
+ TALLOC_FREE(buf);
return NT_STATUS_OK;
}
diff --git a/source3/lib/ldb/include/ldb.h b/source3/lib/ldb/include/ldb.h
index 0a745742d9b..3891c1c6a31 100644
--- a/source3/lib/ldb/include/ldb.h
+++ b/source3/lib/ldb/include/ldb.h
@@ -991,7 +991,7 @@ int ldb_search(struct ldb_context *ldb,
const struct ldb_dn *base,
enum ldb_scope scope,
const char *expression,
- const char * const *attrs, struct ldb_result **res);
+ const char * const *attrs, struct ldb_result **_res);
/*
* a useful search function where you can easily define the expression and
diff --git a/source3/lib/ldb/tools/ldbadd.c b/source3/lib/ldb/tools/ldbadd.c
index 4dde2a1ef53..155395e065a 100644
--- a/source3/lib/ldb/tools/ldbadd.c
+++ b/source3/lib/ldb/tools/ldbadd.c
@@ -35,8 +35,6 @@
#include "ldb/include/includes.h"
#include "ldb/tools/cmdline.h"
-static int failures;
-
static void usage(void)
{
printf("Usage: ldbadd <options> <ldif...>\n");
@@ -53,7 +51,8 @@ static void usage(void)
/*
add records from an opened file
*/
-static int process_file(struct ldb_context *ldb, FILE *f, int *count)
+static int process_file(struct ldb_context *ldb, FILE *f, int *count,
+ int *failures)
{
struct ldb_ldif *ldif;
int ret = LDB_SUCCESS;
@@ -71,7 +70,7 @@ static int process_file(struct ldb_context *ldb, FILE *f, int *count)
if (ret != LDB_SUCCESS) {
fprintf(stderr, "ERR: \"%s\" on DN %s\n",
ldb_errstring(ldb), ldb_dn_linearize(ldb, ldif->msg->dn));
- failures++;
+ (*failures)++;
} else {
(*count)++;
}
@@ -86,7 +85,7 @@ static int process_file(struct ldb_context *ldb, FILE *f, int *count)
int main(int argc, const char **argv)
{
struct ldb_context *ldb;
- int i, ret=0, count=0;
+ int i, ret=0, count=0, failures=0;
struct ldb_cmdline *options;
ldb_global_init();
@@ -96,7 +95,7 @@ int main(int argc, const char **argv)
options = ldb_cmdline_process(ldb, argc, argv, usage);
if (options->argc == 0) {
- ret = process_file(ldb, stdin, &count);
+ ret = process_file(ldb, stdin, &count, &failures);
} else {
for (i=0;i<options->argc;i++) {
const char *fname = options->argv[i];
@@ -106,7 +105,7 @@ int main(int argc, const char **argv)
perror(fname);
exit(1);
}
- ret = process_file(ldb, f, &count);
+ ret = process_file(ldb, f, &count, &failures);
fclose(f);
}
}
diff --git a/source3/lib/ldb/tools/ldbmodify.c b/source3/lib/ldb/tools/ldbmodify.c
index 368b4cf996f..f12387a8f64 100644
--- a/source3/lib/ldb/tools/ldbmodify.c
+++ b/source3/lib/ldb/tools/ldbmodify.c
@@ -35,8 +35,6 @@
#include "ldb/include/includes.h"
#include "ldb/tools/cmdline.h"
-static int failures;
-
static void usage(void)
{
printf("Usage: ldbmodify <options> <ldif...>\n");
@@ -52,7 +50,8 @@ static void usage(void)
/*
process modifies for one file
*/
-static int process_file(struct ldb_context *ldb, FILE *f, int *count)
+static int process_file(struct ldb_context *ldb, FILE *f, int *count,
+ int *failures)
{
struct ldb_ldif *ldif;
int ret = LDB_SUCCESS;
@@ -73,7 +72,7 @@ static int process_file(struct ldb_context *ldb, FILE *f, int *count)
if (ret != LDB_SUCCESS) {
fprintf(stderr, "ERR: \"%s\" on DN %s\n",
ldb_errstring(ldb), ldb_dn_linearize(ldb, ldif->msg->dn));
- failures++;
+ (*failures)++;
} else {
(*count)++;
}
@@ -87,6 +86,7 @@ int main(int argc, const char **argv)
{
struct ldb_context *ldb;
int count=0;
+ int failures=0;
int i, ret=LDB_SUCCESS;
struct ldb_cmdline *options;
@@ -97,7 +97,7 @@ int main(int argc, const char **argv)
options = ldb_cmdline_process(ldb, argc, argv, usage);
if (options->argc == 0) {
- ret = process_file(ldb, stdin, &count);
+ ret = process_file(ldb, stdin, &count, &failures);
} else {
for (i=0;i<options->argc;i++) {
const char *fname = options->argv[i];
@@ -107,7 +107,7 @@ int main(int argc, const char **argv)
perror(fname);
exit(1);
}
- ret = process_file(ldb, f, &count);
+ ret = process_file(ldb, f, &count, &failures);
}
}
diff --git a/source3/lib/packet.c b/source3/lib/packet.c
index e4cab6ba872..ef28bf9f625 100644
--- a/source3/lib/packet.c
+++ b/source3/lib/packet.c
@@ -120,33 +120,43 @@ NTSTATUS packet_fd_read_sync(struct packet_context *ctx)
}
bool packet_handler(struct packet_context *ctx,
- bool (*full_req)(const DATA_BLOB *data,
+ bool (*full_req)(const uint8_t *buf,
+ size_t available,
size_t *length,
- void *private_data),
- NTSTATUS (*callback)(const DATA_BLOB *data,
- void *private_data),
- void *private_data,
- NTSTATUS *status)
+ void *priv),
+ NTSTATUS (*callback)(uint8_t *buf, size_t length,
+ void *priv),
+ void *priv, NTSTATUS *status)
{
size_t length;
- DATA_BLOB data;
+ uint8_t *buf;
- if (!full_req(&ctx->in, &length, private_data)) {
+ if (!full_req(ctx->in.data, ctx->in.length, &length, priv)) {
return False;
}
- SMB_ASSERT(length <= ctx->in.length);
-
- data = data_blob(ctx->in.data, length);
-
- memmove(ctx->in.data, ctx->in.data + length,
- ctx->in.length - length);
- ctx->in.length -= length;
+ if (length > ctx->in.length) {
+ *status = NT_STATUS_INTERNAL_ERROR;
+ return true;
+ }
- *status = callback(&data, private_data);
+ if (length == ctx->in.length) {
+ buf = ctx->in.data;
+ ctx->in.data = NULL;
+ ctx->in.length = 0;
+ } else {
+ buf = (uint8_t *)TALLOC_MEMDUP(ctx, ctx->in.data, length);
+ if (buf == NULL) {
+ *status = NT_STATUS_NO_MEMORY;
+ return true;
+ }
- data_blob_free(&data);
+ memmove(ctx->in.data, ctx->in.data + length,
+ ctx->in.length - length);
+ ctx->in.length -= length;
+ }
+ *status = callback(buf, length, priv);
return True;
}
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index d23758ad6a2..e913b35d607 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -707,10 +707,6 @@ ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
Write data to a fd.
****************************************************************************/
-/****************************************************************************
- Write data to a fd.
-****************************************************************************/
-
ssize_t write_data(int fd, const char *buffer, size_t N)
{
ssize_t ret;
@@ -948,102 +944,319 @@ int open_socket_in(int type,
return( res );
}
+struct open_socket_out_state {
+ int fd;
+ struct event_context *ev;
+ struct sockaddr_storage ss;
+ socklen_t salen;
+ uint16_t port;
+ int wait_nsec;
+};
+
+static void open_socket_out_connected(struct async_req *subreq);
+
+static int open_socket_out_state_destructor(struct open_socket_out_state *s)
+{
+ if (s->fd != -1) {
+ close(s->fd);
+ }
+ return 0;
+}
+
/****************************************************************************
Create an outgoing socket. timeout is in milliseconds.
**************************************************************************/
-int open_socket_out(int type,
- const struct sockaddr_storage *pss,
- uint16_t port,
- int timeout)
+struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ const struct sockaddr_storage *pss,
+ uint16_t port,
+ int timeout)
{
char addr[INET6_ADDRSTRLEN];
- struct sockaddr_storage sock_out = *pss;
- int res,ret;
- int connect_loop = 10;
- int increment = 10;
+ struct async_req *result, *subreq;
+ struct open_socket_out_state *state;
+ NTSTATUS status;
- /* create a socket to write to */
- res = socket(pss->ss_family, type, 0);
- if (res == -1) {
- DEBUG(0,("socket error (%s)\n", strerror(errno)));
- return -1;
+ result = async_req_new(mem_ctx);
+ if (result == NULL) {
+ return NULL;
}
+ state = talloc(result, struct open_socket_out_state);
+ if (state == NULL) {
+ goto fail;
+ }
+ result->private_data = state;
+
+ state->ev = ev;
+ state->ss = *pss;
+ state->port = port;
+ state->wait_nsec = 10000;
+ state->salen = -1;
- if (type != SOCK_STREAM) {
- return res;
+ state->fd = socket(state->ss.ss_family, SOCK_STREAM, 0);
+ if (state->fd == -1) {
+ status = map_nt_error_from_unix(errno);
+ goto post_status;
+ }
+ talloc_set_destructor(state, open_socket_out_state_destructor);
+
+ if (!async_req_set_timeout(result, ev, timeval_set(0, timeout*1000))) {
+ goto fail;
}
#if defined(HAVE_IPV6)
if (pss->ss_family == AF_INET6) {
- struct sockaddr_in6 *psa6 = (struct sockaddr_in6 *)&sock_out;
+ struct sockaddr_in6 *psa6;
+ psa6 = (struct sockaddr_in6 *)&state->ss;
psa6->sin6_port = htons(port);
- if (psa6->sin6_scope_id == 0 &&
- IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
- setup_linklocal_scope_id((struct sockaddr *)&sock_out);
+ if (psa6->sin6_scope_id == 0
+ && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
+ setup_linklocal_scope_id(
+ (struct sockaddr *)&(state->ss));
}
+ state->salen = sizeof(struct sockaddr_in6);
}
#endif
if (pss->ss_family == AF_INET) {
- struct sockaddr_in *psa = (struct sockaddr_in *)&sock_out;
+ struct sockaddr_in *psa;
+ psa = (struct sockaddr_in *)&state->ss;
psa->sin_port = htons(port);
+ state->salen = sizeof(struct sockaddr_in);
}
- /* set it non-blocking */
- set_blocking(res,false);
+ print_sockaddr(addr, sizeof(addr), &state->ss);
+ DEBUG(3,("Connecting to %s at port %u\n", addr, (unsigned int)port));
- print_sockaddr(addr, sizeof(addr), &sock_out);
- DEBUG(3,("Connecting to %s at port %u\n",
- addr,
- (unsigned int)port));
+ subreq = async_connect_send(state, state->ev, state->fd,
+ (struct sockaddr *)&state->ss,
+ state->salen);
+ if ((subreq == NULL)
+ || !async_req_set_timeout(subreq, state->ev,
+ timeval_set(0, state->wait_nsec))) {
+ status = NT_STATUS_NO_MEMORY;
+ goto post_status;
+ }
+ subreq->async.fn = open_socket_out_connected;
+ subreq->async.priv = result;
+ return result;
- /* and connect it to the destination */
- connect_again:
+ post_status:
+ if (!async_post_status(result, ev, status)) {
+ goto fail;
+ }
+ return result;
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
- ret = sys_connect(res, (struct sockaddr *)&sock_out);
+static void open_socket_out_connected(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct open_socket_out_state *state = talloc_get_type_abort(
+ req->private_data, struct open_socket_out_state);
+ NTSTATUS status;
+ int sys_errno;
- /* Some systems return EAGAIN when they mean EINPROGRESS */
- if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
- errno == EAGAIN) && (connect_loop < timeout) ) {
- smb_msleep(connect_loop);
- timeout -= connect_loop;
- connect_loop += increment;
- if (increment < 250) {
- /* After 8 rounds we end up at a max of 255 msec */
- increment *= 1.5;
- }
- goto connect_again;
+ status = async_connect_recv(subreq, &sys_errno);
+ TALLOC_FREE(subreq);
+ if (NT_STATUS_IS_OK(status)) {
+ async_req_done(req);
+ return;
}
- if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
- errno == EAGAIN)) {
- DEBUG(1,("timeout connecting to %s:%u\n",
- addr,
- (unsigned int)port));
- close(res);
- return -1;
+ if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)
+ || (sys_errno == EINPROGRESS)
+ || (sys_errno == EALREADY)
+ || (sys_errno == EAGAIN)) {
+
+ /*
+ * retry
+ */
+
+ if (state->wait_nsec < 250000) {
+ state->wait_nsec *= 1.5;
+ }
+
+ subreq = async_connect_send(state, state->ev, state->fd,
+ (struct sockaddr *)&state->ss,
+ state->salen);
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+ if (!async_req_set_timeout(subreq, state->ev,
+ timeval_set(0, state->wait_nsec))) {
+ async_req_error(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ subreq->async.fn = open_socket_out_connected;
+ subreq->async.priv = req;
+ return;
}
#ifdef EISCONN
- if (ret < 0 && errno == EISCONN) {
- errno = 0;
- ret = 0;
+ if (sys_errno == EISCONN) {
+ async_req_done(req);
+ return;
}
#endif
- if (ret < 0) {
- DEBUG(2,("error connecting to %s:%d (%s)\n",
- addr,
- (unsigned int)port,
- strerror(errno)));
- close(res);
- return -1;
+ /* real error */
+ async_req_error(req, map_nt_error_from_unix(sys_errno));
+}
+
+NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd)
+{
+ struct open_socket_out_state *state = talloc_get_type_abort(
+ req->private_data, struct open_socket_out_state);
+ NTSTATUS status;
+
+ if (async_req_is_error(req, &status)) {
+ return status;
+ }
+ *pfd = state->fd;
+ state->fd = -1;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
+ int timeout, int *pfd)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct async_req *req;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ goto fail;
}
- /* set it blocking again */
- set_blocking(res,true);
+ req = open_socket_out_send(frame, ev, pss, port, timeout);
+ if (req == NULL) {
+ goto fail;
+ }
+ while (req->state < ASYNC_REQ_DONE) {
+ event_loop_once(ev);
+ }
- return res;
+ status = open_socket_out_recv(req, pfd);
+ fail:
+ TALLOC_FREE(frame);
+ return status;
+}
+
+struct open_socket_out_defer_state {
+ struct event_context *ev;
+ struct sockaddr_storage ss;
+ uint16_t port;
+ int timeout;
+ int fd;
+};
+
+static void open_socket_out_defer_waited(struct async_req *subreq);
+static void open_socket_out_defer_connected(struct async_req *subreq);
+
+struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct timeval wait_time,
+ const struct sockaddr_storage *pss,
+ uint16_t port,
+ int timeout)
+{
+ struct async_req *result, *subreq;
+ struct open_socket_out_defer_state *state;
+ NTSTATUS status;
+
+ result = async_req_new(mem_ctx);
+ if (result == NULL) {
+ return NULL;
+ }
+ state = talloc(result, struct open_socket_out_defer_state);
+ if (state == NULL) {
+ goto fail;
+ }
+ result->private_data = state;
+
+ state->ev = ev;
+ state->ss = *pss;
+ state->port = port;
+ state->timeout = timeout;
+
+ subreq = async_wait_send(state, ev, wait_time);
+ if (subreq == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto post_status;
+ }
+ subreq->async.fn = open_socket_out_defer_waited;
+ subreq->async.priv = result;
+ return result;
+
+ post_status:
+ if (!async_post_status(result, ev, status)) {
+ goto fail;
+ }
+ return result;
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void open_socket_out_defer_waited(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct open_socket_out_defer_state *state = talloc_get_type_abort(
+ req->private_data, struct open_socket_out_defer_state);
+ NTSTATUS status;
+
+ status = async_wait_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_error(req, status);
+ return;
+ }
+
+ subreq = open_socket_out_send(state, state->ev, &state->ss,
+ state->port, state->timeout);
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+ subreq->async.fn = open_socket_out_defer_connected;
+ subreq->async.priv = req;
+}
+
+static void open_socket_out_defer_connected(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct open_socket_out_defer_state *state = talloc_get_type_abort(
+ req->private_data, struct open_socket_out_defer_state);
+ NTSTATUS status;
+
+ status = open_socket_out_recv(subreq, &state->fd);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_error(req, status);
+ return;
+ }
+ async_req_done(req);
+}
+
+NTSTATUS open_socket_out_defer_recv(struct async_req *req, int *pfd)
+{
+ struct open_socket_out_defer_state *state = talloc_get_type_abort(
+ req->private_data, struct open_socket_out_defer_state);
+ NTSTATUS status;
+
+ if (async_req_is_error(req, &status)) {
+ return status;
+ }
+ *pfd = state->fd;
+ state->fd = -1;
+ return NT_STATUS_OK;
}
/*******************************************************************
diff --git a/source3/winbindd/winbindd_reqtrans.c b/source3/lib/wb_reqtrans.c
index ea16c5f81e2..1f5f181aa1f 100644
--- a/source3/winbindd/winbindd_reqtrans.c
+++ b/source3/lib/wb_reqtrans.c
@@ -20,7 +20,7 @@
*/
#include "includes.h"
-#include "winbindd.h"
+#include "winbindd/winbindd.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
@@ -43,7 +43,7 @@ struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
struct async_req *result, *subreq;
struct req_read_state *state;
- result = async_req_new(mem_ctx, ev);
+ result = async_req_new(mem_ctx);
if (result == NULL) {
return NULL;
}
@@ -205,7 +205,7 @@ struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
struct async_req *result, *subreq;
struct req_write_state *state;
- result = async_req_new(mem_ctx, ev);
+ result = async_req_new(mem_ctx);
if (result == NULL) {
return NULL;
}
@@ -304,7 +304,7 @@ struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
struct async_req *result, *subreq;
struct resp_read_state *state;
- result = async_req_new(mem_ctx, ev);
+ result = async_req_new(mem_ctx);
if (result == NULL) {
return NULL;
}
@@ -458,7 +458,7 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
struct async_req *result, *subreq;
struct resp_write_state *state;
- result = async_req_new(mem_ctx, ev);
+ result = async_req_new(mem_ctx);
if (result == NULL) {
return NULL;
}
@@ -540,146 +540,3 @@ NTSTATUS wb_resp_write_recv(struct async_req *req)
{
return async_req_simple_recv(req);
}
-
-struct wb_trans_state {
- struct event_context *ev;
- struct timed_event *te;
- int fd;
- struct winbindd_response *wb_resp;
- size_t reply_max_extra_data;
-};
-
-static void wb_trans_timeout(struct event_context *ev, struct timed_event *te,
- const struct timeval *now, void *priv);
-static void wb_trans_sent(struct async_req *req);
-static void wb_trans_received(struct async_req *req);
-
-struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- int fd,
- struct winbindd_request *wb_req,
- struct timeval timeout,
- size_t reply_max_extra_data)
-{
- struct async_req *result, *subreq;
- struct wb_trans_state *state;
-
- result = async_req_new(mem_ctx, ev);
- if (result == NULL) {
- return NULL;
- }
-
- state = talloc(result, struct wb_trans_state);
- if (state == NULL) {
- goto nomem;
- }
- result->private_data = state;
-
- state->ev = ev;
- state->fd = fd;
- state->reply_max_extra_data = reply_max_extra_data;
-
- state->te = event_add_timed(
- ev, state,
- timeval_current_ofs(timeout.tv_sec, timeout.tv_usec),
- "wb_trans_timeout", wb_trans_timeout, result);
- if (state->te == NULL) {
- goto nomem;
- }
-
- subreq = wb_req_write_send(state, state->ev, state->fd, wb_req);
- if (subreq == NULL) {
- goto nomem;
- }
- subreq->async.fn = wb_trans_sent;
- subreq->async.priv = result;
-
- return result;
-
- nomem:
- TALLOC_FREE(result);
- return NULL;
-}
-
-static void wb_trans_timeout(struct event_context *ev, struct timed_event *te,
- const struct timeval *now, void *priv)
-{
- struct async_req *req = talloc_get_type_abort(
- priv, struct async_req);
- struct wb_trans_state *state = talloc_get_type_abort(
- req->private_data, struct wb_trans_state);
-
- TALLOC_FREE(state->te);
- async_req_error(req, NT_STATUS_IO_TIMEOUT);
-}
-
-static void wb_trans_sent(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct wb_trans_state *state = talloc_get_type_abort(
- req->private_data, struct wb_trans_state);
- NTSTATUS status;
-
- status = wb_req_write_recv(subreq);
- TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
- return;
- }
-
- subreq = wb_resp_read_send(state, state->ev, state->fd);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_trans_received;
- subreq->async.priv = req;
-};
-
-static void wb_trans_received(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct wb_trans_state *state = talloc_get_type_abort(
- req->private_data, struct wb_trans_state);
- NTSTATUS status;
-
- TALLOC_FREE(state->te);
-
- status = wb_resp_read_recv(subreq, state, &state->wb_resp);
- TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
- return;
- }
-
- async_req_done(req);
-}
-
-NTSTATUS wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
- struct winbindd_response **presp)
-{
- struct wb_trans_state *state = talloc_get_type_abort(
- req->private_data, struct wb_trans_state);
- NTSTATUS status;
-
- if (async_req_is_error(req, &status)) {
- return status;
- }
- *presp = talloc_move(mem_ctx, &state->wb_resp);
- return NT_STATUS_OK;
-}
-
-struct wb_trans_queue_state {
- struct wb_trans_queue_state *prev, *next;
- struct wb_trans_queue *queue;
- struct winbindd_request *req;
-};
-
-struct wb_trans_queue {
- int fd;
- struct timeval timeout;
- size_t max_resp_extra_data;
- struct wb_trans_queue_state *queued_requests;
-};
diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c
new file mode 100644
index 00000000000..d58c934c071
--- /dev/null
+++ b/source3/lib/wbclient.c
@@ -0,0 +1,774 @@
+/*
+ Unix SMB/CIFS implementation.
+ Infrastructure for async winbind requests
+ Copyright (C) Volker Lendecke 2008
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "winbindd/winbindd.h"
+#include "winbindd/winbindd_proto.h"
+
+static int make_nonstd_fd(int fd)
+{
+ int i;
+ int sys_errno = 0;
+ int fds[3];
+ int num_fds = 0;
+
+ if (fd == -1) {
+ return -1;
+ }
+ while (fd < 3) {
+ fds[num_fds++] = fd;
+ fd = dup(fd);
+ if (fd == -1) {
+ sys_errno = errno;
+ break;
+ }
+ }
+ for (i=0; i<num_fds; i++) {
+ close(fds[i]);
+ }
+ if (fd == -1) {
+ errno = sys_errno;
+ }
+ return fd;
+}
+
+/****************************************************************************
+ Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
+ else
+ if SYSV use O_NDELAY
+ if BSD use FNDELAY
+ Set close on exec also.
+****************************************************************************/
+
+static int make_safe_fd(int fd)
+{
+ int result, flags;
+ int new_fd = make_nonstd_fd(fd);
+
+ if (new_fd == -1) {
+ goto fail;
+ }
+
+ /* Socket should be nonblocking. */
+
+#ifdef O_NONBLOCK
+#define FLAG_TO_SET O_NONBLOCK
+#else
+#ifdef SYSV
+#define FLAG_TO_SET O_NDELAY
+#else /* BSD */
+#define FLAG_TO_SET FNDELAY
+#endif
+#endif
+
+ if ((flags = fcntl(new_fd, F_GETFL)) == -1) {
+ goto fail;
+ }
+
+ flags |= FLAG_TO_SET;
+ if (fcntl(new_fd, F_SETFL, flags) == -1) {
+ goto fail;
+ }
+
+#undef FLAG_TO_SET
+
+ /* Socket should be closed on exec() */
+#ifdef FD_CLOEXEC
+ result = flags = fcntl(new_fd, F_GETFD, 0);
+ if (flags >= 0) {
+ flags |= FD_CLOEXEC;
+ result = fcntl( new_fd, F_SETFD, flags );
+ }
+ if (result < 0) {
+ goto fail;
+ }
+#endif
+ return new_fd;
+
+ fail:
+ if (new_fd != -1) {
+ int sys_errno = errno;
+ close(new_fd);
+ errno = sys_errno;
+ }
+ return -1;
+}
+
+static bool winbind_closed_fd(int fd)
+{
+ struct timeval tv;
+ fd_set r_fds;
+
+ if (fd == -1) {
+ return true;
+ }
+
+ FD_ZERO(&r_fds);
+ FD_SET(fd, &r_fds);
+ ZERO_STRUCT(tv);
+
+ if ((select(fd+1, &r_fds, NULL, NULL, &tv) == -1)
+ || FD_ISSET(fd, &r_fds)) {
+ return true;
+ }
+
+ return false;
+}
+
+struct wb_context {
+ struct async_req_queue *queue;
+ int fd;
+ bool is_priv;
+};
+
+struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
+{
+ struct wb_context *result;
+
+ result = talloc(mem_ctx, struct wb_context);
+ if (result == NULL) {
+ return NULL;
+ }
+ result->queue = async_req_queue_init(result);
+ if (result->queue == NULL) {
+ TALLOC_FREE(result);
+ return NULL;
+ }
+ result->fd = -1;
+ return result;
+}
+
+static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct wb_context *wb_ctx,
+ const char *dir)
+{
+ struct async_req *req;
+ struct sockaddr_un sunaddr;
+ struct stat st;
+ char *path = NULL;
+ NTSTATUS status;
+
+ if (wb_ctx->fd != -1) {
+ close(wb_ctx->fd);
+ wb_ctx->fd = -1;
+ }
+
+ /* Check permissions on unix socket directory */
+
+ if (lstat(dir, &st) == -1) {
+ status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ goto post_status;
+ }
+
+ if (!S_ISDIR(st.st_mode) ||
+ (st.st_uid != 0 && st.st_uid != geteuid())) {
+ status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ goto post_status;
+ }
+
+ /* Connect to socket */
+
+ path = talloc_asprintf(talloc_tos(), "%s/%s", dir,
+ WINBINDD_SOCKET_NAME);
+ if (path == NULL) {
+ goto nomem;
+ }
+
+ sunaddr.sun_family = AF_UNIX;
+ strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
+ TALLOC_FREE(path);
+
+ /* If socket file doesn't exist, don't bother trying to connect
+ with retry. This is an attempt to make the system usable when
+ the winbindd daemon is not running. */
+
+ if ((lstat(sunaddr.sun_path, &st) == -1)
+ || !S_ISSOCK(st.st_mode)
+ || (st.st_uid != 0 && st.st_uid != geteuid())) {
+ status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ goto post_status;
+ }
+
+ wb_ctx->fd = make_safe_fd(socket(AF_UNIX, SOCK_STREAM, 0));
+ if (wb_ctx->fd == -1) {
+ status = map_nt_error_from_unix(errno);
+ goto post_status;
+ }
+
+ req = async_connect_send(mem_ctx, ev, wb_ctx->fd,
+ (struct sockaddr *)&sunaddr,
+ sizeof(sunaddr));
+ if (req == NULL) {
+ goto nomem;
+ }
+ if (!async_req_set_timeout(req, ev, timeval_set(30, 0))) {
+ TALLOC_FREE(req);
+ goto nomem;
+ }
+
+ return req;
+
+ nomem:
+ status = NT_STATUS_NO_MEMORY;
+ post_status:
+ req = async_req_new(mem_ctx);
+ if (req == NULL) {
+ return NULL;
+ }
+ if (async_post_status(req, ev, status)) {
+ return req;
+ }
+ TALLOC_FREE(req);
+ return NULL;
+}
+
+static NTSTATUS wb_connect_recv(struct async_req *req)
+{
+ int dummy;
+
+ return async_connect_recv(req, &dummy);
+}
+
+static struct winbindd_request *winbindd_request_copy(
+ TALLOC_CTX *mem_ctx,
+ const struct winbindd_request *req)
+{
+ struct winbindd_request *result;
+
+ result = (struct winbindd_request *)TALLOC_MEMDUP(
+ mem_ctx, req, sizeof(struct winbindd_request));
+ if (result == NULL) {
+ return NULL;
+ }
+
+ if (result->extra_len == 0) {
+ return result;
+ }
+
+ result->extra_data.data = (char *)TALLOC_MEMDUP(
+ result, result->extra_data.data, result->extra_len);
+ if (result->extra_data.data == NULL) {
+ TALLOC_FREE(result);
+ return NULL;
+ }
+ return result;
+}
+
+struct wb_int_trans_state {
+ struct event_context *ev;
+ int fd;
+ struct winbindd_request *wb_req;
+ struct winbindd_response *wb_resp;
+};
+
+static void wb_int_trans_write_done(struct async_req *subreq);
+static void wb_int_trans_read_done(struct async_req *subreq);
+
+static struct async_req *wb_int_trans_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev, int fd,
+ struct winbindd_request *wb_req)
+{
+ struct async_req *result;
+ struct async_req *subreq;
+ struct wb_int_trans_state *state;
+
+ result = async_req_new(mem_ctx);
+ if (result == NULL) {
+ return NULL;
+ }
+ state = talloc(result, struct wb_int_trans_state);
+ if (state == NULL) {
+ goto fail;
+ }
+ result->private_data = state;
+
+ if (winbind_closed_fd(fd)) {
+ if (!async_post_status(result, ev,
+ NT_STATUS_PIPE_DISCONNECTED)) {
+ goto fail;
+ }
+ return result;
+ }
+
+ state->ev = ev;
+ state->fd = fd;
+ state->wb_req = wb_req;
+
+ state->wb_req->length = sizeof(struct winbindd_request);
+ state->wb_req->pid = getpid();
+
+ subreq = wb_req_write_send(state, state->ev, state->fd, state->wb_req);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = wb_int_trans_write_done;
+ subreq->async.priv = result;
+
+ return result;
+
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void wb_int_trans_write_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct wb_int_trans_state *state = talloc_get_type_abort(
+ req->private_data, struct wb_int_trans_state);
+ NTSTATUS status;
+
+ status = wb_req_write_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_error(req, status);
+ return;
+ }
+
+ subreq = wb_resp_read_send(state, state->ev, state->fd);
+ if (subreq == NULL) {
+ async_req_error(req, NT_STATUS_NO_MEMORY);
+ }
+ subreq->async.fn = wb_int_trans_read_done;
+ subreq->async.priv = req;
+}
+
+static void wb_int_trans_read_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct wb_int_trans_state *state = talloc_get_type_abort(
+ req->private_data, struct wb_int_trans_state);
+ NTSTATUS status;
+
+ status = wb_resp_read_recv(subreq, state, &state->wb_resp);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_error(req, status);
+ return;
+ }
+
+ async_req_done(req);
+}
+
+static NTSTATUS wb_int_trans_recv(struct async_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct winbindd_response **presponse)
+{
+ struct wb_int_trans_state *state = talloc_get_type_abort(
+ req->private_data, struct wb_int_trans_state);
+ NTSTATUS status;
+
+ if (async_req_is_error(req, &status)) {
+ return status;
+ }
+
+ *presponse = talloc_move(mem_ctx, &state->wb_resp);
+ return NT_STATUS_OK;
+}
+
+static const char *winbindd_socket_dir(void)
+{
+#ifdef SOCKET_WRAPPER
+ const char *env_dir;
+
+ env_dir = getenv(WINBINDD_SOCKET_DIR_ENVVAR);
+ if (env_dir) {
+ return env_dir;
+ }
+#endif
+
+ return WINBINDD_SOCKET_DIR;
+}
+
+struct wb_open_pipe_state {
+ struct wb_context *wb_ctx;
+ struct event_context *ev;
+ bool need_priv;
+ struct winbindd_request wb_req;
+};
+
+static void wb_open_pipe_connect_nonpriv_done(struct async_req *subreq);
+static void wb_open_pipe_ping_done(struct async_req *subreq);
+static void wb_open_pipe_getpriv_done(struct async_req *subreq);
+static void wb_open_pipe_connect_priv_done(struct async_req *subreq);
+
+static struct async_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct wb_context *wb_ctx,
+ bool need_priv)
+{
+ struct async_req *result;
+ struct async_req *subreq;
+ struct wb_open_pipe_state *state;
+
+ result = async_req_new(mem_ctx);
+ if (result == NULL) {
+ return NULL;
+ }
+ state = talloc(result, struct wb_open_pipe_state);
+ if (state == NULL) {
+ goto fail;
+ }
+ result->private_data = state;
+
+ state->wb_ctx = wb_ctx;
+ state->ev = ev;
+ state->need_priv = need_priv;
+
+ if (wb_ctx->fd != -1) {
+ close(wb_ctx->fd);
+ wb_ctx->fd = -1;
+ }
+
+ subreq = wb_connect_send(state, ev, wb_ctx, winbindd_socket_dir());
+ if (subreq == NULL) {
+ goto fail;
+ }
+
+ subreq->async.fn = wb_open_pipe_connect_nonpriv_done;
+ subreq->async.priv = result;
+ return result;
+
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void wb_open_pipe_connect_nonpriv_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct wb_open_pipe_state *state = talloc_get_type_abort(
+ req->private_data, struct wb_open_pipe_state);
+ NTSTATUS status;
+
+ status = wb_connect_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ state->wb_ctx->is_priv = true;
+ async_req_error(req, status);
+ return;
+ }
+
+ ZERO_STRUCT(state->wb_req);
+ state->wb_req.cmd = WINBINDD_INTERFACE_VERSION;
+
+ subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
+ &state->wb_req);
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+
+ subreq->async.fn = wb_open_pipe_ping_done;
+ subreq->async.priv = req;
+}
+
+static void wb_open_pipe_ping_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct wb_open_pipe_state *state = talloc_get_type_abort(
+ req->private_data, struct wb_open_pipe_state);
+ struct winbindd_response *wb_resp;
+ NTSTATUS status;
+
+ status = wb_int_trans_recv(subreq, state, &wb_resp);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_error(req, status);
+ return;
+ }
+
+ if (!state->need_priv) {
+ async_req_done(req);
+ return;
+ }
+
+ state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR;
+
+ subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
+ &state->wb_req);
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+
+ subreq->async.fn = wb_open_pipe_getpriv_done;
+ subreq->async.priv = req;
+}
+
+static void wb_open_pipe_getpriv_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct wb_open_pipe_state *state = talloc_get_type_abort(
+ req->private_data, struct wb_open_pipe_state);
+ struct winbindd_response *wb_resp = NULL;
+ NTSTATUS status;
+
+ status = wb_int_trans_recv(subreq, state, &wb_resp);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_error(req, status);
+ return;
+ }
+
+ close(state->wb_ctx->fd);
+ state->wb_ctx->fd = -1;
+
+ subreq = wb_connect_send(state, state->ev, state->wb_ctx,
+ (char *)wb_resp->extra_data.data);
+ TALLOC_FREE(wb_resp);
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+
+ subreq->async.fn = wb_open_pipe_connect_priv_done;
+ subreq->async.priv = req;
+}
+
+static void wb_open_pipe_connect_priv_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct wb_open_pipe_state *state = talloc_get_type_abort(
+ req->private_data, struct wb_open_pipe_state);
+ NTSTATUS status;
+
+ status = wb_connect_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_error(req, status);
+ return;
+ }
+ state->wb_ctx->is_priv = true;
+ async_req_done(req);
+}
+
+static NTSTATUS wb_open_pipe_recv(struct async_req *req)
+{
+ return async_req_simple_recv(req);
+}
+
+struct wb_trans_state {
+ struct wb_trans_state *prev, *next;
+ struct wb_context *wb_ctx;
+ struct event_context *ev;
+ struct winbindd_request *wb_req;
+ struct winbindd_response *wb_resp;
+ int num_retries;
+ bool need_priv;
+};
+
+static void wb_trans_connect_done(struct async_req *subreq);
+static void wb_trans_done(struct async_req *subreq);
+static void wb_trans_retry_wait_done(struct async_req *subreq);
+
+static void wb_trigger_trans(struct async_req *req)
+{
+ struct wb_trans_state *state = talloc_get_type_abort(
+ req->private_data, struct wb_trans_state);
+ struct async_req *subreq;
+
+ if ((state->wb_ctx->fd == -1)
+ || (state->need_priv && !state->wb_ctx->is_priv)) {
+
+ subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
+ state->need_priv);
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+ subreq->async.fn = wb_trans_connect_done;
+ subreq->async.priv = req;
+ return;
+ }
+
+ subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
+ state->wb_req);
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+ subreq->async.fn = wb_trans_done;
+ subreq->async.priv = req;
+}
+
+struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+ struct wb_context *wb_ctx, bool need_priv,
+ const struct winbindd_request *wb_req)
+{
+ struct async_req *result;
+ struct wb_trans_state *state;
+
+ result = async_req_new(mem_ctx);
+ if (result == NULL) {
+ return NULL;
+ }
+ state = talloc(result, struct wb_trans_state);
+ if (state == NULL) {
+ goto fail;
+ }
+ result->private_data = state;
+
+ state->wb_ctx = wb_ctx;
+ state->ev = ev;
+ state->wb_req = winbindd_request_copy(state, wb_req);
+ if (state->wb_req == NULL) {
+ goto fail;
+ }
+ state->num_retries = 10;
+ state->need_priv = need_priv;
+
+ if (!async_req_enqueue(wb_ctx->queue, ev, result, wb_trigger_trans)) {
+ goto fail;
+ }
+ return result;
+
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static bool wb_trans_retry(struct async_req *req,
+ struct wb_trans_state *state,
+ NTSTATUS status)
+{
+ struct async_req *subreq;
+
+ if (NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)
+ || NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ /*
+ * Winbind not around or we can't connect to the pipe. Fail
+ * immediately.
+ */
+ async_req_error(req, status);
+ return true;
+ }
+
+ state->num_retries -= 1;
+ if (state->num_retries == 0) {
+ async_req_error(req, status);
+ return true;
+ }
+
+ /*
+ * The transfer as such failed, retry after one second
+ */
+
+ if (state->wb_ctx->fd != -1) {
+ close(state->wb_ctx->fd);
+ state->wb_ctx->fd = -1;
+ }
+
+ subreq = async_wait_send(state, state->ev, timeval_set(1, 0));
+ if (async_req_nomem(subreq, req)) {
+ return true;
+ }
+
+ subreq->async.fn = wb_trans_retry_wait_done;
+ subreq->async.priv = req;
+ return true;
+}
+
+static void wb_trans_retry_wait_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct wb_trans_state *state = talloc_get_type_abort(
+ req->private_data, struct wb_trans_state);
+ NTSTATUS status;
+
+ status = async_wait_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
+ async_req_error(req, status);
+ return;
+ }
+
+ subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
+ state->need_priv);
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+ subreq->async.fn = wb_trans_connect_done;
+ subreq->async.priv = req;
+}
+
+static void wb_trans_connect_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct wb_trans_state *state = talloc_get_type_abort(
+ req->private_data, struct wb_trans_state);
+ NTSTATUS status;
+
+ status = wb_open_pipe_recv(subreq);
+ TALLOC_FREE(subreq);
+
+ if (wb_trans_retry(req, state, status)) {
+ return;
+ }
+
+ subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
+ state->wb_req);
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+
+ subreq->async.fn = wb_trans_done;
+ subreq->async.priv = req;
+}
+
+static void wb_trans_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct wb_trans_state *state = talloc_get_type_abort(
+ req->private_data, struct wb_trans_state);
+ NTSTATUS status;
+
+ status = wb_int_trans_recv(subreq, state, &state->wb_resp);
+ TALLOC_FREE(subreq);
+
+ if (wb_trans_retry(req, state, status)) {
+ return;
+ }
+
+ async_req_done(req);
+}
+
+NTSTATUS wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+ struct winbindd_response **presponse)
+{
+ struct wb_trans_state *state = talloc_get_type_abort(
+ req->private_data, struct wb_trans_state);
+ NTSTATUS status;
+
+ if (async_req_is_error(req, &status)) {
+ return status;
+ }
+
+ *presponse = talloc_move(mem_ctx, &state->wb_resp);
+ return NT_STATUS_OK;
+}
diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c
index 5032ffd14cc..7cdfbc58a4a 100644
--- a/source3/libads/krb5_setpw.c
+++ b/source3/libads/krb5_setpw.c
@@ -425,21 +425,28 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context,
if (!use_tcp) {
sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT);
-
+ if (sock == -1) {
+ int rc = errno;
+ SAFE_FREE(ap_req.data);
+ krb5_auth_con_free(context, auth_context);
+ DEBUG(1,("failed to open kpasswd socket to %s "
+ "(%s)\n", kdc_host, strerror(errno)));
+ return ADS_ERROR_SYSTEM(rc);
+ }
} else {
-
- sock = open_socket_out(SOCK_STREAM, &addr, DEFAULT_KPASSWD_PORT,
- LONG_CONNECT_TIMEOUT);
+ NTSTATUS status;
+ status = open_socket_out(&addr, DEFAULT_KPASSWD_PORT,
+ LONG_CONNECT_TIMEOUT, &sock);
+ if (!NT_STATUS_IS_OK(status)) {
+ SAFE_FREE(ap_req.data);
+ krb5_auth_con_free(context, auth_context);
+ DEBUG(1,("failed to open kpasswd socket to %s "
+ "(%s)\n", kdc_host,
+ nt_errstr(status)));
+ return ADS_ERROR_NT(status);
+ }
}
- if (sock == -1) {
- int rc = errno;
- SAFE_FREE(ap_req.data);
- krb5_auth_con_free(context, auth_context);
- DEBUG(1,("failed to open kpasswd socket to %s (%s)\n",
- kdc_host, strerror(errno)));
- return ADS_ERROR_SYSTEM(rc);
- }
addr_len = sizeof(remote_addr);
if (getpeername(sock, (struct sockaddr *)&remote_addr, &addr_len) != 0) {
close(sock);
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index 82a919455a5..a1fcf8eb073 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -435,7 +435,7 @@ static struct async_req *cli_request_chain(TALLOC_CTX *mem_ctx,
req->async = tmp_reqs;
req->num_async += 1;
- req->async[req->num_async-1] = async_req_new(mem_ctx, ev);
+ req->async[req->num_async-1] = async_req_new(mem_ctx);
if (req->async[req->num_async-1] == NULL) {
DEBUG(0, ("async_req_new failed\n"));
req->num_async -= 1;
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 5892bdc8592..6ddc249c04c 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1494,17 +1494,17 @@ bool cli_session_request(struct cli_state *cli,
*/
uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
struct in_addr dest_ip;
+ NTSTATUS status;
/* SESSION RETARGET */
putip((char *)&dest_ip,cli->inbuf+4);
in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
- cli->fd = open_socket_out(SOCK_STREAM,
- &cli->dest_ss,
- port,
- LONG_CONNECT_TIMEOUT);
- if (cli->fd == -1)
+ status = open_socket_out(&cli->dest_ss, port,
+ LONG_CONNECT_TIMEOUT, &cli->fd);
+ if (!NT_STATUS_IS_OK(status)) {
return False;
+ }
DEBUG(3,("Retargeted\n"));
@@ -1533,6 +1533,78 @@ bool cli_session_request(struct cli_state *cli,
return(True);
}
+static void smb_sock_connected(struct async_req *req)
+{
+ int *pfd = (int *)req->async.priv;
+ int fd;
+ NTSTATUS status;
+
+ status = open_socket_out_defer_recv(req, &fd);
+ if (NT_STATUS_IS_OK(status)) {
+ *pfd = fd;
+ }
+}
+
+static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
+ uint16_t *port, int timeout, int *pfd)
+{
+ struct event_context *ev;
+ struct async_req *r139, *r445;
+ int fd139 = -1;
+ int fd445 = -1;
+ NTSTATUS status;
+
+ if (*port != 0) {
+ return open_socket_out(pss, *port, timeout, pfd);
+ }
+
+ ev = event_context_init(talloc_tos());
+ if (ev == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
+ pss, 445, timeout);
+ r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
+ pss, 139, timeout);
+ if ((r445 == NULL) || (r139 == NULL)) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ r445->async.fn = smb_sock_connected;
+ r445->async.priv = &fd445;
+ r139->async.fn = smb_sock_connected;
+ r139->async.priv = &fd139;
+
+ while ((fd139 == -1) && (r139->state < ASYNC_REQ_DONE)
+ && (fd445 == -1) && (r445->state < ASYNC_REQ_DONE)) {
+ event_loop_once(ev);
+ }
+
+ if ((fd139 != -1) && (fd445 != -1)) {
+ close(fd139);
+ fd139 = -1;
+ }
+
+ if (fd445 != -1) {
+ *port = 445;
+ *pfd = fd445;
+ status = NT_STATUS_OK;
+ goto done;
+ }
+ if (fd139 != -1) {
+ *port = 139;
+ *pfd = fd139;
+ status = NT_STATUS_OK;
+ goto done;
+ }
+
+ status = open_socket_out_defer_recv(r445, &fd445);
+ done:
+ TALLOC_FREE(ev);
+ return status;
+}
+
/****************************************************************************
Open the client sockets.
****************************************************************************/
@@ -1587,16 +1659,11 @@ NTSTATUS cli_connect(struct cli_state *cli,
if (getenv("LIBSMB_PROG")) {
cli->fd = sock_exec(getenv("LIBSMB_PROG"));
} else {
- /* try 445 first, then 139 */
- uint16_t port = cli->port?cli->port:445;
- cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
- port, cli->timeout);
- if (cli->fd == -1 && cli->port == 0) {
- port = 139;
- cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
- port, cli->timeout);
- }
- if (cli->fd != -1) {
+ uint16_t port = cli->port;
+ NTSTATUS status;
+ status = open_smb_socket(&cli->dest_ss, &port,
+ cli->timeout, &cli->fd);
+ if (NT_STATUS_IS_OK(status)) {
cli->port = port;
}
}
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 4597e63c98f..ac68700fd08 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -54,8 +54,6 @@ static void cm_set_password(const char *newpass);
static int port;
static int name_type = 0x20;
-static bool have_ip;
-static struct sockaddr_storage dest_ss;
static struct client_connection *connections;
@@ -133,8 +131,11 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
}
sharename = servicename;
if (*sharename == '\\') {
- server = sharename+2;
- sharename = strchr_m(server,'\\');
+ sharename += 2;
+ if (server == NULL) {
+ server = sharename;
+ }
+ sharename = strchr_m(sharename,'\\');
if (!sharename) {
return NULL;
}
@@ -151,8 +152,6 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
again:
zero_sockaddr(&ss);
- if (have_ip)
- ss = dest_ss;
/* have to open a new connection */
if (!(c=cli_initialise()) || (cli_set_port(c, port) != port)) {
@@ -550,15 +549,6 @@ void cli_cm_set_fallback_after_kerberos(void)
cm_creds.fallback_after_kerberos = true;
}
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_dest_ss(struct sockaddr_storage *pss)
-{
- dest_ss = *pss;
- have_ip = true;
-}
-
/**********************************************************************
split a dfs path into the server, share name, and extrapath components
**********************************************************************/
diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c
index b33d0f09389..1d5582e61d0 100644
--- a/source3/libsmb/clireadwrite.c
+++ b/source3/libsmb/clireadwrite.c
@@ -278,7 +278,7 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx,
struct cli_pull_state *state;
int i;
- result = async_req_new(mem_ctx, ev);
+ result = async_req_new(mem_ctx);
if (result == NULL) {
goto failed;
}
@@ -302,7 +302,7 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx,
state->top_req = 0;
if (size == 0) {
- if (!async_post_status(result, NT_STATUS_OK)) {
+ if (!async_post_status(result, ev, NT_STATUS_OK)) {
goto failed;
}
return result;
@@ -843,7 +843,7 @@ static struct async_req *cli_writeall_send(TALLOC_CTX *mem_ctx,
struct async_req *subreq;
struct cli_writeall_state *state;
- result = async_req_new(mem_ctx, ev);
+ result = async_req_new(mem_ctx);
if (result == NULL) {
goto fail;
}
@@ -969,7 +969,7 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
struct cli_push_state *state;
int i;
- result = async_req_new(mem_ctx, ev);
+ result = async_req_new(mem_ctx);
if (result == NULL) {
goto failed;
}
@@ -1034,7 +1034,7 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
}
if (i == 0) {
- if (!async_post_status(result, NT_STATUS_OK)) {
+ if (!async_post_status(result, ev, NT_STATUS_OK)) {
goto failed;
}
return result;
diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c
index 16b3b109254..af3f7b0dd58 100644
--- a/source3/libsmb/smb_share_modes.c
+++ b/source3/libsmb/smb_share_modes.c
@@ -1,7 +1,7 @@
/*
Samba share mode database library external interface library.
Used by non-Samba products needing access to the Samba share mode db.
-
+
Copyright (C) Jeremy Allison 2005 - 2006
sharemodes_procid functions (C) Copyright (C) Volker Lendecke 2005
@@ -9,17 +9,17 @@
** NOTE! The following LGPL license applies to this module only.
** This does NOT imply that all of Samba is released
** under the LGPL
-
+
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 3 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, see <http://www.gnu.org/licenses/>.
*/
@@ -92,16 +92,16 @@ int smb_share_mode_db_close(struct smbdb_ctx *db_ctx)
return ret;
}
-static TDB_DATA get_locking_key(uint64_t dev, uint64_t ino)
+static TDB_DATA get_locking_key(struct locking_key *lk, uint64_t dev,
+ uint64_t ino)
{
- static struct locking_key lk;
TDB_DATA ld;
- memset(&lk, '\0', sizeof(struct locking_key));
- lk.dev = (SMB_DEV_T)dev;
- lk.inode = (SMB_INO_T)ino;
- ld.dptr = (uint8 *)&lk;
- ld.dsize = sizeof(lk);
+ memset(lk, '\0', sizeof(*lk));
+ lk->dev = (SMB_DEV_T)dev;
+ lk->inode = (SMB_INO_T)ino;
+ ld.dptr = (uint8 *)lk;
+ ld.dsize = sizeof(*lk);
return ld;
}
@@ -113,14 +113,17 @@ int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino)
{
- return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(dev, ino));
+ struct locking_key lk;
+ return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino));
}
-
+
int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino)
{
- return tdb_chainunlock(db_ctx->smb_tdb, get_locking_key(dev, ino));
+ struct locking_key lk;
+ return tdb_chainunlock(db_ctx->smb_tdb,
+ get_locking_key(&lk, dev, ino));
}
/*
@@ -172,6 +175,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
struct smb_share_mode_entry **pp_list,
unsigned char *p_delete_on_close)
{
+ struct locking_key lk;
TDB_DATA db_data;
struct smb_share_mode_entry *list = NULL;
int num_share_modes = 0;
@@ -183,7 +187,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
*pp_list = NULL;
*p_delete_on_close = 0;
- db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(dev, ino));
+ db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino));
if (!db_data.dptr) {
return 0;
}
@@ -258,7 +262,8 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
const char *filename) /* Must be relative utf8 path. */
{
TDB_DATA db_data;
- TDB_DATA locking_key = get_locking_key(dev, ino);
+ struct locking_key lk;
+ TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
int orig_num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;
@@ -371,7 +376,8 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
const struct smb_share_mode_entry *del_entry)
{
TDB_DATA db_data;
- TDB_DATA locking_key = get_locking_key(dev, ino);
+ struct locking_key lk;
+ TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
int orig_num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;
@@ -473,7 +479,8 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
const struct smb_share_mode_entry *new_entry)
{
TDB_DATA db_data;
- TDB_DATA locking_key = get_locking_key(dev, ino);
+ struct locking_key lk;
+ TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
int num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c
index a4a317d9053..a86d39948d8 100644
--- a/source3/modules/onefs_open.c
+++ b/source3/modules/onefs_open.c
@@ -1,8 +1,8 @@
/*
* Unix SMB/CIFS implementation.
*
- * This file began with some code from source3/smbd/open.c and modified it to
- * work with ifs_createfile.
+ * This file began with some code from source3/smbd/open.c and has been
+ * modified it work with ifs_createfile.
*
* ifs_createfile is a CIFS-specific syscall for opening/files and
* directories. It adds support for:
@@ -459,7 +459,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
fname));
- return print_fsp_open(req, conn, fname, req->vuid, fsp);
+ return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
}
if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c
index 63cc904bed1..3ac5a4971b7 100644
--- a/source3/modules/vfs_smb_traffic_analyzer.c
+++ b/source3/modules/vfs_smb_traffic_analyzer.c
@@ -78,6 +78,7 @@ static int smb_traffic_analyzer_connect_inet_socket(vfs_handle_struct *handle,
for (res = ailist; res; res = res->ai_next) {
struct sockaddr_storage ss;
+ NTSTATUS status;
if (!res->ai_addr || res->ai_addrlen == 0) {
continue;
@@ -86,8 +87,8 @@ static int smb_traffic_analyzer_connect_inet_socket(vfs_handle_struct *handle,
ZERO_STRUCT(ss);
memcpy(&ss, res->ai_addr, res->ai_addrlen);
- sockfd = open_socket_out(SOCK_STREAM, &ss, port, 10000);
- if (sockfd != -1) {
+ status = open_socket_out(&ss, port, 10000, &sockfd);
+ if (NT_STATUS_IS_OK(status)) {
break;
}
}
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 274c79904e5..cb0ba47572e 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -4630,7 +4630,7 @@ static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
{
void *parm_ptr;
- if (parm.ptr == NULL); {
+ if (parm.ptr == NULL) {
return;
}
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index a2d334230dd..3fd31e28676 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -2618,9 +2618,8 @@ static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
goto fail;
}
- result->trans.sock.fd = open_socket_out(SOCK_STREAM, &addr, port, 60);
- if (result->trans.sock.fd == -1) {
- status = map_nt_error_from_unix(errno);
+ status = open_socket_out(&addr, port, 60, &result->trans.sock.fd);
+ if (!NT_STATUS_IS_OK(status)) {
goto fail;
}
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 1cff95dcaba..7d1f8242342 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -105,8 +105,7 @@ static bool pipe_init_outgoing_data(pipes_struct *p)
static struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
const char *pipe_name,
const char *client_address,
- struct auth_serversupplied_info *server_info,
- uint16_t vuid)
+ struct auth_serversupplied_info *server_info)
{
pipes_struct *p;
@@ -1125,8 +1124,7 @@ NTSTATUS np_open(struct smb_request *smb_req, const char *name,
p = make_internal_rpc_pipe_p(fsp->fake_file_handle, name,
conn->client_address,
- conn->server_info,
- smb_req->vuid);
+ conn->server_info);
fsp->fake_file_handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
fsp->fake_file_handle->private_data = p;
diff --git a/source3/samba4.m4 b/source3/samba4.m4
index 5199363fc3e..a7916ef7942 100644
--- a/source3/samba4.m4
+++ b/source3/samba4.m4
@@ -65,13 +65,8 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.3,
SMB_INCLUDE_MK(../lib/tdb/python.mk)
-SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent >= 0.9.0,
- [],
- [
- m4_include(../lib/tevent/libtevent.m4)
- SMB_INCLUDE_MK(../lib/tevent/config.mk)
- AC_CONFIG_FILES(../lib/tevent/tevent.pc)
- ]
+SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent >= 0.9.2,
+ [],[m4_include(../lib/tevent/samba.m4)]
)
SMB_INCLUDE_MK(../lib/tevent/python.mk)
@@ -114,8 +109,6 @@ SMB_INCLUDE_MK(lib/ldb/python.mk)
SMB_ENABLE(swig_ldb,YES)
m4_include(lib/tls/config.m4)
-teventdir="../lib/tevent"
-m4_include(../lib/tevent/libtevent.m4)
dnl m4_include(auth/kerberos/config.m4)
m4_include(auth/gensec/config.m4)
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 8466e841799..67e6067b260 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -284,7 +284,7 @@ static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
if (CVAL(lenbuf,0) == 0 &&
min_recv_size &&
- smb_len_large(lenbuf) > min_recv_size && /* Could be a UNIX large writeX. */
+ smb_len_large(lenbuf) > (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE) && /* Could be a UNIX large writeX. */
!srv_is_signing_active()) {
return receive_smb_raw_talloc_partial_read(
diff --git a/source3/torture/nbio.c b/source3/torture/nbio.c
index 81d0eb816b9..a010c80985e 100644
--- a/source3/torture/nbio.c
+++ b/source3/torture/nbio.c
@@ -111,7 +111,9 @@ static void sigsegv(int sig)
printf("segv at line %d\n", line_count);
slprintf(line, sizeof(line), "/usr/X11R6/bin/xterm -e gdb /proc/%d/exe %d",
(int)getpid(), (int)getpid());
- system(line);
+ if (system(line) == -1) {
+ printf("system() failed\n");
+ }
exit(1);
}
@@ -280,10 +282,16 @@ static void delete_fn(const char *mnt, file_info *finfo, const char *name, void
n = SMB_STRDUP(name);
n[strlen(n)-1] = 0;
- asprintf(&s, "%s%s", n, finfo->name);
+ if (asprintf(&s, "%s%s", n, finfo->name) == -1) {
+ printf("asprintf failed\n");
+ return;
+ }
if (finfo->mode & aDIR) {
char *s2;
- asprintf(&s2, "%s\\*", s);
+ if (asprintf(&s2, "%s\\*", s) == -1) {
+ printf("asprintf failed\n");
+ return;
+ }
cli_list(c, s2, aDIR, delete_fn, NULL);
nb_rmdir(s);
} else {
@@ -297,7 +305,10 @@ static void delete_fn(const char *mnt, file_info *finfo, const char *name, void
void nb_deltree(const char *dname)
{
char *mask;
- asprintf(&mask, "%s\\*", dname);
+ if (asprintf(&mask, "%s\\*", dname) == -1) {
+ printf("asprintf failed\n");
+ return;
+ }
total_deleted = 0;
cli_list(c, mask, aDIR, delete_fn, NULL);
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 63942da2e5b..8a1a61e79ac 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -1213,7 +1213,9 @@ static bool run_tcon2_test(int dummy)
printf("starting tcon2 test\n");
- asprintf(&service, "\\\\%s\\%s", host, share);
+ if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
+ return false;
+ }
status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
@@ -5280,8 +5282,13 @@ static bool run_local_rbtree(int dummy)
for (i=0; i<1000; i++) {
char *key, *value;
- asprintf(&key, "key%ld", random());
- asprintf(&value, "value%ld", random());
+ if (asprintf(&key, "key%ld", random()) == -1) {
+ goto done;
+ }
+ if (asprintf(&value, "value%ld", random()) == -1) {
+ SAFE_FREE(key);
+ goto done;
+ }
if (!rbt_testval(db, key, value)) {
SAFE_FREE(key);
@@ -5290,7 +5297,10 @@ static bool run_local_rbtree(int dummy)
}
SAFE_FREE(value);
- asprintf(&value, "value%ld", random());
+ if (asprintf(&value, "value%ld", random()) == -1) {
+ SAFE_FREE(key);
+ goto done;
+ }
if (!rbt_testval(db, key, value)) {
SAFE_FREE(key);
@@ -5483,6 +5493,70 @@ static bool run_local_memcache(int dummy)
return ret;
}
+static void wbclient_done(struct async_req *req)
+{
+ NTSTATUS status;
+ struct winbindd_response *wb_resp;
+ int *i = (int *)req->async.priv;
+
+ status = wb_trans_recv(req, req, &wb_resp);
+ TALLOC_FREE(req);
+ *i += 1;
+ d_printf("wb_trans_recv %d returned %s\n", *i, nt_errstr(status));
+}
+
+static bool run_local_wbclient(int dummy)
+{
+ struct event_context *ev;
+ struct wb_context **wb_ctx;
+ struct winbindd_request wb_req;
+ bool result = false;
+ int i, j;
+
+ BlockSignals(True, SIGPIPE);
+
+ ev = event_context_init(talloc_tos());
+ if (ev == NULL) {
+ goto fail;
+ }
+
+ wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
+ if (wb_ctx == NULL) {
+ goto fail;
+ }
+
+ ZERO_STRUCT(wb_req);
+ wb_req.cmd = WINBINDD_PING;
+
+ for (i=0; i<torture_numops; i++) {
+ wb_ctx[i] = wb_context_init(ev);
+ if (wb_ctx[i] == NULL) {
+ goto fail;
+ }
+ for (j=0; j<5; j++) {
+ struct async_req *req;
+ req = wb_trans_send(ev, ev, wb_ctx[i],
+ (j % 2) == 0, &wb_req);
+ if (req == NULL) {
+ goto fail;
+ }
+ req->async.fn = wbclient_done;
+ req->async.priv = &i;
+ }
+ }
+
+ i = 0;
+
+ while (i < 5 * torture_numops) {
+ event_loop_once(ev);
+ }
+
+ result = true;
+ fail:
+ TALLOC_FREE(ev);
+ return result;
+}
+
static double create_procs(bool (*fn)(int), bool *result)
{
int i, status;
@@ -5642,6 +5716,7 @@ static struct {
{ "LOCAL-RBTREE", run_local_rbtree, 0},
{ "LOCAL-MEMCACHE", run_local_memcache, 0},
{ "LOCAL-STREAM-NAME", run_local_stream_name, 0},
+ { "LOCAL-WBCLIENT", run_local_wbclient, 0},
{NULL, NULL, 0}};
diff --git a/source3/torture/utable.c b/source3/torture/utable.c
index 7032cea99b8..e36b0388c4e 100644
--- a/source3/torture/utable.c
+++ b/source3/torture/utable.c
@@ -84,7 +84,11 @@ bool torture_utable(int dummy)
d_printf("Failed to create valid.dat - %s", strerror(errno));
return False;
}
- write(fd, valid, 0x10000);
+ if (write(fd, valid, 0x10000) != 0x10000) {
+ d_printf("Failed to create valid.dat - %s", strerror(errno));
+ close(fd);
+ return false;
+ }
close(fd);
d_printf("wrote valid.dat\n");
diff --git a/source3/utils/smbfilter.c b/source3/utils/smbfilter.c
index 1e22a402013..1fdea818d6e 100644
--- a/source3/utils/smbfilter.c
+++ b/source3/utils/smbfilter.c
@@ -141,10 +141,11 @@ static bool send_smb(int fd, char *buffer)
static void filter_child(int c, struct sockaddr_storage *dest_ss)
{
- int s;
+ NTSTATUS status;
+ int s = -1;
/* we have a connection from a new client, now connect to the server */
- s = open_socket_out(SOCK_STREAM, dest_ss, 445, LONG_CONNECT_TIMEOUT);
+ status = open_socket_out(dest_ss, 445, LONG_CONNECT_TIMEOUT, &s);
if (s == -1) {
char addr[INET6_ADDRSTRLEN];
diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c
index 6be55ef03c6..ca07f230ab0 100644
--- a/source3/winbindd/idmap.c
+++ b/source3/winbindd/idmap.c
@@ -735,6 +735,17 @@ NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id)
maps[0] = id;
maps[1] = NULL;
+ /*
+ * Always give passdb a chance first
+ */
+
+ dom = idmap_init_passdb_domain(NULL);
+ if ((dom != NULL)
+ && NT_STATUS_IS_OK(dom->methods->unixids_to_sids(dom, maps))
+ && id->status == ID_MAPPED) {
+ return NT_STATUS_OK;
+ }
+
dom = idmap_find_domain(domname);
if (dom == NULL) {
return NT_STATUS_NONE_MAPPED;
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 92ce1f98509..3869ac57712 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -88,15 +88,6 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
struct winbindd_response *wb_resp);
NTSTATUS wb_resp_write_recv(struct async_req *req);
-struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- int fd,
- struct winbindd_request *wb_req,
- struct timeval timeout,
- size_t reply_max_extra_data);
-NTSTATUS wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
- struct winbindd_response **presp);
-
/* The following definitions come from winbindd/winbindd_ads.c */
diff --git a/source4/auth/kerberos/config.mk b/source4/auth/kerberos/config.mk
index b724b8df377..822bf398a76 100644
--- a/source4/auth/kerberos/config.mk
+++ b/source4/auth/kerberos/config.mk
@@ -2,7 +2,7 @@
# Start SUBSYSTEM KERBEROS
[SUBSYSTEM::KERBEROS]
PUBLIC_DEPENDENCIES = HEIMDAL_KRB5 NDR_KRB5PAC samba_socket LIBCLI_RESOLVE
-PRIVATE_DEPENDENCIES = ASN1_UTIL auth_sam_reply LIBPACKET LIBNDR
+PRIVATE_DEPENDENCIES = ASN1_UTIL auth_sam_reply LIBTEVENT LIBPACKET LIBNDR
# End SUBSYSTEM KERBEROS
#################################
diff --git a/source4/auth/kerberos/krb5_init_context.c b/source4/auth/kerberos/krb5_init_context.c
index 2f0a2317a0a..6e885842f31 100644
--- a/source4/auth/kerberos/krb5_init_context.c
+++ b/source4/auth/kerberos/krb5_init_context.c
@@ -22,11 +22,11 @@
#include "includes.h"
#include "system/kerberos.h"
+#include <tevent.h>
#include "auth/kerberos/kerberos.h"
#include "lib/socket/socket.h"
#include "lib/stream/packet.h"
#include "system/network.h"
-#include "lib/events/events.h"
#include "param/param.h"
#include "libcli/resolve/resolve.h"
@@ -159,9 +159,9 @@ static void smb_krb5_socket_send(struct smb_krb5_socket *smb_krb5)
if (!NT_STATUS_IS_OK(status)) return;
- EVENT_FD_READABLE(smb_krb5->fde);
+ TEVENT_FD_READABLE(smb_krb5->fde);
- EVENT_FD_NOT_WRITEABLE(smb_krb5->fde);
+ TEVENT_FD_NOT_WRITEABLE(smb_krb5->fde);
return;
}
@@ -175,22 +175,22 @@ static void smb_krb5_socket_handler(struct tevent_context *ev, struct tevent_fd
struct smb_krb5_socket *smb_krb5 = talloc_get_type(private, struct smb_krb5_socket);
switch (smb_krb5->hi->proto) {
case KRB5_KRBHST_UDP:
- if (flags & EVENT_FD_READ) {
+ if (flags & TEVENT_FD_READ) {
smb_krb5_socket_recv(smb_krb5);
return;
}
- if (flags & EVENT_FD_WRITE) {
+ if (flags & TEVENT_FD_WRITE) {
smb_krb5_socket_send(smb_krb5);
return;
}
/* not reached */
return;
case KRB5_KRBHST_TCP:
- if (flags & EVENT_FD_READ) {
+ if (flags & TEVENT_FD_READ) {
packet_recv(smb_krb5->packet);
return;
}
- if (flags & EVENT_FD_WRITE) {
+ if (flags & TEVENT_FD_WRITE) {
packet_queue_run(smb_krb5->packet);
return;
}
@@ -284,24 +284,24 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
* drop) and mark as AUTOCLOSE along with the fde */
/* Ths is equivilant to EVENT_FD_READABLE(smb_krb5->fde) */
- smb_krb5->fde = event_add_fd(ev, smb_krb5->sock,
- socket_get_fd(smb_krb5->sock),
- EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
- smb_krb5_socket_handler, smb_krb5);
+ smb_krb5->fde = tevent_add_fd(ev, smb_krb5->sock,
+ socket_get_fd(smb_krb5->sock),
+ TEVENT_FD_READ,
+ smb_krb5_socket_handler, smb_krb5);
/* its now the job of the event layer to close the socket */
+ tevent_fd_set_close_fn(smb_krb5->fde, socket_tevent_fd_close_fn);
socket_set_flags(smb_krb5->sock, SOCKET_FLAG_NOCLOSE);
- event_add_timed(ev, smb_krb5,
- timeval_current_ofs(timeout, 0),
- smb_krb5_request_timeout, smb_krb5);
+ tevent_add_timer(ev, smb_krb5,
+ timeval_current_ofs(timeout, 0),
+ smb_krb5_request_timeout, smb_krb5);
-
smb_krb5->status = NT_STATUS_OK;
smb_krb5->reply = data_blob(NULL, 0);
switch (hi->proto) {
case KRB5_KRBHST_UDP:
- EVENT_FD_WRITEABLE(smb_krb5->fde);
+ TEVENT_FD_WRITEABLE(smb_krb5->fde);
smb_krb5->request = send_blob;
break;
case KRB5_KRBHST_TCP:
@@ -329,7 +329,7 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
return EINVAL;
}
while ((NT_STATUS_IS_OK(smb_krb5->status)) && !smb_krb5->reply.length) {
- if (event_loop_once(ev) != 0) {
+ if (tevent_loop_once(ev) != 0) {
talloc_free(smb_krb5);
return EINVAL;
}
diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4
index 5be4189e064..e51a8ac1464 100644
--- a/source4/build/m4/public.m4
+++ b/source4/build/m4/public.m4
@@ -155,6 +155,14 @@ SMB_INFO_ENABLES="$SMB_INFO_ENABLES
\$enabled{$1} = \"$2\";"
])
+dnl SMB_MAKE_SETTINGS(text)
+AC_DEFUN([SMB_MAKE_SETTINGS],
+[
+MAKE_SETTINGS="$MAKE_SETTINGS
+$1
+"
+])
+
dnl SMB_WRITE_MAKEVARS(path, skip_vars)
AC_DEFUN([SMB_WRITE_MAKEVARS],
[
diff --git a/source4/configure.ac b/source4/configure.ac
index debdc39d58a..6c8fb0efc28 100644
--- a/source4/configure.ac
+++ b/source4/configure.ac
@@ -60,13 +60,8 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.3,
SMB_INCLUDE_MK(../lib/tdb/python.mk)
-SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent >= 0.9.0,
- [],
- [
- m4_include(../lib/tevent/libtevent.m4)
- SMB_INCLUDE_MK(../lib/tevent/config.mk)
- AC_CONFIG_FILES(../lib/tevent/tevent.pc)
- ]
+SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent >= 0.9.2,
+ [],[m4_include(../lib/tevent/samba.m4)]
)
SMB_INCLUDE_MK(../lib/tevent/python.mk)
diff --git a/source4/headermap.txt b/source4/headermap.txt
index d5e70a73048..c27ec2f2dea 100644
--- a/source4/headermap.txt
+++ b/source4/headermap.txt
@@ -49,11 +49,8 @@ param/share.h: share.h
../lib/util/util_tdb.h: util_tdb.h
../lib/util/util_ldb.h: util_ldb.h
../lib/util/wrap_xattr.h: wrap_xattr.h
-lib/events/events.h: events/events.h
-lib/events/events_internal.h: events/events_internal.h
libcli/ldap/ldap_ndr.h: ldap_ndr.h
lib/events/events.h: events.h
-lib/events/events_internal.h: events_internal.h
../lib/tevent/tevent.h: tevent.h
../lib/tevent/tevent_internal.h: tevent_internal.h
auth/session.h: samba/session.h
diff --git a/source4/lib/events/config.mk b/source4/lib/events/config.mk
index a1b2cd218ac..c07a21bc75b 100644
--- a/source4/lib/events/config.mk
+++ b/source4/lib/events/config.mk
@@ -4,4 +4,4 @@ CFLAGS = -Ilib/events
LIBEVENTS_OBJ_FILES = $(addprefix $(libeventssrcdir)/, tevent_s4.o)
-PUBLIC_HEADERS += $(addprefix $(libeventssrcdir)/, events.h events_internal.h)
+PUBLIC_HEADERS += $(addprefix $(libeventssrcdir)/, events.h)
diff --git a/source4/lib/events/events.h b/source4/lib/events/events.h
index 698ff2919ba..1b2dbde32b1 100644
--- a/source4/lib/events/events.h
+++ b/source4/lib/events/events.h
@@ -3,5 +3,5 @@
#define TEVENT_COMPAT_DEFINES 1
#include <../lib/tevent/tevent.h>
struct tevent_context *s4_event_context_init(TALLOC_CTX *mem_ctx);
-struct tevent_context *event_context_find(TALLOC_CTX *mem_ctx);
+struct tevent_context *event_context_find(TALLOC_CTX *mem_ctx) _DEPRECATED_;
#endif /* __LIB_EVENTS_H__ */
diff --git a/source4/lib/events/events_internal.h b/source4/lib/events/events_internal.h
deleted file mode 100644
index 055bfe1a92b..00000000000
--- a/source4/lib/events/events_internal.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifndef __LIB_EVENTS_INTERNAL_H__
-#define __LIB_EVENTS_INTERNAL_H__
-#define TEVENT_COMPAT_DEFINES 1
-#include <../lib/tevent/tevent_internal.h>
-#endif /* __LIB_EVENTS_INTERNAL_H__ */
diff --git a/source4/lib/events/tevent_s4.c b/source4/lib/events/tevent_s4.c
index b3de7e667a5..34a34a8e0b3 100644
--- a/source4/lib/events/tevent_s4.c
+++ b/source4/lib/events/tevent_s4.c
@@ -17,38 +17,37 @@
*/
#include "includes.h"
-#include <events.h>
-#include <events_internal.h>
+#include "lib/events/events.h"
/*
this is used to catch debug messages from events
*/
-static void ev_wrap_debug(void *context, enum ev_debug_level level,
+static void ev_wrap_debug(void *context, enum tevent_debug_level level,
const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
-static void ev_wrap_debug(void *context, enum ev_debug_level level,
+static void ev_wrap_debug(void *context, enum tevent_debug_level level,
const char *fmt, va_list ap)
{
int samba_level = -1;
char *s = NULL;
switch (level) {
- case EV_DEBUG_FATAL:
+ case TEVENT_DEBUG_FATAL:
samba_level = 0;
break;
- case EV_DEBUG_ERROR:
+ case TEVENT_DEBUG_ERROR:
samba_level = 1;
break;
- case EV_DEBUG_WARNING:
+ case TEVENT_DEBUG_WARNING:
samba_level = 2;
break;
- case EV_DEBUG_TRACE:
+ case TEVENT_DEBUG_TRACE:
samba_level = 5;
break;
};
vasprintf(&s, fmt, ap);
if (!s) return;
- DEBUG(samba_level, ("events: %s\n", s));
+ DEBUG(samba_level, ("tevent: %s\n", s));
free(s);
}
@@ -63,10 +62,27 @@ struct tevent_context *s4_event_context_init(TALLOC_CTX *mem_ctx)
{
struct tevent_context *ev;
- ev = event_context_init_byname(mem_ctx, NULL);
+ ev = tevent_context_init_byname(mem_ctx, NULL);
if (ev) {
- ev_set_debug(ev, ev_wrap_debug, NULL);
+ tevent_set_debug(ev, ev_wrap_debug, NULL);
}
return 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 tevent_context *event_context_find(TALLOC_CTX *mem_ctx)
+{
+ struct tevent_context *ev = talloc_find_parent_bytype(mem_ctx, struct tevent_context);
+ if (ev == NULL) {
+ ev = tevent_context_init(mem_ctx);
+ }
+ return ev;
+}
diff --git a/source4/lib/registry/pyregistry.c b/source4/lib/registry/pyregistry.c
index 2d2f2fb6859..357305c4de3 100644
--- a/source4/lib/registry/pyregistry.c
+++ b/source4/lib/registry/pyregistry.c
@@ -357,7 +357,7 @@ static PyObject *py_open_ldb_file(PyObject *self, PyObject *args, PyObject *kwar
session_info = NULL; /* FIXME */
result = reg_open_ldb_file(NULL, location, session_info, credentials,
- event_context_init(NULL), lp_ctx, &key);
+ tevent_context_init(NULL), lp_ctx, &key);
PyErr_WERROR_IS_ERR_RAISE(result);
return py_talloc_import(&PyHiveKey, key);
diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c
index a869ed44404..4cbcb09a102 100644
--- a/source4/lib/registry/regf.c
+++ b/source4/lib/registry/regf.c
@@ -543,7 +543,7 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, struct hive_key *key,
if (vk->data_length & 0x80000000) {
vk->data_length &=~0x80000000;
- data->data = (uint8_t *)&vk->data_offset;
+ data->data = talloc_memdup(ctx, (uint8_t *)&vk->data_offset, vk->data_length);
data->length = vk->data_length;
} else {
*data = hbin_get(regf, vk->data_offset);
@@ -2045,7 +2045,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location,
struct tdr_pull *pull;
int i;
- regf = (struct regf_data *)talloc_zero(NULL, struct regf_data);
+ regf = (struct regf_data *)talloc_zero(parent_ctx, struct regf_data);
regf->iconv_convenience = iconv_convenience;
diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c
index c9f1248bf8e..d997cb0fde5 100644
--- a/source4/lib/registry/tools/common.c
+++ b/source4/lib/registry/tools/common.c
@@ -51,7 +51,7 @@ struct registry_key *reg_common_open_file(const char *path,
struct registry_context *h = NULL;
WERROR error;
- error = reg_open_hive(NULL, path, NULL, creds, ev_ctx, lp_ctx, &hive_root);
+ error = reg_open_hive(ev_ctx, path, NULL, creds, ev_ctx, lp_ctx, &hive_root);
if(!W_ERROR_IS_OK(error)) {
fprintf(stderr, "Unable to open '%s': %s \n",
diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c
index cca009a0e2c..948ed49312d 100644
--- a/source4/lib/registry/tools/regtree.c
+++ b/source4/lib/registry/tools/regtree.c
@@ -55,13 +55,16 @@ static void print_tree(int level, struct registry_key *p,
&keyname,
NULL,
NULL)); i++) {
- SMB_ASSERT(strlen(keyname) > 0);
+
+ SMB_ASSERT(strlen(keyname) > 0);
if (!W_ERROR_IS_OK(reg_open_key(mem_ctx, p, keyname, &subkey)))
- continue;
+ continue;
+
print_tree(level+1, subkey, (fullpath && strlen(name))?
- talloc_asprintf(mem_ctx, "%s\\%s",
- name, keyname):
- keyname, fullpath, novals);
+ talloc_asprintf(mem_ctx, "%s\\%s",
+ name, keyname):
+ keyname, fullpath, novals);
+ talloc_free(subkey);
}
talloc_free(mem_ctx);
diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c
index 26cdac99a3d..9d30e0a77ef 100644
--- a/source4/lib/socket/socket.c
+++ b/source4/lib/socket/socket.c
@@ -37,6 +37,15 @@ static int socket_destructor(struct socket_context *sock)
return 0;
}
+_PUBLIC_ void socket_tevent_fd_close_fn(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ int fd,
+ void *private_data)
+{
+ /* this might be the socket_wrapper swrap_close() */
+ close(fd);
+}
+
_PUBLIC_ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *ops,
struct socket_context **new_sock,
enum socket_type type, uint32_t flags)
diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h
index 7a27e3070b7..e9338127c4b 100644
--- a/source4/lib/socket/socket.h
+++ b/source4/lib/socket/socket.h
@@ -21,6 +21,7 @@
#define _SAMBA_SOCKET_H
struct tevent_context;
+struct tevent_fd;
struct socket_context;
enum socket_type {
@@ -205,6 +206,11 @@ NTSTATUS socket_connect_multi(TALLOC_CTX *mem_ctx, const char *server_address,
void set_socket_options(int fd, const char *options);
void socket_set_flags(struct socket_context *socket, unsigned flags);
+void socket_tevent_fd_close_fn(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ int fd,
+ void *private_data);
+
extern bool testnonblock;
#endif /* _SAMBA_SOCKET_H */
diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk
index 2e50596dadc..11157c5b63c 100644
--- a/source4/libcli/ldap/config.mk
+++ b/source4/libcli/ldap/config.mk
@@ -1,5 +1,5 @@
[SUBSYSTEM::LIBCLI_LDAP]
-PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET
+PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTEVENT LIBPACKET
PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS ASN1_UTIL \
LDAP_ENCODE LIBNDR LP_RESOLVE gensec
diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c
index 18784135cc5..e30d5032fb5 100644
--- a/source4/libcli/ldap/ldap_client.c
+++ b/source4/libcli/ldap/ldap_client.c
@@ -23,10 +23,10 @@
*/
#include "includes.h"
+#include <tevent.h>
+#include "lib/socket/socket.h"
#include "../lib/util/asn1.h"
#include "../lib/util/dlinklist.h"
-#include "lib/events/events.h"
-#include "lib/socket/socket.h"
#include "libcli/ldap/ldap.h"
#include "libcli/ldap/ldap_proto.h"
#include "libcli/ldap/ldap_client.h"
@@ -229,11 +229,11 @@ static void ldap_io_handler(struct tevent_context *ev, struct tevent_fd *fde,
{
struct ldap_connection *conn = talloc_get_type(private_data,
struct ldap_connection);
- if (flags & EVENT_FD_WRITE) {
+ if (flags & TEVENT_FD_WRITE) {
packet_queue_run(conn->packet);
if (!tls_enabled(conn->sock)) return;
}
- if (flags & EVENT_FD_READ) {
+ if (flags & TEVENT_FD_READ) {
ldap_read_io_handler(private_data, flags);
}
}
@@ -387,14 +387,15 @@ static void ldap_connect_got_sock(struct composite_context *ctx,
struct ldap_connection *conn)
{
/* setup a handler for events on this socket */
- conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock,
- socket_get_fd(conn->sock),
- EVENT_FD_READ | EVENT_FD_AUTOCLOSE, ldap_io_handler, conn);
+ conn->event.fde = tevent_add_fd(conn->event.event_ctx, conn->sock,
+ socket_get_fd(conn->sock),
+ TEVENT_FD_READ, ldap_io_handler, conn);
if (conn->event.fde == NULL) {
composite_error(ctx, NT_STATUS_INTERNAL_ERROR);
return;
}
+ tevent_fd_set_close_fn(conn->event.fde, socket_tevent_fd_close_fn);
socket_set_flags(conn->sock, SOCKET_FLAG_NOCLOSE);
talloc_steal(conn, conn->sock);
@@ -621,8 +622,8 @@ _PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn,
req->state = LDAP_REQUEST_DONE;
/* we can't call the async callback now, as it isn't setup, so
call it as next event */
- event_add_timed(conn->event.event_ctx, req, timeval_zero(),
- ldap_request_complete, req);
+ tevent_add_timer(conn->event.event_ctx, req, timeval_zero(),
+ ldap_request_complete, req);
return req;
}
@@ -630,17 +631,17 @@ _PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn,
DLIST_ADD(conn->pending, req);
/* put a timeout on the request */
- req->time_event = event_add_timed(conn->event.event_ctx, req,
- timeval_current_ofs(conn->timeout, 0),
- ldap_request_timeout, req);
+ req->time_event = tevent_add_timer(conn->event.event_ctx, req,
+ timeval_current_ofs(conn->timeout, 0),
+ ldap_request_timeout, req);
return req;
failed:
req->status = status;
req->state = LDAP_REQUEST_ERROR;
- event_add_timed(conn->event.event_ctx, req, timeval_zero(),
- ldap_request_complete, req);
+ tevent_add_timer(conn->event.event_ctx, req, timeval_zero(),
+ ldap_request_complete, req);
return req;
}
@@ -653,7 +654,7 @@ failed:
_PUBLIC_ NTSTATUS ldap_request_wait(struct ldap_request *req)
{
while (req->state < LDAP_REQUEST_DONE) {
- if (event_loop_once(req->conn->event.event_ctx) != 0) {
+ if (tevent_loop_once(req->conn->event.event_ctx) != 0) {
req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
break;
}
@@ -768,7 +769,7 @@ _PUBLIC_ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_mes
NT_STATUS_HAVE_NO_MEMORY(req);
while (req->state < LDAP_REQUEST_DONE && n >= req->num_replies) {
- if (event_loop_once(req->conn->event.event_ctx) != 0) {
+ if (tevent_loop_once(req->conn->event.event_ctx) != 0) {
return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
}
}
diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4
index fe1997b4371..a6f79dfbb38 100644
--- a/source4/ntvfs/posix/config.m4
+++ b/source4/ntvfs/posix/config.m4
@@ -30,8 +30,7 @@ if test x"$ac_cv_func_ext_blkid_get_cache" = x"yes"; then
SMB_ENABLE(BLKID,YES)
fi
-AC_CHECK_HEADERS(libaio.h)
SMB_ENABLE(pvfs_aio,NO)
-if test x"$ac_cv_header_libaio_h" = x"yes"; then
+if test x"$tevent_cv_aio_support" = x"yes"; then
SMB_ENABLE(pvfs_aio,YES)
fi
diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk
index ec1cdf3659b..1d7949214ac 100644
--- a/source4/ntvfs/posix/config.mk
+++ b/source4/ntvfs/posix/config.mk
@@ -29,7 +29,7 @@ pvfs_acl_nfs4_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_nfs4.o
################################################
[SUBSYSTEM::pvfs_aio]
-PRIVATE_DEPENDENCIES = LIBTEVENT LIBAIO_LINUX
+PRIVATE_DEPENDENCIES = LIBTEVENT LIBTEVENT_EXT
################################################
pvfs_aio_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_aio.o
diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c
index f7aa91dd0e1..42aac0b0974 100644
--- a/source4/ntvfs/sysdep/inotify.c
+++ b/source4/ntvfs/sysdep/inotify.c
@@ -23,8 +23,8 @@
#include "includes.h"
#include "system/filesys.h"
+#include <tevent.h>
#include "ntvfs/sysdep/sys_notify.h"
-#include "lib/events/events.h"
#include "../lib/util/dlinklist.h"
#include "libcli/raw/smb.h"
#include "param/param.h"
@@ -249,8 +249,11 @@ static void inotify_handler(struct tevent_context *ev, struct tevent_fd *fde,
static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
{
struct inotify_private *in;
+ struct tevent_fd *fde;
+
in = talloc(ctx, struct inotify_private);
NT_STATUS_HAVE_NO_MEMORY(in);
+
in->fd = inotify_init();
if (in->fd == -1) {
DEBUG(0,("Failed to init inotify - %s\n", strerror(errno)));
@@ -263,8 +266,19 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
ctx->private_data = in;
/* add a event waiting for the inotify fd to be readable */
- event_add_fd(ctx->ev, in, in->fd, EVENT_FD_READ|EVENT_FD_AUTOCLOSE, inotify_handler, in);
-
+ fde = tevent_add_fd(ctx->ev, in, in->fd,
+ TEVENT_FD_READ, inotify_handler, in);
+ if (!fde) {
+ if (errno == 0) {
+ errno = ENOMEM;
+ }
+ DEBUG(0,("Failed to tevent_add_fd() - %s\n", strerror(errno)));
+ talloc_free(in);
+ return map_nt_error_from_unix(errno);
+ }
+
+ tevent_fd_set_auto_close(fde);
+
return NT_STATUS_OK;
}
diff --git a/source4/selftest/tests.sh b/source4/selftest/tests.sh
index 0a5bdf62cde..56cbacbdaf7 100755
--- a/source4/selftest/tests.sh
+++ b/source4/selftest/tests.sh
@@ -401,7 +401,7 @@ plantest "samr.python" dc $SUBUNITRUN samba.tests.dcerpc.sam
plantest "dcerpc.bare.python" dc $SUBUNITRUN samba.tests.dcerpc.bare
plantest "unixinfo.python" dc $SUBUNITRUN samba.tests.dcerpc.unix
plantest "samdb.python" none $SUBUNITRUN samba.tests.samdb
-plantest "events.python" none PYTHONPATH="$PYTHONPATH:../lib/tevent" $SUBUNITRUN tests
+plantest "tevent.python" none PYTHONPATH="$PYTHONPATH:../lib/tevent" $SUBUNITRUN tests
plantest "messaging.python" none PYTHONPATH="$PYTHONPATH:lib/messaging/tests" $SUBUNITRUN bindings
plantest "samba3sam.python" none PYTHONPATH="$PYTHONPATH:dsdb/samdb/ldb_modules/tests" $SUBUNITRUN samba3sam
plantest "subunit.python" none $SUBUNITRUN subunit
diff --git a/source4/smbd/config.mk b/source4/smbd/config.mk
index e0b09f4b8c2..a76d10cbe72 100644
--- a/source4/smbd/config.mk
+++ b/source4/smbd/config.mk
@@ -2,7 +2,7 @@
[SUBSYSTEM::service]
PRIVATE_DEPENDENCIES = \
- LIBEVENTS MESSAGING samba_socket NDR_NAMED_PIPE_AUTH
+ LIBTEVENT MESSAGING samba_socket NDR_NAMED_PIPE_AUTH
service_OBJ_FILES = $(addprefix $(smbdsrcdir)/, \
service.o \
@@ -21,6 +21,7 @@ $(eval $(call proto_header_template,$(smbdsrcdir)/pidfile.h,$(PIDFILE_OBJ_FILES:
[BINARY::samba]
INSTALLDIR = SBINDIR
PRIVATE_DEPENDENCIES = \
+ LIBEVENTS \
process_model \
service \
LIBSAMBA-HOSTCONFIG \
diff --git a/source4/smbd/server.c b/source4/smbd/server.c
index c1683a48dcf..df970661f17 100644
--- a/source4/smbd/server.c
+++ b/source4/smbd/server.c
@@ -266,7 +266,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
umask(0);
DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING));
- DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2008\n"));
+ DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2009\n"));
if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
@@ -323,7 +323,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
if (opt_interactive) {
/* terminate when stdin goes away */
- stdin_event_flags = EVENT_FD_READ;
+ stdin_event_flags = TEVENT_FD_READ;
} else {
/* stay alive forever */
stdin_event_flags = 0;
@@ -333,15 +333,15 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
#ifdef SIGTTIN
signal(SIGTTIN, SIG_IGN);
#endif
- event_add_fd(event_ctx, event_ctx, 0, stdin_event_flags,
- server_stdin_handler,
- discard_const(binary_name));
+ tevent_add_fd(event_ctx, event_ctx, 0, stdin_event_flags,
+ server_stdin_handler,
+ discard_const(binary_name));
if (max_runtime) {
- event_add_timed(event_ctx, event_ctx,
- timeval_current_ofs(max_runtime, 0),
- max_runtime_handler,
- discard_const(binary_name));
+ tevent_add_timer(event_ctx, event_ctx,
+ timeval_current_ofs(max_runtime, 0),
+ max_runtime_handler,
+ discard_const(binary_name));
}
DEBUG(0,("%s: using '%s' process model\n", binary_name, model));
@@ -354,7 +354,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
/* wait for events - this is where smbd sits for most of its
life */
- event_loop_wait(event_ctx);
+ tevent_loop_wait(event_ctx);
/* as everything hangs off this event context, freeing it
should initiate a clean shutdown of all services */
diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c
index 94fd501ffea..02b71de7c3f 100644
--- a/source4/smbd/service_named_pipe.c
+++ b/source4/smbd/service_named_pipe.c
@@ -20,7 +20,7 @@
*/
#include "includes.h"
-#include "lib/events/events.h"
+#include <tevent.h>
#include "lib/socket/socket.h"
#include "smbd/service.h"
#include "param/param.h"
@@ -49,7 +49,7 @@ static void named_pipe_handover_connection(void *private_data)
private_data, struct named_pipe_connection);
struct stream_connection *conn = pipe_conn->connection;
- EVENT_FD_NOT_WRITEABLE(conn->event.fde);
+ TEVENT_FD_NOT_WRITEABLE(conn->event.fde);
if (!NT_STATUS_IS_OK(pipe_conn->status)) {
stream_terminate_connection(conn, nt_errstr(pipe_conn->status));
@@ -64,7 +64,7 @@ static void named_pipe_handover_connection(void *private_data)
talloc_free(pipe_conn);
/* we're now ready to start receiving events on this stream */
- EVENT_FD_READABLE(conn->event.fde);
+ TEVENT_FD_READABLE(conn->event.fde);
/*
* hand over to the real pipe implementation,
diff --git a/source4/smbd/service_stream.c b/source4/smbd/service_stream.c
index ef98919f937..6dff01f4f35 100644
--- a/source4/smbd/service_stream.c
+++ b/source4/smbd/service_stream.c
@@ -21,8 +21,8 @@
*/
#include "includes.h"
+#include <tevent.h>
#include "process_model.h"
-#include "lib/events/events.h"
#include "lib/socket/socket.h"
#include "smbd/service.h"
#include "smbd/service_stream.h"
@@ -72,7 +72,7 @@ void stream_terminate_connection(struct stream_connection *srv_conn, const char
*
* and we don't want to read or write to the connection...
*/
- event_set_fd_flags(srv_conn->event.fde, 0);
+ tevent_fd_set_flags(srv_conn->event.fde, 0);
return;
}
@@ -88,9 +88,9 @@ void stream_terminate_connection(struct stream_connection *srv_conn, const char
static void stream_io_handler(struct stream_connection *conn, uint16_t flags)
{
conn->processing++;
- if (flags & EVENT_FD_WRITE) {
+ if (flags & TEVENT_FD_WRITE) {
conn->ops->send_handler(conn, flags);
- } else if (flags & EVENT_FD_READ) {
+ } else if (flags & TEVENT_FD_READ) {
conn->ops->recv_handler(conn, flags);
}
conn->processing--;
@@ -144,9 +144,14 @@ NTSTATUS stream_new_connection_merge(struct tevent_context *ev,
srv_conn->msg_ctx = msg_ctx;
srv_conn->event.ctx = ev;
srv_conn->lp_ctx = lp_ctx;
- srv_conn->event.fde = event_add_fd(ev, srv_conn, socket_get_fd(sock),
- EVENT_FD_READ,
- stream_io_handler_fde, srv_conn);
+ srv_conn->event.fde = tevent_add_fd(ev, srv_conn, socket_get_fd(sock),
+ TEVENT_FD_READ,
+ stream_io_handler_fde, srv_conn);
+ if (!srv_conn->event.fde) {
+ talloc_free(srv_conn);
+ return NT_STATUS_NO_MEMORY;
+ }
+
*_srv_conn = srv_conn;
return NT_STATUS_OK;
}
@@ -179,14 +184,19 @@ static void stream_new_connection(struct tevent_context *ev,
srv_conn->ops = stream_socket->ops;
srv_conn->event.ctx = ev;
srv_conn->lp_ctx = lp_ctx;
- srv_conn->event.fde = event_add_fd(ev, srv_conn, socket_get_fd(sock),
- 0, stream_io_handler_fde, srv_conn);
if (!socket_check_access(sock, "smbd", lp_hostsallow(NULL, lp_default_service(lp_ctx)), lp_hostsdeny(NULL, lp_default_service(lp_ctx)))) {
stream_terminate_connection(srv_conn, "denied by access rules");
return;
}
+ srv_conn->event.fde = tevent_add_fd(ev, srv_conn, socket_get_fd(sock),
+ 0, stream_io_handler_fde, srv_conn);
+ if (!srv_conn->event.fde) {
+ stream_terminate_connection(srv_conn, "tevent_add_fd() failed");
+ return;
+ }
+
/* setup to receive internal messages on this connection */
srv_conn->msg_ctx = messaging_init(srv_conn,
lp_messaging_path(srv_conn, lp_ctx),
@@ -214,7 +224,7 @@ static void stream_new_connection(struct tevent_context *ev,
talloc_free(s);
/* we're now ready to start receiving events on this stream */
- EVENT_FD_READABLE(srv_conn->event.fde);
+ TEVENT_FD_READABLE(srv_conn->event.fde);
/* call the server specific accept code */
stream_socket->ops->accept_connection(srv_conn);
@@ -258,6 +268,7 @@ NTSTATUS stream_setup_socket(struct tevent_context *event_context,
NTSTATUS status;
struct stream_socket *stream_socket;
struct socket_address *socket_address;
+ struct tevent_fd *fde;
int i;
stream_socket = talloc_zero(event_context, struct stream_socket);
@@ -322,20 +333,24 @@ NTSTATUS stream_setup_socket(struct tevent_context *event_context,
return status;
}
- /* By specifying EVENT_FD_AUTOCLOSE below, we indicate that we
- * will close the socket using the events system. This avoids
- * nasty interactions with waiting for talloc to close the socket. */
-
- socket_set_flags(stream_socket->sock, SOCKET_FLAG_NOCLOSE);
-
/* Add the FD from the newly created socket into the event
* subsystem. it will call the accept handler whenever we get
* new connections */
- event_add_fd(event_context, stream_socket->sock,
- socket_get_fd(stream_socket->sock),
- EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
- stream_accept_handler, stream_socket);
+ fde = tevent_add_fd(event_context, stream_socket->sock,
+ socket_get_fd(stream_socket->sock),
+ TEVENT_FD_READ,
+ stream_accept_handler, stream_socket);
+ if (!fde) {
+ DEBUG(0,("Failed to setup fd event\n"));
+ talloc_free(stream_socket);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* we let events system to the close on the socket. This avoids
+ * nasty interactions with waiting for talloc to close the socket. */
+ tevent_fd_set_close_fn(fde, socket_tevent_fd_close_fn);
+ socket_set_flags(stream_socket->sock, SOCKET_FLAG_NOCLOSE);
stream_socket->private = talloc_reference(stream_socket, private);
stream_socket->ops = stream_ops;
diff --git a/source4/smbd/service_task.c b/source4/smbd/service_task.c
index 34ce755b931..d3951a4a9ab 100644
--- a/source4/smbd/service_task.c
+++ b/source4/smbd/service_task.c
@@ -21,7 +21,6 @@
#include "includes.h"
#include "process_model.h"
-#include "lib/events/events.h"
#include "smbd/service.h"
#include "smbd/service_task.h"
#include "lib/messaging/irpc.h"
diff --git a/source4/torture/util_smb.c b/source4/torture/util_smb.c
index f88a641059b..732b84af731 100644
--- a/source4/torture/util_smb.c
+++ b/source4/torture/util_smb.c
@@ -656,7 +656,10 @@ double torture_create_procs(struct torture_context *tctx,
pid_t mypid = getpid();
srandom(((int)mypid) ^ ((int)time(NULL)));
- asprintf(&myname, "CLIENT%d", i);
+ if (asprintf(&myname, "CLIENT%d", i) == -1) {
+ printf("asprintf failed\n");
+ return -1;
+ }
lp_set_cmdline(tctx->lp_ctx, "netbios name", myname);
free(myname);
diff --git a/source4/winbind/wb_init_domain.c b/source4/winbind/wb_init_domain.c
index 637cf10bb78..5953474c52f 100644
--- a/source4/winbind/wb_init_domain.c
+++ b/source4/winbind/wb_init_domain.c
@@ -402,8 +402,7 @@ static void init_domain_recv_samr(struct composite_context *ctx)
talloc_steal(state->domain->libnet_ctx->samr.pipe, state->domain->samr_binding);
state->domain->libnet_ctx->samr.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
state->domain->libnet_ctx->samr.name = state->domain->info->name;
- state->domain->libnet_ctx->samr.sid = dom_sid_dup(state->ctx,
- state->domain->info->sid);
+ state->domain->libnet_ctx->samr.sid = state->domain->info->sid;
composite_done(state->ctx);
}
diff --git a/source4/winbind/wb_samba3_cmd.c b/source4/winbind/wb_samba3_cmd.c
index 6cad76b08b0..6af92668a37 100644
--- a/source4/winbind/wb_samba3_cmd.c
+++ b/source4/winbind/wb_samba3_cmd.c
@@ -115,7 +115,7 @@ NTSTATUS wbsrv_samba3_priv_pipe_dir(struct wbsrv_samba3_call *s3call)
{
const char *path = s3call->wbconn->listen_socket->service->priv_socket_path;
s3call->response.result = WINBINDD_OK;
- WBSRV_SAMBA3_SET_STRING(s3call->response.extra_data.data, path);
+ s3call->response.extra_data.data = discard_const(path);
s3call->response.length += strlen(path) + 1;
return NT_STATUS_OK;