From c14b7e648bcfc4865da4b290e46977fff81d4500 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 1 Feb 2009 16:32:02 +0100 Subject: Split up async_req into a generic and a NTSTATUS specific part --- lib/async_req/async_req.c | 67 +++++++------------------------ lib/async_req/async_req.h | 20 ++++------ lib/async_req/async_req_ntstatus.c | 82 ++++++++++++++++++++++++++++++++++++++ lib/async_req/async_req_ntstatus.h | 37 +++++++++++++++++ lib/async_req/async_sock.c | 30 +++++++------- lib/async_req/config.mk | 2 +- 6 files changed, 158 insertions(+), 80 deletions(-) create mode 100644 lib/async_req/async_req_ntstatus.c create mode 100644 lib/async_req/async_req_ntstatus.h (limited to 'lib/async_req') diff --git a/lib/async_req/async_req.c b/lib/async_req/async_req.c index be70a56380f..1b9fc5517be 100644 --- a/lib/async_req/async_req.c +++ b/lib/async_req/async_req.c @@ -43,8 +43,8 @@ char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req) { - return talloc_asprintf(mem_ctx, "async_req: state=%d, status=%s, " - "priv=%s", req->state, nt_errstr(req->status), + return talloc_asprintf(mem_ctx, "async_req: state=%d, error=%d, " + "priv=%s", req->state, (int)req->error, talloc_get_name(req->private_data)); } @@ -81,7 +81,7 @@ struct async_req *async_req_new(TALLOC_CTX *mem_ctx) void async_req_done(struct async_req *req) { - req->status = NT_STATUS_OK; + req->error = 0; req->state = ASYNC_REQ_DONE; if (req->async.fn != NULL) { req->async.fn(req); @@ -98,9 +98,9 @@ void async_req_done(struct async_req *req) * function with the appropriate status code. */ -void async_req_error(struct async_req *req, NTSTATUS status) +void async_req_error(struct async_req *req, uint32_t error) { - req->status = status; + req->error = error; req->state = ASYNC_REQ_ERROR; if (req->async.fn != NULL) { req->async.fn(req); @@ -121,11 +121,11 @@ static void async_trigger(struct tevent_context *ev, struct tevent_timer *te, struct async_req *req = talloc_get_type_abort(priv, struct async_req); TALLOC_FREE(te); - if (NT_STATUS_IS_OK(req->status)) { + if (req->error == 0) { async_req_done(req); } else { - async_req_error(req, req->status); + async_req_error(req, req->error); } } @@ -142,10 +142,10 @@ static void async_trigger(struct tevent_context *ev, struct tevent_timer *te, * conventions, independent of whether the request was actually deferred. */ -bool async_post_status(struct async_req *req, struct tevent_context *ev, - NTSTATUS status) +bool async_post_error(struct async_req *req, struct tevent_context *ev, + uint32_t error) { - req->status = status; + req->error = error; if (tevent_add_timer(ev, req, timeval_zero(), async_trigger, req) == NULL) { @@ -154,55 +154,18 @@ bool async_post_status(struct async_req *req, struct tevent_context *ev, return true; } -/** - * @brief Helper function for nomem check - * @param[in] p The pointer to be checked - * @param[in] req The request being processed - * - * Convenience helper to easily check alloc failure within a callback - * implementing the next step of an async request. - * - * Call pattern would be - * \code - * p = talloc(mem_ctx, bla); - * if (async_req_nomem(p, req)) { - * return; - * } - * \endcode - */ - -bool async_req_nomem(const void *p, struct async_req *req) -{ - if (p != NULL) { - return false; - } - async_req_error(req, NT_STATUS_NO_MEMORY); - return true; -} - -bool async_req_is_error(struct async_req *req, NTSTATUS *status) +bool async_req_is_error(struct async_req *req, uint32_t *error) { if (req->state < ASYNC_REQ_DONE) { - *status = NT_STATUS_INTERNAL_ERROR; return true; } if (req->state == ASYNC_REQ_ERROR) { - *status = req->status; + *error = req->error; return true; } return false; } -NTSTATUS async_req_simple_recv(struct async_req *req) -{ - NTSTATUS status; - - if (async_req_is_error(req, &status)) { - return status; - } - return NT_STATUS_OK; -} - static void async_req_timedout(struct tevent_context *ev, struct tevent_timer *te, struct timeval now, @@ -211,7 +174,7 @@ static void async_req_timedout(struct tevent_context *ev, struct async_req *req = talloc_get_type_abort( priv, struct async_req); TALLOC_FREE(te); - async_req_error(req, NT_STATUS_IO_TIMEOUT); + async_req_nterror(req, NT_STATUS_IO_TIMEOUT); } bool async_req_set_timeout(struct async_req *req, struct tevent_context *ev, @@ -240,9 +203,9 @@ struct async_req *async_wait_send(TALLOC_CTX *mem_ctx, return result; } -NTSTATUS async_wait_recv(struct async_req *req) +bool async_wait_recv(struct async_req *req) { - return NT_STATUS_OK; + return true; } struct async_queue_entry { diff --git a/lib/async_req/async_req.h b/lib/async_req/async_req.h index 59f5bd19b2a..19b052a788a 100644 --- a/lib/async_req/async_req.h +++ b/lib/async_req/async_req.h @@ -20,7 +20,7 @@ #ifndef __ASYNC_REQ_H__ #define __ASYNC_REQ_H__ -#include "includes.h" +#include "lib/talloc/talloc.h" /** * An async request moves between the following 4 states: @@ -92,9 +92,9 @@ struct async_req { * @brief status code when finished * * This status can be queried in the async completion function. It - * will be set to NT_STATUS_OK when everything went fine. + * will be set to 0 when everything went fine. **/ - NTSTATUS status; + uint32_t error; /** * @brief What to do on completion @@ -121,16 +121,12 @@ char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req); void async_req_done(struct async_req *req); -void async_req_error(struct async_req *req, NTSTATUS status); +void async_req_error(struct async_req *req, uint32_t error); -bool async_post_status(struct async_req *req, struct tevent_context *ev, - NTSTATUS status); +bool async_post_error(struct async_req *req, struct tevent_context *ev, + uint32_t error); -bool async_req_nomem(const void *p, struct async_req *req); - -bool async_req_is_error(struct async_req *req, NTSTATUS *status); - -NTSTATUS async_req_simple_recv(struct async_req *req); +bool async_req_is_error(struct async_req *req, uint32_t *error); bool async_req_set_timeout(struct async_req *req, struct tevent_context *ev, struct timeval to); @@ -139,7 +135,7 @@ struct async_req *async_wait_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct timeval to); -NTSTATUS async_wait_recv(struct async_req *req); +bool async_wait_recv(struct async_req *req); struct async_req_queue; diff --git a/lib/async_req/async_req_ntstatus.c b/lib/async_req/async_req_ntstatus.c new file mode 100644 index 00000000000..dd810260743 --- /dev/null +++ b/lib/async_req/async_req_ntstatus.c @@ -0,0 +1,82 @@ +/* + Unix SMB/CIFS implementation. + NTSTATUS wrappers for async_req.h + Copyright (C) Volker Lendecke 2008, 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 "includes.h" +#include "lib/tevent/tevent.h" +#include "lib/talloc/talloc.h" +#include "lib/util/dlinklist.h" +#include "lib/async_req/async_req_ntstatus.h" + +/** + * @brief Helper function for nomem check + * @param[in] p The pointer to be checked + * @param[in] req The request being processed + * + * Convenience helper to easily check alloc failure within a callback + * implementing the next step of an async request. + * + * Call pattern would be + * \code + * p = talloc(mem_ctx, bla); + * if (async_req_ntnomem(p, req)) { + * return; + * } + * \endcode + */ + +bool async_req_ntnomem(const void *p, struct async_req *req) +{ + if (p != NULL) { + return false; + } + async_req_nterror(req, NT_STATUS_NO_MEMORY); + return true; +} + +void async_req_nterror(struct async_req *req, NTSTATUS status) +{ + async_req_error(req, NT_STATUS_V(status)); +} + +bool async_post_ntstatus(struct async_req *req, struct tevent_context *ev, + NTSTATUS status) +{ + return async_post_error(req, ev, NT_STATUS_V(status)); +} + +bool async_req_is_nterror(struct async_req *req, NTSTATUS *status) +{ + uint32_t error = NT_STATUS_V(NT_STATUS_INTERNAL_ERROR); + + if (async_req_is_error(req, &error)) { + *status = NT_STATUS(error); + return true; + } + return false; +} + +NTSTATUS async_req_simple_recv_ntstatus(struct async_req *req) +{ + NTSTATUS status; + + if (async_req_is_nterror(req, &status)) { + return status; + } + return NT_STATUS_OK; +} diff --git a/lib/async_req/async_req_ntstatus.h b/lib/async_req/async_req_ntstatus.h new file mode 100644 index 00000000000..7cc8caa14c8 --- /dev/null +++ b/lib/async_req/async_req_ntstatus.h @@ -0,0 +1,37 @@ +/* + Unix SMB/CIFS implementation. + NTSTATUS wrappers for async_req.h + Copyright (C) Volker Lendecke 2008, 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 __ASYNC_REQ_NTSTATUS_H__ +#define __ASYNC_REQ_NTSTATUS_H__ + +#include "lib/async_req/async_req.h" +#include "includes.h" + +void async_req_nterror(struct async_req *req, NTSTATUS status); + +bool async_post_ntstatus(struct async_req *req, struct tevent_context *ev, + NTSTATUS status); + +bool async_req_is_nterror(struct async_req *req, NTSTATUS *status); + +NTSTATUS async_req_simple_recv_ntstatus(struct async_req *req); + +bool async_req_ntnomem(const void *p, struct async_req *req); + +#endif diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 7febc54fd4f..b9923206690 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -239,7 +239,7 @@ static void async_send_callback(struct tevent_context *ev, struct param_send *p = &state->param.param_send; if (state->syscall_type != ASYNC_SYSCALL_SEND) { - async_req_error(req, NT_STATUS_INTERNAL_ERROR); + async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); return; } @@ -306,7 +306,7 @@ static void async_sendall_callback(struct tevent_context *ev, struct param_sendall *p = &state->param.param_sendall; if (state->syscall_type != ASYNC_SYSCALL_SENDALL) { - async_req_error(req, NT_STATUS_INTERNAL_ERROR); + async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); return; } @@ -316,18 +316,18 @@ static void async_sendall_callback(struct tevent_context *ev, state->sys_errno = errno; if (state->result.result_ssize_t == -1) { - async_req_error(req, map_nt_error_from_unix(state->sys_errno)); + async_req_nterror(req, map_nt_error_from_unix(state->sys_errno)); return; } if (state->result.result_ssize_t == 0) { - async_req_error(req, NT_STATUS_END_OF_FILE); + async_req_nterror(req, NT_STATUS_END_OF_FILE); return; } p->sent += state->result.result_ssize_t; if (p->sent > p->length) { - async_req_error(req, NT_STATUS_INTERNAL_ERROR); + async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); return; } @@ -376,7 +376,7 @@ struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, NTSTATUS sendall_recv(struct async_req *req) { - return async_req_simple_recv(req); + return async_req_simple_recv_ntstatus(req); } /** @@ -398,7 +398,7 @@ static void async_recv_callback(struct tevent_context *ev, struct param_recv *p = &state->param.param_recv; if (state->syscall_type != ASYNC_SYSCALL_RECV) { - async_req_error(req, NT_STATUS_INTERNAL_ERROR); + async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); return; } @@ -466,7 +466,7 @@ static void async_recvall_callback(struct tevent_context *ev, struct param_recvall *p = &state->param.param_recvall; if (state->syscall_type != ASYNC_SYSCALL_RECVALL) { - async_req_error(req, NT_STATUS_INTERNAL_ERROR); + async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); return; } @@ -476,18 +476,18 @@ static void async_recvall_callback(struct tevent_context *ev, state->sys_errno = errno; if (state->result.result_ssize_t == -1) { - async_req_error(req, map_nt_error_from_unix(state->sys_errno)); + async_req_nterror(req, map_nt_error_from_unix(state->sys_errno)); return; } if (state->result.result_ssize_t == 0) { - async_req_error(req, NT_STATUS_END_OF_FILE); + async_req_nterror(req, NT_STATUS_END_OF_FILE); return; } p->received += state->result.result_ssize_t; if (p->received > p->length) { - async_req_error(req, NT_STATUS_INTERNAL_ERROR); + async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); return; } @@ -535,7 +535,7 @@ struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, NTSTATUS recvall_recv(struct async_req *req) { - return async_req_simple_recv(req); + return async_req_simple_recv_ntstatus(req); } struct async_connect_state { @@ -627,7 +627,7 @@ struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, status = map_nt_error_from_unix(state->sys_errno); post_status: fcntl(fd, F_SETFL, state->old_sockflags); - if (!async_post_status(result, ev, status)) { + if (!async_post_ntstatus(result, ev, status)) { goto fail; } return result; @@ -675,7 +675,7 @@ 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, map_nt_error_from_unix(state->sys_errno)); + async_req_nterror(req, map_nt_error_from_unix(state->sys_errno)); return; } @@ -693,7 +693,7 @@ NTSTATUS async_connect_recv(struct async_req *req, int *perrno) *perrno = state->sys_errno; - if (async_req_is_error(req, &status)) { + if (async_req_is_nterror(req, &status)) { return status; } if (state->sys_errno == 0) { diff --git a/lib/async_req/config.mk b/lib/async_req/config.mk index 8cc594082c7..820f890fd07 100644 --- a/lib/async_req/config.mk +++ b/lib/async_req/config.mk @@ -1,3 +1,3 @@ [SUBSYSTEM::LIBASYNC_REQ] -LIBASYNC_REQ_OBJ_FILES = $(addprefix ../lib/async_req/, async_req.o async_sock.o) +LIBASYNC_REQ_OBJ_FILES = $(addprefix ../lib/async_req/, async_req.o async_sock.o async_req_ntstatus.o) -- cgit