summaryrefslogtreecommitdiff
path: root/source4/rpc_server/dcerpc_tcp.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-01-20 05:54:17 +0000
committerAndrew Tridgell <tridge@samba.org>2004-01-20 05:54:17 +0000
commit7a4da9654e30ea96b326448c3e9111c2a5604f58 (patch)
tree628dbc1eeaf7034349708149e2a49d3fb402f65a /source4/rpc_server/dcerpc_tcp.c
parent4d39861f991254aa381b8823476825e26a4d6da3 (diff)
downloadsamba-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.c31
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);
}
/*