diff options
author | Volker Lendecke <vl@samba.org> | 2008-03-18 13:20:10 +0100 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2008-03-18 13:49:46 +0100 |
commit | 16cbc22a99c0a302d248dc006ac0016042c1e3ec (patch) | |
tree | 6a1e98392cf2379eb4737cb7a6318cc5c7b844a2 | |
parent | c5356479c1953b15fee8097d5d3436204fc7a4ce (diff) | |
download | samba-16cbc22a99c0a302d248dc006ac0016042c1e3ec.tar.gz samba-16cbc22a99c0a302d248dc006ac0016042c1e3ec.tar.xz samba-16cbc22a99c0a302d248dc006ac0016042c1e3ec.zip |
Fix bug 5334
I did not test with a zero length file :-)
(This used to be commit 7d7a73944c2dcf078f7bc8de65d575f32f9aa851)
-rw-r--r-- | source3/include/async_req.h | 7 | ||||
-rw-r--r-- | source3/lib/async_req.c | 30 | ||||
-rw-r--r-- | source3/libsmb/clireadwrite.c | 8 |
3 files changed, 45 insertions, 0 deletions
diff --git a/source3/include/async_req.h b/source3/include/async_req.h index 6df53602b26..fb463d5b9a1 100644 --- a/source3/include/async_req.h +++ b/source3/include/async_req.h @@ -75,6 +75,13 @@ void async_req_done(struct async_req *req); void async_req_error(struct async_req *req, NTSTATUS status); /* + * If a request is finished or ends in error even before it has the chance to + * trigger the event loop, post a status. This creates an immediate timed + * event to call the async function if there is any. + */ +bool async_post_status(struct async_req *req, NTSTATUS status); + +/* * Convenience helper to easily check alloc failure within a callback. * * Call pattern would be diff --git a/source3/lib/async_req.c b/source3/lib/async_req.c index 01154ca4363..2e85d9a38d7 100644 --- a/source3/lib/async_req.c +++ b/source3/lib/async_req.c @@ -58,6 +58,36 @@ void async_req_error(struct async_req *req, NTSTATUS status) } } +static void async_trigger(struct event_context *ev, struct timed_event *te, + const struct timeval *now, void *priv) +{ + struct async_req *req = talloc_get_type_abort(priv, struct async_req); + + TALLOC_FREE(te); + if (NT_STATUS_IS_OK(req->status)) { + async_req_done(req); + } + else { + async_req_error(req, req->status); + } +} + +bool async_post_status(struct async_req *req, NTSTATUS status) +{ + /* + * Used if a request is finished before it even started + */ + + req->status = status; + + if (event_add_timed(req->event_ctx, req, timeval_zero(), + "async_trigger", + async_trigger, req) == NULL) { + return false; + } + return true; +} + bool async_req_nomem(const void *p, struct async_req *req) { if (p != NULL) { diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 9bd81706730..13c024a2642 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -262,6 +262,14 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, state->pushed = 0; state->top_req = 0; + + if (size == 0) { + if (!async_post_status(result, NT_STATUS_OK)) { + goto failed; + } + return result; + } + state->chunk_size = cli_read_max_bufsize(cli); state->num_reqs = MAX(window_size/state->chunk_size, 1); |