diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-01-20 05:54:17 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2004-01-20 05:54:17 +0000 |
commit | 7a4da9654e30ea96b326448c3e9111c2a5604f58 (patch) | |
tree | 628dbc1eeaf7034349708149e2a49d3fb402f65a /source4/rpc_server/dcerpc_tcp.c | |
parent | 4d39861f991254aa381b8823476825e26a4d6da3 (diff) | |
download | samba-7a4da9654e30ea96b326448c3e9111c2a5604f58.tar.gz samba-7a4da9654e30ea96b326448c3e9111c2a5604f58.tar.bz2 samba-7a4da9654e30ea96b326448c3e9111c2a5604f58.zip |
dcerpc server output now copes with the client blocking part way
through a read. This happens to also avoid a memcpy on output for
dcerpc over tcp.
(This used to be commit e7c53ad1856e299d82d84b5837189ae3191c32de)
Diffstat (limited to 'source4/rpc_server/dcerpc_tcp.c')
-rw-r--r-- | source4/rpc_server/dcerpc_tcp.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/source4/rpc_server/dcerpc_tcp.c b/source4/rpc_server/dcerpc_tcp.c index 34e6db63e3..cc7581ee2f 100644 --- a/source4/rpc_server/dcerpc_tcp.c +++ b/source4/rpc_server/dcerpc_tcp.c @@ -54,6 +54,21 @@ static void terminate_rpc_session(struct rpc_server_context *r, const char *reas r->model_ops->terminate_rpc_connection(r, reason); } + +/* + write_fn callback for dcesrv_output() +*/ +static ssize_t dcerpc_write_fn(void *private, const void *buf, size_t count) +{ + struct fd_event *fde = private; + ssize_t ret; + ret = write(fde->fd, buf, count); + if (ret == -1 && errno == EINTR) { + return 0; + } + return ret; +} + /* called when a RPC socket becomes writable */ @@ -61,26 +76,16 @@ static void dcerpc_write_handler(struct event_context *ev, struct fd_event *fde, time_t t, uint16 flags) { struct rpc_server_context *r = fde->private; - DATA_BLOB blob; NTSTATUS status; - blob = data_blob(NULL, 0x4000); - if (!blob.data) { - terminate_rpc_session(r, "out of memory"); - return; - } - - status = dcesrv_output(r->dce_conn, &blob); - - if (NT_STATUS_IS_OK(status)) { - write_data(fde->fd, blob.data, blob.length); + status = dcesrv_output(r->dce_conn, fde, dcerpc_write_fn); + if (!NT_STATUS_IS_OK(status)) { + /* TODO: destroy fd_event? */ } if (!r->dce_conn->call_list || !r->dce_conn->call_list->replies) { fde->flags &= ~EVENT_FD_WRITE; } - - data_blob_free(&blob); } /* |