From e66d53a35c7b59f46e31451da90b306a9beeacc6 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 4 Mar 2016 22:22:51 -0800 Subject: Socket operations become proper stream virtuals. * stream.c (unimpl_get_sock_family, unimpl_get_sock_type, unimpl_get_sock_peer, unimpl_set_sock_peer): New static functions. (fill_stream_ops): Set new function pointers in struct strm_ops to point to the unimpl_* functions. (stdio_get_sock_family, stdio_get_sock_type, stdio_get_sock_peer, stdio_set_sock_peer): New static functions. (stdio_sock_ops): New static structure. (make_sock_stream): Use stdio_sock_ops for socket object. (sock_family, sock_type, sock_peer, sock_set_peer): These API functions now just call their corresponding virtuals. (stream_init): Set up stdio_sock_ops as a copy of stdio_ops, and then override the socket-specific virtuals from the unimpl_* stubs to the stdio_get_sock_* and stdio_set_sock_* functions. * stream.h (struct strm_ops): New members, get_sock_family, get_sock_type, get_sock_peer and set_sock_peer. (strm_ops_init): Set new members to zero. --- stream.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- stream.h | 6 ++++- 2 files changed, 82 insertions(+), 14 deletions(-) diff --git a/stream.c b/stream.c index f6bff498..6e23d0f7 100644 --- a/stream.c +++ b/stream.c @@ -173,6 +173,26 @@ static noreturn val unimpl_truncate(val stream, val len) unimpl(stream, lit("truncate-stream")); } +static noreturn val unimpl_get_sock_family(val stream) +{ + unimpl(stream, lit("sock-family")); +} + +static noreturn val unimpl_get_sock_type(val stream) +{ + unimpl(stream, lit("sock-type")); +} + +static noreturn val unimpl_get_sock_peer(val stream) +{ + unimpl(stream, lit("sock-peer")); +} + +static noreturn val unimpl_set_sock_peer(val stream, val peer) +{ + unimpl(stream, lit("sock-set-peer")); +} + static val null_put_string(val stream, val str) { return nil; @@ -284,6 +304,14 @@ void fill_stream_ops(struct strm_ops *ops) ops->get_error_str = null_get_error_str; if (!ops->clear_error) ops->clear_error = null_clear_error; + if (!ops->get_sock_family) + ops->get_sock_family = unimpl_get_sock_family; + if (!ops->get_sock_type) + ops->get_sock_type = unimpl_get_sock_type; + if (!ops->get_sock_peer) + ops->get_sock_peer = unimpl_get_sock_peer; + if (!ops->set_sock_peer) + ops->set_sock_peer = unimpl_set_sock_peer; } static struct strm_ops null_ops = @@ -704,6 +732,34 @@ static val stdio_truncate(val stream, val len) #define stdio_truncate unimpl_truncate #endif +#if HAVE_SOCKETS + +static val stdio_get_sock_family(val stream) +{ + struct stdio_handle *h = coerce(struct stdio_handle *, stream->co.handle); + return h->family; +} + +static val stdio_get_sock_type(val stream) +{ + struct stdio_handle *h = coerce(struct stdio_handle *, stream->co.handle); + return h->type; +} + +static val stdio_get_sock_peer(val stream) +{ + struct stdio_handle *h = coerce(struct stdio_handle *, stream->co.handle); + return h->peer; +} + +static val stdio_set_sock_peer(val stream, val peer) +{ + struct stdio_handle *h = coerce(struct stdio_handle *, stream->co.handle); + return h->peer = peer; +} + +#endif + static struct strm_ops stdio_ops = strm_ops_init(cobj_ops_init(eq, stdio_stream_print, @@ -729,6 +785,10 @@ static struct strm_ops stdio_ops = stdio_get_error_str, stdio_clear_error); +#if HAVE_SOCKETS +static struct strm_ops stdio_sock_ops; +#endif + static void tail_calc(unsigned long *state, int *sec, int *mod) { unsigned long count = (*state)++; @@ -1169,7 +1229,7 @@ val make_pipe_stream(FILE *f, val descr) #if HAVE_SOCKETS static val make_sock_stream(FILE *f, val family, val type) { - val s = make_stdio_stream_common(f, lit("socket"), &stdio_ops.cobj_ops); + val s = make_stdio_stream_common(f, lit("socket"), &stdio_sock_ops.cobj_ops); struct stdio_handle *h = coerce(struct stdio_handle *, s->co.handle); h->family = family; h->type = type; @@ -1187,30 +1247,26 @@ val stream_fd(val stream) #if HAVE_SOCKETS val sock_family(val stream) { - struct stdio_handle *h = coerce(struct stdio_handle *, - cobj_handle(stream, stdio_stream_s)); - return h->family; + struct strm_ops *ops = coerce(struct strm_ops *, cobj_ops(stream, stream_s)); + return ops->get_sock_family(stream); } val sock_type(val stream) { - struct stdio_handle *h = coerce(struct stdio_handle *, - cobj_handle(stream, stdio_stream_s)); - return h->type; + struct strm_ops *ops = coerce(struct strm_ops *, cobj_ops(stream, stream_s)); + return ops->get_sock_type(stream); } val sock_peer(val stream) { - struct stdio_handle *h = coerce(struct stdio_handle *, - cobj_handle(stream, stdio_stream_s)); - return h->peer; + struct strm_ops *ops = coerce(struct strm_ops *, cobj_ops(stream, stream_s)); + return ops->get_sock_peer(stream); } val sock_set_peer(val stream, val peer) { - struct stdio_handle *h = coerce(struct stdio_handle *, stream->co.handle); - h->peer = peer; - return stream; + struct strm_ops *ops = coerce(struct strm_ops *, cobj_ops(stream, stream_s)); + return ops->set_sock_peer(stream, peer); } #endif @@ -3702,4 +3758,12 @@ void stream_init(void) fill_stream_ops(&strlist_out_ops); fill_stream_ops(&dir_ops); fill_stream_ops(&cat_stream_ops); + +#if HAVE_SOCKETS + stdio_sock_ops = stdio_ops; + stdio_sock_ops.get_sock_family = stdio_get_sock_family; + stdio_sock_ops.get_sock_type = stdio_get_sock_type; + stdio_sock_ops.get_sock_peer = stdio_get_sock_peer; + stdio_sock_ops.set_sock_peer = stdio_set_sock_peer; +#endif } diff --git a/stream.h b/stream.h index c7e70c12..ff5ee9f8 100644 --- a/stream.h +++ b/stream.h @@ -64,6 +64,10 @@ struct strm_ops { val (*get_error)(val); val (*get_error_str)(val); val (*clear_error)(val); + val (*get_sock_family)(val); + val (*get_sock_type)(val); + val (*get_sock_peer)(val); + val (*set_sock_peer)(val, val); }; #define strm_ops_init(cobj_init_macro, name, put_string, put_char, put_byte, \ @@ -74,7 +78,7 @@ struct strm_ops { cobj_init_macro, name, put_string, put_char, put_byte, get_line, \ get_char, get_byte, unget_char, unget_byte, \ close, flush, seek, truncate, get_prop, set_prop, \ - get_error, get_error_str, clear_error \ + get_error, get_error_str, clear_error, 0, 0, 0, 0, \ } #define std_input (deref(lookup_var_l(nil, stdin_s))) -- cgit v1.2.3