From 116ce19b10a1fd60776764974ad50776ff7c4714 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Fri, 20 Feb 2009 15:10:21 -0800 Subject: Moved become_daemon() and close_low_fds() to shared util lib --- lib/util/become_daemon.c | 22 +++++++++++----------- lib/util/util.h | 9 ++++++--- 2 files changed, 17 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/util/become_daemon.c b/lib/util/become_daemon.c index 034114eade..5a97b65407 100644 --- a/lib/util/become_daemon.c +++ b/lib/util/become_daemon.c @@ -28,14 +28,15 @@ /******************************************************************* Close the low 3 fd's and open dev/null in their place. ********************************************************************/ -static void close_low_fds(bool stderr_too) + +_PUBLIC_ void close_low_fds(bool stderr_too) { #ifndef VALGRIND int fd; int i; close(0); - close(1); + close(1); if (stderr_too) close(2); @@ -61,11 +62,11 @@ static void close_low_fds(bool stderr_too) #endif } -/** +/**************************************************************************** Become a daemon, discarding the controlling terminal. -**/ +****************************************************************************/ -_PUBLIC_ void become_daemon(bool Fork) +_PUBLIC_ void become_daemon(bool Fork, bool no_process_group) { if (Fork) { if (fork()) { @@ -73,14 +74,14 @@ _PUBLIC_ void become_daemon(bool Fork) } } - /* detach from the terminal */ + /* detach from the terminal */ #ifdef HAVE_SETSID - setsid(); + if (!no_process_group) setsid(); #elif defined(TIOCNOTTY) - { - int i = open("/dev/tty", O_RDWR, 0); + if (!no_process_group) { + int i = sys_open("/dev/tty", O_RDWR, 0); if (i != -1) { - ioctl(i, (int) TIOCNOTTY, (char *)0); + ioctl(i, (int) TIOCNOTTY, (char *)0); close(i); } } @@ -90,4 +91,3 @@ _PUBLIC_ void become_daemon(bool Fork) close_low_fds(false); /* Don't close stderr, let the debug system attach it to the logfile */ } - diff --git a/lib/util/util.h b/lib/util/util.h index 7873f0e769..4d4df21600 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -724,12 +724,15 @@ _PUBLIC_ int idr_remove(struct idr_context *idp, int id); /* The following definitions come from lib/util/become_daemon.c */ -#if _SAMBA_BUILD_ == 4 +/** + Close the low 3 fd's and open dev/null in their place +**/ +_PUBLIC_ void close_low_fds(bool stderr_too); + /** Become a daemon, discarding the controlling terminal. **/ -_PUBLIC_ void become_daemon(bool fork); -#endif +_PUBLIC_ void become_daemon(bool fork, bool no_process_group); /** * Load a ini-style file. -- cgit From c9a057bc0497fd201142799d02f046e95236f921 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 21 Feb 2009 19:08:24 +0100 Subject: pytevent: Fix include path - tevent_util is not installed. --- lib/tevent/pytevent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c index 4c0cbfd3cd..3b45ba1928 100644 --- a/lib/tevent/pytevent.c +++ b/lib/tevent/pytevent.c @@ -29,7 +29,7 @@ #include #include -#include +#include "tevent_util.h" typedef struct { PyObject_HEAD -- cgit From 39b508e38e831f826be254391f7f341bc935f792 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sat, 21 Feb 2009 13:54:43 -0800 Subject: Fix shadowed declaration warning --- lib/util/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/util/util.h b/lib/util/util.h index 4d4df21600..d3e446f488 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -732,7 +732,7 @@ _PUBLIC_ void close_low_fds(bool stderr_too); /** Become a daemon, discarding the controlling terminal. **/ -_PUBLIC_ void become_daemon(bool fork, bool no_process_group); +_PUBLIC_ void become_daemon(bool do_fork, bool no_process_group); /** * Load a ini-style file. -- cgit From cd6ae0de52164dd6f50b3614f2511acb3eb15993 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Sun, 22 Feb 2009 00:43:38 +0100 Subject: all BSDs use this evironment variable Signed-off-by: Stefan Metzmacher --- lib/replace/libreplace_ld.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/replace/libreplace_ld.m4 b/lib/replace/libreplace_ld.m4 index 81bde46219..9529c5e0a5 100644 --- a/lib/replace/libreplace_ld.m4 +++ b/lib/replace/libreplace_ld.m4 @@ -292,7 +292,7 @@ AC_DEFUN([AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR], *linux*) LIB_PATH_VAR=LD_LIBRARY_PATH ;; - *netbsd*) + *bsd*) LIB_PATH_VAR=LD_LIBRARY_PATH ;; *solaris*) -- cgit From faa1100d229aef56da5d48f5c19ec901e520f8ef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 23 Feb 2009 16:22:43 -0800 Subject: More warning fixes for Solaris. Jeremy. --- lib/replace/getifaddrs.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'lib') diff --git a/lib/replace/getifaddrs.c b/lib/replace/getifaddrs.c index f6f0ec080c..3a91bb40d2 100644 --- a/lib/replace/getifaddrs.c +++ b/lib/replace/getifaddrs.c @@ -84,9 +84,6 @@ int rep_getifaddrs(struct ifaddrs **ifap) char buff[8192]; int fd, i, n; struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; struct ifaddrs *curif; struct ifaddrs *lastif = NULL; @@ -164,9 +161,6 @@ int rep_getifaddrs(struct ifaddrs **ifap) char buff[8192]; int fd, i, n; struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; struct ifaddrs *curif; struct ifaddrs *lastif = NULL; @@ -265,9 +259,6 @@ int rep_getifaddrs(struct ifaddrs **ifap) int fd, i; struct ifconf ifc; struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; struct ifaddrs *curif; struct ifaddrs *lastif = NULL; -- cgit From 8d63c596a0f512c96f5663c0a9bd49d3c98c6df9 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Mon, 23 Feb 2009 20:46:11 -0800 Subject: Refactored sys_fork() and sys_pid() into shared util library This fixes a bug in 116ce19b, where we didn't clear the pid cache in become_daemon() and thus the /var/run/smbd.pid didn't match the actual pid of the parent process. Currently S4 will clear the pid cache on fork but doesn't yet take advantage of the pid cache by using sys_pid() instead of the direct get_pid(). --- lib/util/become_daemon.c | 6 +++--- lib/util/system.c | 29 +++++++++++++++++++++++++++++ lib/util/util.h | 10 ++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/util/become_daemon.c b/lib/util/become_daemon.c index 5a97b65407..3d06a4363d 100644 --- a/lib/util/become_daemon.c +++ b/lib/util/become_daemon.c @@ -66,10 +66,10 @@ _PUBLIC_ void close_low_fds(bool stderr_too) Become a daemon, discarding the controlling terminal. ****************************************************************************/ -_PUBLIC_ void become_daemon(bool Fork, bool no_process_group) +_PUBLIC_ void become_daemon(bool do_fork, bool no_process_group) { - if (Fork) { - if (fork()) { + if (do_fork) { + if (sys_fork()) { _exit(0); } } diff --git a/lib/util/system.c b/lib/util/system.c index 9bd1800233..9bf5de1a83 100644 --- a/lib/util/system.c +++ b/lib/util/system.c @@ -88,3 +88,32 @@ _PUBLIC_ struct in_addr sys_inet_makeaddr(int net, int host) return in2; } +/************************************************************************** + Wrapper for fork. Ensures we clear our pid cache. +****************************************************************************/ + +static pid_t mypid = (pid_t)-1; + +_PUBLIC_ pid_t sys_fork(void) +{ + pid_t forkret = fork(); + + if (forkret == (pid_t)0) { + /* Child - reset mypid so sys_getpid does a system call. */ + mypid = (pid_t) -1; + } + + return forkret; +} + +/************************************************************************** + Wrapper for getpid. Ensures we only do a system call *once*. +****************************************************************************/ + +_PUBLIC_ pid_t sys_getpid(void) +{ + if (mypid == (pid_t)-1) + mypid = getpid(); + + return mypid; +} diff --git a/lib/util/util.h b/lib/util/util.h index d3e446f488..27f94cd685 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -134,6 +134,16 @@ apparent reason. _PUBLIC_ struct hostent *sys_gethostbyname(const char *name); _PUBLIC_ struct in_addr sys_inet_makeaddr(int net, int host); +/** + * Wrapper for fork used to invalid pid cache. + **/ +_PUBLIC_ pid_t sys_fork(void); + +/** + * Wrapper for getpid. Ensures we only do a system call *once*. + **/ +_PUBLIC_ pid_t sys_getpid(void); + /* The following definitions come from lib/util/genrand.c */ /** -- cgit From c50233695e002d9f7c872821f7b90cdea632dd30 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 19:47:54 +0100 Subject: Add tevent_req_is_unix_error --- lib/util/tevent_unix.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ lib/util/tevent_unix.h | 27 +++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 lib/util/tevent_unix.c create mode 100644 lib/util/tevent_unix.h (limited to 'lib') diff --git a/lib/util/tevent_unix.c b/lib/util/tevent_unix.c new file mode 100644 index 0000000000..b89d5cd4d4 --- /dev/null +++ b/lib/util/tevent_unix.c @@ -0,0 +1,46 @@ +/* + Unix SMB/CIFS implementation. + Wrap unix errno around tevent_req + Copyright (C) Volker Lendecke 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 . +*/ + +#include "tevent_unix.h" +#include "../replace/replace.h" + +bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno) +{ + enum tevent_req_state state; + uint64_t err; + + if (!tevent_req_is_error(req, &state, &err)) { + return false; + } + switch (state) { + case TEVENT_REQ_TIMED_OUT: + *perrno = ETIMEDOUT; + break; + case TEVENT_REQ_NO_MEMORY: + *perrno = ENOMEM; + break; + case TEVENT_REQ_USER_ERROR: + *perrno = err; + break; + default: + *perrno = EINVAL; + break; + } + return true; +} diff --git a/lib/util/tevent_unix.h b/lib/util/tevent_unix.h new file mode 100644 index 0000000000..dc3ffaef33 --- /dev/null +++ b/lib/util/tevent_unix.h @@ -0,0 +1,27 @@ +/* + Unix SMB/CIFS implementation. + Wrap unix errno around tevent_req + Copyright (C) Volker Lendecke 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 . +*/ + +#ifndef _TEVENT_UNIX_H +#define _TEVENT_UNIX_H + +#include "../tevent/tevent.h" + +bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno); + +#endif -- cgit From 70814474f55befc1617e1162a23d14838ba451a3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 19:48:46 +0100 Subject: tevent.h requires bool and uint[16|32|64]_t --- lib/tevent/tevent.h | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 16fac7327f..33747f0986 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -31,6 +31,7 @@ #include #include #include +#include <../lib/replace/replace.h> struct tevent_context; struct tevent_ops; -- cgit From 39976035ebd669d168afa91274d7e368305bf69d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 19:49:18 +0100 Subject: Convert async_connect to tevent_req --- lib/async_req/async_sock.c | 54 +++++++++++++++++++++++----------------------- lib/async_req/async_sock.h | 11 +++++----- 2 files changed, 33 insertions(+), 32 deletions(-) (limited to 'lib') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 02ae880683..f5e3e5ba33 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -22,6 +22,7 @@ #include "lib/tevent/tevent.h" #include "lib/async_req/async_req.h" #include "lib/async_req/async_sock.h" +#include "lib/util/tevent_unix.h" #include #ifndef TALLOC_FREE @@ -633,17 +634,18 @@ static void async_connect_connected(struct tevent_context *ev, * connect in an async state. This will be reset when the request is finished. */ -struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, const struct sockaddr *address, - socklen_t address_len) +struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const struct sockaddr *address, + socklen_t address_len) { - struct async_req *result; + struct tevent_req *result; struct async_connect_state *state; struct tevent_fd *fde; - if (!async_req_setup(mem_ctx, &result, &state, - struct async_connect_state)) { + result = tevent_req_create( + mem_ctx, &state, struct async_connect_state); + if (result == NULL) { return NULL; } @@ -664,8 +666,8 @@ struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, state->result = connect(fd, address, address_len); if (state->result == 0) { - state->sys_errno = 0; - goto post_status; + errno = 0; + goto post_errno; } /** @@ -686,22 +688,20 @@ struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE, async_connect_connected, result); if (fde == NULL) { - state->sys_errno = ENOMEM; - goto post_status; + errno = ENOMEM; + goto post_errno; } return result; post_errno: state->sys_errno = errno; - post_status: fcntl(fd, F_SETFL, state->old_sockflags); - if (!async_post_error(result, ev, state->sys_errno)) { - goto fail; + if (state->sys_errno == 0) { + tevent_req_done(result); + } else { + tevent_req_error(result, state->sys_errno); } - return result; - fail: - TALLOC_FREE(result); - return NULL; + return tevent_req_post(result, ev); } /** @@ -716,10 +716,10 @@ static void async_connect_connected(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *priv) { - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); + struct tevent_req *req = talloc_get_type_abort( + priv, struct tevent_req); struct async_connect_state *state = talloc_get_type_abort( - req->private_data, struct async_connect_state); + req->private_state, struct async_connect_state); TALLOC_FREE(fde); @@ -743,27 +743,27 @@ static void async_connect_connected(struct tevent_context *ev, DEBUG(10, ("connect returned %s\n", strerror(errno))); fcntl(state->fd, F_SETFL, state->old_sockflags); - async_req_error(req, state->sys_errno); + tevent_req_error(req, state->sys_errno); return; } state->sys_errno = 0; - async_req_done(req); + tevent_req_done(req); } -int async_connect_recv(struct async_req *req, int *perrno) +int async_connect_recv(struct tevent_req *req, int *perrno) { struct async_connect_state *state = talloc_get_type_abort( - req->private_data, struct async_connect_state); + req->private_state, struct async_connect_state); int err; fcntl(state->fd, F_SETFL, state->old_sockflags); - - if (async_req_is_errno(req, &err)) { + if (tevent_req_is_unix_error(req, &err)) { *perrno = err; return -1; } + if (state->sys_errno == 0) { return 0; } diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index c8739e9ed6..784571ed5a 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -35,11 +35,12 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, void *buffer, size_t length, int flags); -struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, const struct sockaddr *address, - socklen_t address_len); -int async_connect_recv(struct async_req *req, int *perrno); + +struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const struct sockaddr *address, + socklen_t address_len); +int async_connect_recv(struct tevent_req *req, int *perrno); struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const void *buffer, size_t length, -- cgit From 76c6330dfb78e536bc7620719d12859ff7418c36 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 20:16:32 +0100 Subject: Add async writev --- lib/async_req/async_sock.c | 105 +++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 4 ++ 2 files changed, 109 insertions(+) (limited to 'lib') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index f5e3e5ba33..380fea5908 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -771,3 +771,108 @@ int async_connect_recv(struct tevent_req *req, int *perrno) *perrno = state->sys_errno; return -1; } + +struct writev_state { + struct tevent_context *ev; + int fd; + struct iovec *iov; + int count; + size_t total_size; +}; + +static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, struct iovec *iov, int count) +{ + struct tevent_req *result; + struct writev_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct writev_state); + if (result == NULL) { + return NULL; + } + state->ev = ev; + state->fd = fd; + state->total_size = 0; + state->count = count; + state->iov = (struct iovec *)talloc_memdup( + state, iov, sizeof(struct iovec) * count); + if (state->iov == NULL) { + goto fail; + } + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, writev_handler, + result); + if (fde == NULL) { + goto fail; + } + return result; + + fail: + TALLOC_FREE(result); + return NULL; +} + +static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct writev_state *state = talloc_get_type_abort( + req->private_state, struct writev_state); + size_t to_write, written; + int i; + + to_write = 0; + + for (i=0; icount; i++) { + to_write += state->iov[i].iov_len; + } + + written = sys_writev(state->fd, state->iov, state->count); + if (written == -1) { + tevent_req_error(req, errno); + return; + } + if (written == 0) { + tevent_req_error(req, EOF); + return; + } + state->total_size += written; + + if (written == to_write) { + tevent_req_done(req); + return; + } + + /* + * We've written less than we were asked to, drop stuff from + * state->iov. + */ + + while (written > 0) { + if (written < state->iov[0].iov_len) { + state->iov[0].iov_base = + (char *)state->iov[0].iov_base + written; + state->iov[0].iov_len -= written; + break; + } + written = state->iov[0].iov_len; + state->iov += 1; + state->count -= 1; + } +} + +ssize_t writev_recv(struct tevent_req *req, int *perrno) +{ + struct writev_state *state = talloc_get_type_abort( + req->private_state, struct writev_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + return state->total_size; +} diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 784571ed5a..3d70673c17 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -52,4 +52,8 @@ struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int flags); ssize_t recvall_recv(struct async_req *req, int *perr); +struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, struct iovec *iov, int count); +ssize_t writev_recv(struct tevent_req *req, int *perrno); + #endif -- cgit From e50075a5804204068f07cb82337d3a251b368245 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 22:03:06 +0100 Subject: Remove async sendall --- lib/async_req/async_sock.c | 111 --------------------------------------------- lib/async_req/async_sock.h | 5 -- 2 files changed, 116 deletions(-) (limited to 'lib') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 380fea5908..33f8ebe192 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -34,7 +34,6 @@ */ enum async_syscall_type { ASYNC_SYSCALL_SEND, - ASYNC_SYSCALL_SENDALL, ASYNC_SYSCALL_RECV, ASYNC_SYSCALL_RECVALL, ASYNC_SYSCALL_CONNECT @@ -55,13 +54,6 @@ struct async_syscall_state { size_t length; int flags; } param_send; - struct param_sendall { - int fd; - const void *buffer; - size_t length; - int flags; - size_t sent; - } param_sendall; struct param_recv { int fd; void *buffer; @@ -337,109 +329,6 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return result; } -/** - * fde event handler for the "sendall" syscall group - * @param[in] ev The event context that sent us here - * @param[in] fde The file descriptor event associated with the send - * @param[in] flags Can only be TEVENT_FD_WRITE here - * @param[in] priv private data, "struct async_req *" in this case - */ - -static void async_sendall_callback(struct tevent_context *ev, - struct tevent_fd *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_sendall *p = &state->param.param_sendall; - - if (state->syscall_type != ASYNC_SYSCALL_SENDALL) { - async_req_error(req, EIO); - return; - } - - state->result.result_ssize_t = send(p->fd, - (const char *)p->buffer + p->sent, - p->length - p->sent, p->flags); - state->sys_errno = errno; - - if (state->result.result_ssize_t == -1) { - async_req_error(req, state->sys_errno); - return; - } - - if (state->result.result_ssize_t == 0) { - async_req_error(req, EOF); - return; - } - - p->sent += state->result.result_ssize_t; - if (p->sent > p->length) { - async_req_error(req, EIO); - return; - } - - if (p->sent == p->length) { - TALLOC_FREE(state->fde); - async_req_done(req); - } -} - -/** - * @brief Send all bytes to a socket - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] fd The socket to send to - * @param[in] buffer The buffer to send - * @param[in] length How many bytes to send - * @param[in] flags flags passed to send(2) - * - * async_sendall calls send(2) as long as it is necessary to send all of the - * "length" bytes - */ - -struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, const void *buffer, size_t length, - int flags) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_fde_syscall_new( - mem_ctx, ev, ASYNC_SYSCALL_SENDALL, - fd, TEVENT_FD_WRITE, async_sendall_callback, - &state); - if (result == NULL) { - return NULL; - } - - state->param.param_sendall.fd = fd; - state->param.param_sendall.buffer = buffer; - state->param.param_sendall.length = length; - state->param.param_sendall.flags = flags; - state->param.param_sendall.sent = 0; - - return result; -} - -ssize_t sendall_recv(struct async_req *req, int *perr) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - int err; - - err = async_req_simple_recv_errno(req); - - if (err != 0) { - *perr = err; - return -1; - } - - return state->result.result_ssize_t; -} - /** * fde event handler for the "recv" syscall * @param[in] ev The event context that sent us here diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 3d70673c17..6a862c45c6 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -42,11 +42,6 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, socklen_t address_len); int async_connect_recv(struct tevent_req *req, int *perrno); -struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, const void *buffer, size_t length, - int flags); -ssize_t sendall_recv(struct async_req *req, int *perr); - struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, void *buffer, size_t length, int flags); -- cgit From f9df355befdef7c424ebc70abfeb696de095235e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 23:12:56 +0100 Subject: Fix async writev --- lib/async_req/async_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 33f8ebe192..67776ff67f 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -727,7 +727,7 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, return; } if (written == 0) { - tevent_req_error(req, EOF); + tevent_req_error(req, EPIPE); return; } state->total_size += written; -- cgit From 4021029cddddcb23c41cd7f8b711f3a8d83c3931 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 23:13:34 +0100 Subject: Add async read_packet --- lib/async_req/async_sock.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 10 ++++ 2 files changed, 128 insertions(+) (limited to 'lib') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 67776ff67f..02e4c9eb4b 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -765,3 +765,121 @@ ssize_t writev_recv(struct tevent_req *req, int *perrno) } return state->total_size; } + +struct read_packet_state { + int fd; + uint8_t *buf; + size_t nread; + ssize_t (*more)(uint8_t *buf, size_t buflen, void *private_data); + void *private_data; +}; + +static void read_packet_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, size_t initial, + ssize_t (*more)(uint8_t *buf, + size_t buflen, + void *private_data), + void *private_data) +{ + struct tevent_req *result; + struct read_packet_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct read_packet_state); + if (result == NULL) { + return NULL; + } + state->fd = fd; + state->nread = 0; + state->more = more; + state->private_data = private_data; + + state->buf = talloc_array(state, uint8_t, initial); + if (state->buf == NULL) { + goto fail; + } + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, read_packet_handler, + result); + if (fde == NULL) { + goto fail; + } + return result; + fail: + TALLOC_FREE(result); + return NULL; +} + +static void read_packet_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct read_packet_state *state = talloc_get_type_abort( + req->private_state, struct read_packet_state); + size_t total = talloc_get_size(state->buf); + ssize_t nread, more; + uint8_t *tmp; + + nread = read(state->fd, state->buf+state->nread, total-state->nread); + if (nread == -1) { + tevent_req_error(req, errno); + return; + } + if (nread == 0) { + tevent_req_error(req, EPIPE); + return; + } + + state->nread += nread; + if (state->nread < total) { + /* Come back later */ + return; + } + + /* + * We got what was initially requested. See if "more" asks for -- more. + */ + if (state->more == NULL) { + /* Nobody to ask, this is a async read_data */ + tevent_req_done(req); + return; + } + + more = state->more(state->buf, total, state->private_data); + if (more == -1) { + /* We got an invalid packet, tell the caller */ + tevent_req_error(req, EIO); + return; + } + if (more == 0) { + /* We're done, full packet received */ + tevent_req_done(req); + return; + } + + tmp = TALLOC_REALLOC_ARRAY(state, state->buf, uint8_t, total+more); + if (tevent_req_nomem(tmp, req)) { + return; + } + state->buf = tmp; +} + +ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + uint8_t **pbuf, int *perrno) +{ + struct read_packet_state *state = talloc_get_type_abort( + req->private_state, struct read_packet_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + *pbuf = talloc_move(mem_ctx, &state->buf); + return talloc_get_size(*pbuf); +} diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 6a862c45c6..0cf4e4ecf5 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -51,4 +51,14 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, struct iovec *iov, int count); ssize_t writev_recv(struct tevent_req *req, int *perrno); +struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, size_t initial, + ssize_t (*more)(uint8_t *buf, + size_t buflen, + void *private_data), + void *private_data); +ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + uint8_t **pbuf, int *perrno); + #endif -- cgit From bbbdfa20566a607e0fdfdd190bb12bc3130e8bee Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 00:20:24 +0100 Subject: Remove unused recvall --- lib/async_req/async_sock.c | 110 --------------------------------------------- lib/async_req/async_sock.h | 5 --- 2 files changed, 115 deletions(-) (limited to 'lib') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 02e4c9eb4b..86f89c159a 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -35,7 +35,6 @@ enum async_syscall_type { ASYNC_SYSCALL_SEND, ASYNC_SYSCALL_RECV, - ASYNC_SYSCALL_RECVALL, ASYNC_SYSCALL_CONNECT }; @@ -60,13 +59,6 @@ struct async_syscall_state { size_t length; int flags; } param_recv; - struct param_recvall { - int fd; - void *buffer; - size_t length; - int flags; - size_t received; - } param_recvall; struct param_connect { /** * connect needs to be done on a nonblocking @@ -397,108 +389,6 @@ struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return result; } -/** - * fde event handler for the "recvall" syscall group - * @param[in] ev The event context that sent us here - * @param[in] fde The file descriptor event associated with the recv - * @param[in] flags Can only be TEVENT_FD_READ here - * @param[in] priv private data, "struct async_req *" in this case - */ - -static void async_recvall_callback(struct tevent_context *ev, - struct tevent_fd *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_recvall *p = &state->param.param_recvall; - - if (state->syscall_type != ASYNC_SYSCALL_RECVALL) { - async_req_error(req, EIO); - return; - } - - state->result.result_ssize_t = recv(p->fd, - (char *)p->buffer + p->received, - p->length - p->received, p->flags); - state->sys_errno = errno; - - if (state->result.result_ssize_t == -1) { - async_req_error(req, state->sys_errno); - return; - } - - if (state->result.result_ssize_t == 0) { - async_req_error(req, EIO); - return; - } - - p->received += state->result.result_ssize_t; - if (p->received > p->length) { - async_req_error(req, EIO); - return; - } - - if (p->received == p->length) { - TALLOC_FREE(state->fde); - async_req_done(req); - } -} - -/** - * Receive a specified number of bytes from a socket - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] fd The socket to recv from - * @param[in] buffer The buffer to recv into - * @param[in] length How many bytes to recv - * @param[in] flags flags passed to recv(2) - * - * async_recvall will call recv(2) until "length" bytes are received - */ - -struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, void *buffer, size_t length, - int flags) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_fde_syscall_new( - mem_ctx, ev, ASYNC_SYSCALL_RECVALL, - fd, TEVENT_FD_READ, async_recvall_callback, - &state); - if (result == NULL) { - return NULL; - } - - state->param.param_recvall.fd = fd; - state->param.param_recvall.buffer = buffer; - state->param.param_recvall.length = length; - state->param.param_recvall.flags = flags; - state->param.param_recvall.received = 0; - - return result; -} - -ssize_t recvall_recv(struct async_req *req, int *perr) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - int err; - - err = async_req_simple_recv_errno(req); - - if (err != 0) { - *perr = err; - return -1; - } - - return state->result.result_ssize_t; -} - struct async_connect_state { int fd; int result; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 0cf4e4ecf5..bfa23d7836 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -42,11 +42,6 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, socklen_t address_len); int async_connect_recv(struct tevent_req *req, int *perrno); -struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, void *buffer, size_t length, - int flags); -ssize_t recvall_recv(struct async_req *req, int *perr); - struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, struct iovec *iov, int count); ssize_t writev_recv(struct tevent_req *req, int *perrno); -- cgit From 08f028f179f474f83d46b1a23d1cfbd8848b68b0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 00:21:27 +0100 Subject: Remove unused param_connect struct --- lib/async_req/async_sock.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'lib') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 86f89c159a..7bb52767af 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -35,7 +35,6 @@ enum async_syscall_type { ASYNC_SYSCALL_SEND, ASYNC_SYSCALL_RECV, - ASYNC_SYSCALL_CONNECT }; /** @@ -59,16 +58,6 @@ struct async_syscall_state { size_t length; int flags; } param_recv; - struct param_connect { - /** - * connect needs to be done on a nonblocking - * socket. Keep the old flags around - */ - long old_sockflags; - int fd; - const struct sockaddr *address; - socklen_t address_len; - } param_connect; } param; union { -- cgit From a60480b71ad7cdaa495b7624f04bc477a3330cbf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 08:53:01 +0100 Subject: Add more conventional async_send --- lib/async_req/async_sock.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 6 +++++ 2 files changed, 73 insertions(+) (limited to 'lib') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 7bb52767af..323d285729 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -378,6 +378,73 @@ struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return result; } +struct async_send_state { + int fd; + const void *buf; + size_t len; + int flags; + ssize_t sent; +}; + +static void async_send_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const void *buf, size_t len, + int flags) +{ + struct tevent_req *result; + struct async_send_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct async_send_state); + if (result == NULL) { + return result; + } + state->fd = fd; + state->buf = buf; + state->len = len; + state->flags = flags; + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, async_send_handler, + result); + if (fde == NULL) { + TALLOC_FREE(result); + return NULL; + } + return result; +} + +static void async_send_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct async_send_state *state = talloc_get_type_abort( + req->private_state, struct async_send_state); + + state->sent = send(state->fd, state->buf, state->len, state->flags); + if (state->sent == -1) { + tevent_req_error(req, errno); + return; + } + tevent_req_done(req); +} + +ssize_t async_send_recv(struct tevent_req *req, int *perrno) +{ + struct async_send_state *state = talloc_get_type_abort( + req->private_state, struct async_send_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + return state->sent; +} + struct async_connect_state { int fd; int result; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index bfa23d7836..89dabdac4c 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -36,6 +36,12 @@ struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, void *buffer, size_t length, int flags); +struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const void *buf, size_t len, + int flags); +ssize_t async_send_recv(struct tevent_req *req, int *perrno); + struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const struct sockaddr *address, -- cgit From 25df6d74131b8b9bd8924ca70eb891ff97d3ddfd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 08:56:35 +0100 Subject: Add more conventional async_recv --- lib/async_req/async_sock.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 5 ++++ 2 files changed, 72 insertions(+) (limited to 'lib') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 323d285729..3563421e0e 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -445,6 +445,73 @@ ssize_t async_send_recv(struct tevent_req *req, int *perrno) return state->sent; } +struct async_recv_state { + int fd; + void *buf; + size_t len; + int flags; + ssize_t received; +}; + +static void async_recv_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *async_recv_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, void *buf, size_t len, int flags) +{ + struct tevent_req *result; + struct async_recv_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct async_recv_state); + if (result == NULL) { + return result; + } + state->fd = fd; + state->buf = buf; + state->len = len; + state->flags = flags; + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, async_recv_handler, + result); + if (fde == NULL) { + TALLOC_FREE(result); + return NULL; + } + return result; +} + +static void async_recv_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct async_recv_state *state = talloc_get_type_abort( + req->private_state, struct async_recv_state); + + state->received = recv(state->fd, state->buf, state->len, + state->flags); + if (state->received == -1) { + tevent_req_error(req, errno); + return; + } + tevent_req_done(req); +} + +ssize_t async_recv_recv(struct tevent_req *req, int *perrno) +{ + struct async_recv_state *state = talloc_get_type_abort( + req->private_state, struct async_recv_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + return state->received; +} + struct async_connect_state { int fd; int result; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 89dabdac4c..bfc4346d39 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -42,6 +42,11 @@ struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, int flags); ssize_t async_send_recv(struct tevent_req *req, int *perrno); +struct tevent_req *async_recv_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, void *buf, size_t len, int flags); +ssize_t async_recv_recv(struct tevent_req *req, int *perrno); + struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const struct sockaddr *address, -- cgit From 9e3178e8387cd85858a145bb4918073f91127d20 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 10:54:19 +0100 Subject: Attempt to fix the OpenChange build -- sorry for the break --- lib/tevent/tevent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 33747f0986..b3d1c6d59a 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -31,7 +31,7 @@ #include #include #include -#include <../lib/replace/replace.h> +#include struct tevent_context; struct tevent_ops; -- cgit From 00ad0c4a4317db810bf2197503006ae5a6bb8bce Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 12:38:32 +0100 Subject: Remove async_req based async_recv --- lib/async_req/async_sock.c | 68 ---------------------------------------------- lib/async_req/async_sock.h | 3 -- 2 files changed, 71 deletions(-) (limited to 'lib') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 3563421e0e..302265c805 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -310,74 +310,6 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return result; } -/** - * fde event handler for the "recv" syscall - * @param[in] ev The event context that sent us here - * @param[in] fde The file descriptor event associated with the recv - * @param[in] flags Can only be TEVENT_FD_READ here - * @param[in] priv private data, "struct async_req *" in this case - */ - -static void async_recv_callback(struct tevent_context *ev, - struct tevent_fd *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_recv *p = &state->param.param_recv; - - if (state->syscall_type != ASYNC_SYSCALL_RECV) { - async_req_error(req, EIO); - return; - } - - state->result.result_ssize_t = recv(p->fd, p->buffer, p->length, - p->flags); - state->sys_errno = errno; - - TALLOC_FREE(state->fde); - - async_req_done(req); -} - -/** - * Async version of recv(2) - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] fd The socket to recv from - * @param[in] buffer The buffer to recv into - * @param[in] length How many bytes to recv - * @param[in] flags flags passed to recv(2) - * - * This function is a direct counterpart of recv(2) - */ - -struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, void *buffer, size_t length, - int flags) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_fde_syscall_new( - mem_ctx, ev, ASYNC_SYSCALL_RECV, - fd, TEVENT_FD_READ, async_recv_callback, - &state); - - if (result == NULL) { - return NULL; - } - - state->param.param_recv.fd = fd; - state->param.param_recv.buffer = buffer; - state->param.param_recv.length = length; - state->param.param_recv.flags = flags; - - return result; -} - struct async_send_state { int fd; const void *buf; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index bfc4346d39..1d0558b41e 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -32,9 +32,6 @@ int async_syscall_result_int(struct async_req *req, int *perrno); struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const void *buffer, size_t length, int flags); -struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, void *buffer, size_t length, - int flags); struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, -- cgit From 423c1d88fcd0f128bceaf8b0c371281aa4a41003 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 12:45:39 +0100 Subject: Remove async_req based async_send --- lib/async_req/async_sock.c | 232 --------------------------------------------- lib/async_req/async_sock.h | 8 -- 2 files changed, 240 deletions(-) (limited to 'lib') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 302265c805..40e7bca4c8 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -29,45 +29,6 @@ #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) #endif -/** - * Discriminator for async_syscall_state - */ -enum async_syscall_type { - ASYNC_SYSCALL_SEND, - ASYNC_SYSCALL_RECV, -}; - -/** - * Holder for syscall arguments and the result - */ - -struct async_syscall_state { - enum async_syscall_type syscall_type; - struct tevent_fd *fde; - - union { - struct param_send { - int fd; - const void *buffer; - size_t length; - int flags; - } param_send; - struct param_recv { - int fd; - void *buffer; - size_t length; - int flags; - } param_recv; - } param; - - union { - ssize_t result_ssize_t; - size_t result_size_t; - int result_int; - } result; - int sys_errno; -}; - /** * @brief Map async_req states to unix-style errnos * @param[in] req The async req to get the state from @@ -117,199 +78,6 @@ int async_req_simple_recv_errno(struct async_req *req) return 0; } -/** - * @brief Create a new async syscall req - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] type Which syscall will this be - * @param[in] pstate Where to put the newly created private_data state - * @retval The new request - * - * This is a helper function to prepare a new struct async_req with an - * associated struct async_syscall_state. The async_syscall_state will be put - * into the async_req as private_data. - */ - -static struct async_req *async_syscall_new(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - enum async_syscall_type type, - struct async_syscall_state **pstate) -{ - struct async_req *result; - struct async_syscall_state *state; - - if (!async_req_setup(mem_ctx, &result, &state, - struct async_syscall_state)) { - return NULL; - } - state->syscall_type = type; - - result->private_data = state; - - *pstate = state; - - return result; -} - -/** - * @brief Create a new async syscall req based on a fd - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] type Which syscall will this be - * @param[in] fd The file descriptor we work on - * @param[in] fde_flags TEVENT_FD_READ/WRITE -- what are we interested in? - * @param[in] fde_cb The callback function for the file descriptor event - * @param[in] pstate Where to put the newly created private_data state - * @retval The new request - * - * This is a helper function to prepare a new struct async_req with an - * associated struct async_syscall_state and an associated file descriptor - * event. - */ - -static struct async_req *async_fde_syscall_new( - TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - enum async_syscall_type type, - int fd, - uint16_t fde_flags, - void (*fde_cb)(struct tevent_context *ev, - struct tevent_fd *fde, uint16_t flags, - void *priv), - struct async_syscall_state **pstate) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_syscall_new(mem_ctx, ev, type, &state); - if (result == NULL) { - return NULL; - } - - state->fde = tevent_add_fd(ev, state, fd, fde_flags, fde_cb, result); - if (state->fde == NULL) { - TALLOC_FREE(result); - return NULL; - } - *pstate = state; - return result; -} - -/** - * Retrieve a ssize_t typed result from an async syscall - * @param[in] req The syscall that has just finished - * @param[out] perrno Where to put the syscall's errno - * @retval The return value from the asynchronously called syscall - */ - -ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - - *perrno = state->sys_errno; - return state->result.result_ssize_t; -} - -/** - * Retrieve a size_t typed result from an async syscall - * @param[in] req The syscall that has just finished - * @param[out] perrno Where to put the syscall's errno - * @retval The return value from the asynchronously called syscall - */ - -size_t async_syscall_result_size_t(struct async_req *req, int *perrno) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - - *perrno = state->sys_errno; - return state->result.result_size_t; -} - -/** - * Retrieve a int typed result from an async syscall - * @param[in] req The syscall that has just finished - * @param[out] perrno Where to put the syscall's errno - * @retval The return value from the asynchronously called syscall - */ - -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); - - *perrno = state->sys_errno; - return state->result.result_int; -} - -/** - * fde event handler for the "send" syscall - * @param[in] ev The event context that sent us here - * @param[in] fde The file descriptor event associated with the send - * @param[in] flags Can only be TEVENT_FD_WRITE here - * @param[in] priv private data, "struct async_req *" in this case - */ - -static void async_send_callback(struct tevent_context *ev, - struct tevent_fd *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_send *p = &state->param.param_send; - - if (state->syscall_type != ASYNC_SYSCALL_SEND) { - async_req_error(req, EIO); - return; - } - - state->result.result_ssize_t = send(p->fd, p->buffer, p->length, - p->flags); - state->sys_errno = errno; - - TALLOC_FREE(state->fde); - - async_req_done(req); -} - -/** - * Async version of send(2) - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] fd The socket to send to - * @param[in] buffer The buffer to send - * @param[in] length How many bytes to send - * @param[in] flags flags passed to send(2) - * - * This function is a direct counterpart of send(2) - */ - -struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, const void *buffer, size_t length, - int flags) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_fde_syscall_new( - mem_ctx, ev, ASYNC_SYSCALL_SEND, - fd, TEVENT_FD_WRITE, async_send_callback, - &state); - if (result == NULL) { - return NULL; - } - - state->param.param_send.fd = fd; - state->param.param_send.buffer = buffer; - state->param.param_send.length = length; - state->param.param_send.flags = flags; - - return result; -} - struct async_send_state { int fd; const void *buf; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 1d0558b41e..e001709d27 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -25,14 +25,6 @@ bool async_req_is_errno(struct async_req *req, int *err); int async_req_simple_recv_errno(struct async_req *req); -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); -int async_syscall_result_int(struct async_req *req, int *perrno); - -struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, const void *buffer, size_t length, - int flags); - struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const void *buf, size_t len, -- cgit From 13ac0dc4565b1cbdb977b6959562f3f8f9ac5ff8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 13:53:19 +0100 Subject: tevent: add tevent_req_poll() function metze --- lib/tevent/tevent.h | 3 +++ lib/tevent/tevent_req.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+) (limited to 'lib') diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index b3d1c6d59a..b3611228aa 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -296,6 +296,9 @@ struct tevent_req *tevent_req_post(struct tevent_req *req, bool tevent_req_is_in_progress(struct tevent_req *req); +bool tevent_req_poll(struct tevent_req *req, + struct tevent_context *ev); + bool tevent_req_is_error(struct tevent_req *req, enum tevent_req_state *state, uint64_t *error); diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index 800e3855d1..c17587b16c 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -235,6 +235,21 @@ bool tevent_req_is_in_progress(struct tevent_req *req) return false; } +bool tevent_req_poll(struct tevent_req *req, + struct tevent_context *ev) +{ + while (tevent_req_is_in_progress(req)) { + int ret; + + ret = tevent_loop_once(ev); + if (ret != 0) { + return false; + } + } + + return true; +} + bool tevent_req_is_error(struct tevent_req *req, enum tevent_req_state *state, uint64_t *error) { -- cgit From e2f37ec106fb51ec894e0d6160949545e80dfe69 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 14:29:31 +0100 Subject: tevent: add private_print function feature to tevent_req metze --- lib/tevent/tevent.h | 11 +++++++++++ lib/tevent/tevent_req.c | 27 ++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index b3611228aa..185a8fa193 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -211,6 +211,15 @@ struct tevent_req { */ void *private_state; + /** + * @brief A function to overwrite the default print function + * + * The implementation doing the work may want to imeplement a + * custom function to print the text representation of the async + * request. + */ + char *(*private_print)(struct tevent_req *req, TALLOC_CTX *mem_ctx); + /** * @brief Internal state of the request * @@ -267,6 +276,8 @@ struct tevent_req { } internal; }; +char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx); + char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req); struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index c17587b16c..e243c7de5d 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -28,14 +28,17 @@ #include "tevent_util.h" /** - * @brief Print an tevent_req structure in debug messages - * @param[in] mem_ctx The memory context for the result + * @brief The default print function for creating debug messages * @param[in] req The request to be printed + * @param[in] mem_ctx The memory context for the result * @retval Text representation of req * + * The function should not be used by users of the asynx API, + * but custom print function can use it and append custom text + * to the string. */ -char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) +char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) { return talloc_asprintf(mem_ctx, "tevent_req[%p/%s]: state[%d] error[%lld (0x%llX)] " @@ -50,6 +53,24 @@ char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) ); } +/** + * @brief Print an tevent_req structure in debug messages + * @param[in] mem_ctx The memory context for the result + * @param[in] req The request to be printed + * @retval Text representation of req + * + * This function should be used by callers of the async API + */ + +char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) +{ + if (!req->private_print) { + return tevent_req_default_print(req, mem_ctx); + } + + return req->private_print(req, mem_ctx); +} + /** * @brief Create an async request * @param[in] mem_ctx The memory context for the result -- cgit From e17df483fbedb81aededdef5fbb6ae1d034bc2dd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Jan 2009 10:54:12 +0100 Subject: lib/tdb: if we know pwrite and pread are thread/fork safe tdb_reopen_all() should be a noop The reason for tdb_reopen_all() is that the seek pointer on fds are shared between parent and child. metze --- lib/tdb/common/open.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib') diff --git a/lib/tdb/common/open.c b/lib/tdb/common/open.c index b19e4cea29..e58c8ca7ff 100644 --- a/lib/tdb/common/open.c +++ b/lib/tdb/common/open.c @@ -461,6 +461,10 @@ fail: /* reopen all tdb's */ int tdb_reopen_all(int parent_longlived) { +#if defined(LIBREPLACE_PREAD_NOT_REPLACED) && \ + defined(LIBREPLACE_PWRITE_NOT_REPLACED) + return 0; +#else struct tdb_context *tdb; for (tdb=tdbs; tdb; tdb = tdb->next) { @@ -483,6 +487,7 @@ int tdb_reopen_all(int parent_longlived) if (tdb_reopen(tdb) != 0) return -1; } +#endif return 0; } -- cgit From c21ae8d1bfd4423cf1c4a62c11ba228773548de2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 10:29:55 +0100 Subject: libreplace: make it possible to disable socket_wrapper via -DSOCKET_WRAPPER_DISABLE=1 metze --- lib/replace/system/network.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/replace/system/network.h b/lib/replace/system/network.h index 40d20db2d4..f135d175d4 100644 --- a/lib/replace/system/network.h +++ b/lib/replace/system/network.h @@ -327,10 +327,12 @@ struct addrinfo { #endif #ifdef SOCKET_WRAPPER +#ifndef SOCKET_WRAPPER_DISABLE #ifndef SOCKET_WRAPPER_NOT_REPLACE #define SOCKET_WRAPPER_REPLACE -#endif +#endif /* SOCKET_WRAPPER_NOT_REPLACE */ #include "../socket_wrapper/socket_wrapper.h" -#endif +#endif /* SOCKET_WRAPPER_DISABLE */ +#endif /* SOCKET_WRAPPER */ #endif -- cgit From 26f238466caa1d40edf74d4678c2e981ec9018bd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Feb 2009 17:01:58 +0100 Subject: Speed up "net conf list" With 1000 shares in the registry, this changed the time of "net conf list" from 1.1 seconds to .6 seconds. Signed-off-by: Michael Adam --- lib/smbconf/smbconf.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib') diff --git a/lib/smbconf/smbconf.c b/lib/smbconf/smbconf.c index bcab0b97cd..595fd23421 100644 --- a/lib/smbconf/smbconf.c +++ b/lib/smbconf/smbconf.c @@ -203,10 +203,6 @@ WERROR smbconf_get_share(struct smbconf_ctx *ctx, const char *servicename, struct smbconf_service **service) { - if (!smbconf_share_exists(ctx, servicename)) { - return WERR_NO_SUCH_SERVICE; - } - return ctx->ops->get_share(ctx, mem_ctx, servicename, service); } -- cgit From bd121b532cf5a6728b7605072f725cc9c6d47f48 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 10:52:30 +0100 Subject: s3:libsmbconf: add transactions to the libsmbconf api This is useful for wrapping higher level aggregate operations in transactions. The text backend implementations just return WERR_OK, the registry backend implementatoins use the regdb_transaction_start|commit|cancel routines just added. Michael --- lib/smbconf/smbconf.c | 15 +++++++++++++++ lib/smbconf/smbconf.h | 4 ++++ lib/smbconf/smbconf_private.h | 3 +++ lib/smbconf/smbconf_txt.c | 17 +++++++++++++++++ 4 files changed, 39 insertions(+) (limited to 'lib') diff --git a/lib/smbconf/smbconf.c b/lib/smbconf/smbconf.c index 595fd23421..f25ccae0d4 100644 --- a/lib/smbconf/smbconf.c +++ b/lib/smbconf/smbconf.c @@ -399,3 +399,18 @@ WERROR smbconf_delete_global_includes(struct smbconf_ctx *ctx) return werr; } + +WERROR smbconf_transaction_start(struct smbconf_ctx *ctx) +{ + return ctx->ops->transaction_start(ctx); +} + +WERROR smbconf_transaction_commit(struct smbconf_ctx *ctx) +{ + return ctx->ops->transaction_commit(ctx); +} + +WERROR smbconf_transaction_cancel(struct smbconf_ctx *ctx) +{ + return ctx->ops->transaction_cancel(ctx); +} diff --git a/lib/smbconf/smbconf.h b/lib/smbconf/smbconf.h index 106fae6431..517302ac88 100644 --- a/lib/smbconf/smbconf.h +++ b/lib/smbconf/smbconf.h @@ -94,4 +94,8 @@ WERROR smbconf_set_global_includes(struct smbconf_ctx *ctx, WERROR smbconf_delete_includes(struct smbconf_ctx *ctx, const char *service); WERROR smbconf_delete_global_includes(struct smbconf_ctx *ctx); +WERROR smbconf_transaction_start(struct smbconf_ctx *ctx); +WERROR smbconf_transaction_commit(struct smbconf_ctx *ctx); +WERROR smbconf_transaction_cancel(struct smbconf_ctx *ctx); + #endif /* _LIBSMBCONF_H_ */ diff --git a/lib/smbconf/smbconf_private.h b/lib/smbconf/smbconf_private.h index c9e44181c6..e6998ad639 100644 --- a/lib/smbconf/smbconf_private.h +++ b/lib/smbconf/smbconf_private.h @@ -68,6 +68,9 @@ struct smbconf_ops { uint32_t num_includes, const char **includes); WERROR (*delete_includes)(struct smbconf_ctx *ctx, const char *service); + WERROR (*transaction_start)(struct smbconf_ctx *ctx); + WERROR (*transaction_commit)(struct smbconf_ctx *ctx); + WERROR (*transaction_cancel)(struct smbconf_ctx *ctx); }; struct smbconf_ctx { diff --git a/lib/smbconf/smbconf_txt.c b/lib/smbconf/smbconf_txt.c index 1df4a9fdb7..501382cc5f 100644 --- a/lib/smbconf/smbconf_txt.c +++ b/lib/smbconf/smbconf_txt.c @@ -612,6 +612,20 @@ static WERROR smbconf_txt_delete_includes(struct smbconf_ctx *ctx, return WERR_NOT_SUPPORTED; } +static WERROR smbconf_txt_transaction_start(struct smbconf_ctx *ctx) +{ + return WERR_OK; +} + +static WERROR smbconf_txt_transaction_commit(struct smbconf_ctx *ctx) +{ + return WERR_OK; +} + +static WERROR smbconf_txt_transaction_cancel(struct smbconf_ctx *ctx) +{ + return WERR_OK; +} static struct smbconf_ops smbconf_ops_txt = { .init = smbconf_txt_init, @@ -633,6 +647,9 @@ static struct smbconf_ops smbconf_ops_txt = { .get_includes = smbconf_txt_get_includes, .set_includes = smbconf_txt_set_includes, .delete_includes = smbconf_txt_delete_includes, + .transaction_start = smbconf_txt_transaction_start, + .transaction_commit = smbconf_txt_transaction_commit, + .transaction_cancel = smbconf_txt_transaction_cancel, }; -- cgit From 4d22554e98134755cea609aa6d888c8e67fc123b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Feb 2009 10:48:41 +0100 Subject: Add tevent_ntstatus --- lib/util/tevent_ntstatus.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++ lib/util/tevent_ntstatus.h | 32 +++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 lib/util/tevent_ntstatus.c create mode 100644 lib/util/tevent_ntstatus.h (limited to 'lib') diff --git a/lib/util/tevent_ntstatus.c b/lib/util/tevent_ntstatus.c new file mode 100644 index 0000000000..1a34e9c749 --- /dev/null +++ b/lib/util/tevent_ntstatus.c @@ -0,0 +1,51 @@ +/* + Unix SMB/CIFS implementation. + Wrap unix errno around tevent_req + Copyright (C) Volker Lendecke 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 . +*/ + +#include "tevent_ntstatus.h" +#include "../replace/replace.h" + +bool tevent_req_nterror(struct tevent_req *req, NTSTATUS status) +{ + return tevent_req_error(req, NT_STATUS_V(status)); +} + +bool tevent_req_is_nterror(struct tevent_req *req, NTSTATUS *status) +{ + enum tevent_req_state state; + uint64_t err; + + if (!tevent_req_is_error(req, &state, &err)) { + return false; + } + switch (state) { + case TEVENT_REQ_TIMED_OUT: + *status = NT_STATUS_IO_TIMEOUT; + break; + case TEVENT_REQ_NO_MEMORY: + *status = NT_STATUS_NO_MEMORY; + break; + case TEVENT_REQ_USER_ERROR: + *status = NT_STATUS(err); + break; + default: + *status = NT_STATUS_INTERNAL_ERROR; + break; + } + return true; +} diff --git a/lib/util/tevent_ntstatus.h b/lib/util/tevent_ntstatus.h new file mode 100644 index 0000000000..84c275fb13 --- /dev/null +++ b/lib/util/tevent_ntstatus.h @@ -0,0 +1,32 @@ +/* + Unix SMB/CIFS implementation. + Wrap unix errno around tevent_req + Copyright (C) Volker Lendecke 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 . +*/ + +#ifndef _TEVENT_NTSTATUS_H +#define _TEVENT_NTSTATUS_H + +#include +#include +#include "config.h" +#include "../libcli/util/ntstatus.h" +#include "../tevent/tevent.h" + +bool tevent_req_nterror(struct tevent_req *req, NTSTATUS status); +bool tevent_req_is_nterror(struct tevent_req *req, NTSTATUS *pstatus); + +#endif -- cgit From 3a1f24f286d4dba836b750122f571f831a794e4a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Feb 2009 11:42:01 +0100 Subject: tevent: add tevent_queue infrastructure metze --- lib/tevent/libtevent.m4 | 2 +- lib/tevent/tevent.h | 22 ++++++ lib/tevent/tevent_queue.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 lib/tevent/tevent_queue.c (limited to 'lib') diff --git a/lib/tevent/libtevent.m4 b/lib/tevent/libtevent.m4 index 29a64ae3b3..c316823a71 100644 --- a/lib/tevent/libtevent.m4 +++ b/lib/tevent/libtevent.m4 @@ -27,7 +27,7 @@ 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_req.o tevent_wakeup.o" +TEVENT_OBJ="$TEVENT_OBJ tevent_req.o tevent_wakeup.o tevent_queue.o" TEVENT_OBJ="$TEVENT_OBJ tevent_standard.o tevent_select.o" AC_CHECK_HEADERS(sys/epoll.h) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 185a8fa193..8c119ffb8e 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -338,6 +338,28 @@ struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs, struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs); +struct tevent_queue; + +struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx, + const char *name, + const char *location); + +#define tevent_queue_create(_mem_ctx, _name) \ + _tevent_queue_create((_mem_ctx), (_name), __location__) + +typedef void (*tevent_queue_trigger_fn_t)(struct tevent_req *req, + void *private_data); +bool tevent_queue_add(struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data); +bool tevent_queue_start(struct tevent_queue *queue, + struct tevent_context *ev); +void tevent_queue_stop(struct tevent_queue *queue); + +size_t tevent_queue_length(struct tevent_queue *queue); + #ifdef TEVENT_COMPAT_DEFINES #define event_context tevent_context diff --git a/lib/tevent/tevent_queue.c b/lib/tevent/tevent_queue.c new file mode 100644 index 0000000000..6c8fbe4f95 --- /dev/null +++ b/lib/tevent/tevent_queue.c @@ -0,0 +1,198 @@ +/* + Unix SMB/CIFS implementation. + Infrastructure for async requests + Copyright (C) Volker Lendecke 2008 + Copyright (C) Stefan Metzmacher 2009 + + ** NOTE! The following LGPL license applies to the tevent + ** library. 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 . +*/ + +#include "replace.h" +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +struct tevent_queue_entry { + struct tevent_queue_entry *prev, *next; + struct tevent_queue *queue; + + bool triggered; + + struct tevent_req *req; + + tevent_queue_trigger_fn_t trigger; + void *private_data; +}; + +struct tevent_queue { + const char *name; + const char *location; + + bool running; + struct tevent_timer *timer; + + size_t length; + struct tevent_queue_entry *list; +}; + +static int tevent_queue_entry_destructor(struct tevent_queue_entry *e) +{ + struct tevent_queue *q = e->queue; + + if (!q) { + return 0; + } + + DLIST_REMOVE(q->list, e); + q->length--; + + if (e->triggered && + q->running && + q->list) { + q->list->triggered = true; + q->list->trigger(q->list->req, + q->list->private_data); + } + + return 0; +} + +static int tevent_queue_destructor(struct tevent_queue *q) +{ + q->running = false; + + while (q->list) { + struct tevent_queue_entry *e = q->list; + talloc_free(e); + } + + return 0; +} + +struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx, + const char *name, + const char *location) +{ + struct tevent_queue *queue; + + queue = talloc_zero(mem_ctx, struct tevent_queue); + if (!queue) { + return NULL; + } + + queue->name = talloc_strdup(queue, name); + if (!queue->name) { + talloc_free(queue); + return NULL; + } + + queue->location = location; + + /* queue is running by default */ + queue->running = true; + + talloc_set_destructor(queue, tevent_queue_destructor); + return queue; +} + +static void tevent_queue_timer_start(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval now, + void *private_data) +{ + struct tevent_queue *q = talloc_get_type(private_data, + struct tevent_queue); + + talloc_free(te); + q->timer = NULL; + + q->list->triggered = true; + q->list->trigger(q->list->req, q->list->private_data); +} + +bool tevent_queue_add(struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data) +{ + struct tevent_queue_entry *e; + + e = talloc_zero(req, struct tevent_queue_entry); + if (e == NULL) { + return false; + } + + e->queue = queue; + e->req = req; + e->trigger = trigger; + e->private_data = private_data; + + if (queue->running && + !queue->timer && + !queue->list) { + queue->timer = tevent_add_timer(ev, queue, tevent_timeval_zero(), + tevent_queue_timer_start, + queue); + if (!queue->timer) { + talloc_free(e); + return false; + } + } + + DLIST_ADD_END(queue->list, e, struct tevent_queue_entry *); + queue->length++; + talloc_set_destructor(e, tevent_queue_entry_destructor); + + return true; +} + +bool tevent_queue_start(struct tevent_queue *queue, + struct tevent_context *ev) +{ + if (queue->running) { + /* already started */ + return true; + } + + if (!queue->timer && + queue->list) { + queue->timer = tevent_add_timer(ev, queue, tevent_timeval_zero(), + tevent_queue_timer_start, + queue); + if (!queue->timer) { + return false; + } + } + + queue->running = true; + + return true; +} + +void tevent_queue_stop(struct tevent_queue *queue) +{ + queue->running = false; + talloc_free(queue->timer); + queue->timer = NULL; +} + +size_t tevent_queue_length(struct tevent_queue *queue) +{ + return queue->length; +} -- cgit From b934f509ed222eb49e8b24ca111361e563434646 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 15:36:16 +0100 Subject: lib/torture: fix depency to map_nt_error_from_unix() This should fix the build on Mac OS 10 metze --- lib/torture/config.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/torture/config.mk b/lib/torture/config.mk index abd89260f6..b4ad9ae17f 100644 --- a/lib/torture/config.mk +++ b/lib/torture/config.mk @@ -3,7 +3,9 @@ PUBLIC_DEPENDENCIES = \ LIBSAMBA-HOSTCONFIG \ LIBSAMBA-UTIL \ - LIBTALLOC + LIBSAMBA-ERRORS \ + LIBTALLOC \ + LIBTEVENT CFLAGS = -I$(libtorturesrcdir) -I$(libtorturesrcdir)/../ torture_VERSION = 0.0.1 -- cgit From ddd3da8ab7b82a59b84338fb4814981d5ae2f8e4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 28 Feb 2009 12:19:24 +0100 Subject: Simplify async_connect_send slightly --- lib/async_req/async_sock.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 40e7bca4c8..1f48697f26 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -268,8 +268,8 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, state->result = connect(fd, address, address_len); if (state->result == 0) { - errno = 0; - goto post_errno; + tevent_req_done(result); + goto done; } /** @@ -284,25 +284,22 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, errno == EISCONN || #endif errno == EAGAIN || errno == EINTR)) { + state->sys_errno = errno; goto post_errno; } fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE, async_connect_connected, result); if (fde == NULL) { - errno = ENOMEM; + state->sys_errno = ENOMEM; goto post_errno; } return result; post_errno: - state->sys_errno = errno; + tevent_req_error(result, state->sys_errno); + done: fcntl(fd, F_SETFL, state->old_sockflags); - if (state->sys_errno == 0) { - tevent_req_done(result); - } else { - tevent_req_error(result, state->sys_errno); - } return tevent_req_post(result, ev); } -- cgit From d776ac03c3ce8a9090b847f20d2cdd16d745441f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 1 Mar 2009 16:16:16 +0100 Subject: Move next_token_talloc() to top-level. --- lib/util/util.h | 15 ++++++++ lib/util/util_str.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) (limited to 'lib') diff --git a/lib/util/util.h b/lib/util/util.h index 27f94cd685..1f6e3b193b 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -204,6 +204,21 @@ _PUBLIC_ void display_set_stderr(void); /* The following definitions come from lib/util/util_str.c */ +bool next_token_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep); + +/** + * Get the next token from a string, return false if none found. Handles + * double-quotes. This version does not trim leading separator characters + * before looking for a token. + */ +bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep); + /** Trim the specified elements off the front and back of a string. diff --git a/lib/util/util_str.c b/lib/util/util_str.c index a2c50fd38f..8bf6026105 100644 --- a/lib/util/util_str.c +++ b/lib/util/util_str.c @@ -332,4 +332,104 @@ _PUBLIC_ void string_replace(char *s, char oldc, char newc) } } +/** + * @file + * @brief String utilities. + **/ + +static bool next_token_internal_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep, + bool ltrim) +{ + char *s; + char *saved_s; + char *pbuf; + bool quoted; + size_t len=1; + + *pp_buff = NULL; + if (!ptr) { + return(false); + } + + s = (char *)*ptr; + + /* default to simple separators */ + if (!sep) { + sep = " \t\n\r"; + } + + /* find the first non sep char, if left-trimming is requested */ + if (ltrim) { + while (*s && strchr_m(sep,*s)) { + s++; + } + } + + /* nothing left? */ + if (!*s) { + return false; + } + + /* When restarting we need to go from here. */ + saved_s = s; + + /* Work out the length needed. */ + for (quoted = false; *s && + (quoted || !strchr_m(sep,*s)); s++) { + if (*s == '\"') { + quoted = !quoted; + } else { + len++; + } + } + + /* We started with len = 1 so we have space for the nul. */ + *pp_buff = talloc_array(ctx, char, len); + if (!*pp_buff) { + return false; + } + + /* copy over the token */ + pbuf = *pp_buff; + s = saved_s; + for (quoted = false; *s && + (quoted || !strchr_m(sep,*s)); s++) { + if ( *s == '\"' ) { + quoted = !quoted; + } else { + *pbuf++ = *s; + } + } + + *ptr = (*s) ? s+1 : s; + *pbuf = 0; + + return true; +} + +bool next_token_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep) +{ + return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true); +} + +/* + * Get the next token from a string, return false if none found. Handles + * double-quotes. This version does not trim leading separator characters + * before looking for a token. + */ + +bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep) +{ + return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false); +} + -- cgit From 55903e6f9120f1ec58a8554813229975c3028a09 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 1 Mar 2009 16:19:38 +0100 Subject: Move next_token_talloc to util.c, as util_str.c is only compiled inside samba 4. --- lib/util/util.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/util/util_str.c | 100 ---------------------------------------------------- 2 files changed, 100 insertions(+), 100 deletions(-) (limited to 'lib') diff --git a/lib/util/util.c b/lib/util/util.c index 988d8f9fa0..1f31f55e8b 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -836,4 +836,104 @@ _PUBLIC_ size_t utf16_len_n(const void *src, size_t n) return len; } +/** + * @file + * @brief String utilities. + **/ + +static bool next_token_internal_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep, + bool ltrim) +{ + char *s; + char *saved_s; + char *pbuf; + bool quoted; + size_t len=1; + + *pp_buff = NULL; + if (!ptr) { + return(false); + } + + s = (char *)*ptr; + + /* default to simple separators */ + if (!sep) { + sep = " \t\n\r"; + } + + /* find the first non sep char, if left-trimming is requested */ + if (ltrim) { + while (*s && strchr_m(sep,*s)) { + s++; + } + } + + /* nothing left? */ + if (!*s) { + return false; + } + + /* When restarting we need to go from here. */ + saved_s = s; + + /* Work out the length needed. */ + for (quoted = false; *s && + (quoted || !strchr_m(sep,*s)); s++) { + if (*s == '\"') { + quoted = !quoted; + } else { + len++; + } + } + + /* We started with len = 1 so we have space for the nul. */ + *pp_buff = talloc_array(ctx, char, len); + if (!*pp_buff) { + return false; + } + + /* copy over the token */ + pbuf = *pp_buff; + s = saved_s; + for (quoted = false; *s && + (quoted || !strchr_m(sep,*s)); s++) { + if ( *s == '\"' ) { + quoted = !quoted; + } else { + *pbuf++ = *s; + } + } + + *ptr = (*s) ? s+1 : s; + *pbuf = 0; + + return true; +} + +bool next_token_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep) +{ + return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true); +} + +/* + * Get the next token from a string, return false if none found. Handles + * double-quotes. This version does not trim leading separator characters + * before looking for a token. + */ + +bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep) +{ + return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false); +} + diff --git a/lib/util/util_str.c b/lib/util/util_str.c index 8bf6026105..a2c50fd38f 100644 --- a/lib/util/util_str.c +++ b/lib/util/util_str.c @@ -332,104 +332,4 @@ _PUBLIC_ void string_replace(char *s, char oldc, char newc) } } -/** - * @file - * @brief String utilities. - **/ - -static bool next_token_internal_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep, - bool ltrim) -{ - char *s; - char *saved_s; - char *pbuf; - bool quoted; - size_t len=1; - - *pp_buff = NULL; - if (!ptr) { - return(false); - } - - s = (char *)*ptr; - - /* default to simple separators */ - if (!sep) { - sep = " \t\n\r"; - } - - /* find the first non sep char, if left-trimming is requested */ - if (ltrim) { - while (*s && strchr_m(sep,*s)) { - s++; - } - } - - /* nothing left? */ - if (!*s) { - return false; - } - - /* When restarting we need to go from here. */ - saved_s = s; - - /* Work out the length needed. */ - for (quoted = false; *s && - (quoted || !strchr_m(sep,*s)); s++) { - if (*s == '\"') { - quoted = !quoted; - } else { - len++; - } - } - - /* We started with len = 1 so we have space for the nul. */ - *pp_buff = talloc_array(ctx, char, len); - if (!*pp_buff) { - return false; - } - - /* copy over the token */ - pbuf = *pp_buff; - s = saved_s; - for (quoted = false; *s && - (quoted || !strchr_m(sep,*s)); s++) { - if ( *s == '\"' ) { - quoted = !quoted; - } else { - *pbuf++ = *s; - } - } - - *ptr = (*s) ? s+1 : s; - *pbuf = 0; - - return true; -} - -bool next_token_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep) -{ - return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true); -} - -/* - * Get the next token from a string, return false if none found. Handles - * double-quotes. This version does not trim leading separator characters - * before looking for a token. - */ - -bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep) -{ - return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false); -} - -- cgit