X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fstream.c;h=43b73af0adf9f7f542019a031e57b3515a799298;hb=fb0d597fb64308c60001e3afc9b31eb295dedb6b;hp=ed497d693300c9bfba3511700ee78552ee2231a5;hpb=26ad129e69fc7c800630dbd541dc2dcc8150c3a4;p=openvswitch diff --git a/lib/stream.c b/lib/stream.c index ed497d69..43b73af0 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -25,6 +25,7 @@ #include #include "coverage.h" #include "dynamic-string.h" +#include "fatal-signal.h" #include "flow.h" #include "ofp-print.h" #include "ofpbuf.h" @@ -222,13 +223,23 @@ error: return error; } +/* Blocks until a previously started stream connection attempt succeeds or + * fails. 'error' should be the value returned by stream_open() and 'streamp' + * should point to the stream pointer set by stream_open(). Returns 0 if + * successful, otherwise a positive errno value other than EAGAIN or + * EINPROGRESS. If successful, leaves '*streamp' untouched; on error, closes + * '*streamp' and sets '*streamp' to null. + * + * Typical usage: + * error = stream_open_block(stream_open("tcp:1.2.3.4:5", &stream), &stream); + */ int -stream_open_block(const char *name, struct stream **streamp) +stream_open_block(int error, struct stream **streamp) { - struct stream *stream; - int error; + struct stream *stream = *streamp; + + fatal_signal_run(); - error = stream_open(name, &stream); while (error == EAGAIN) { stream_run(stream); stream_run_wait(stream); @@ -562,6 +573,7 @@ pstream_accept_block(struct pstream *pstream, struct stream **new_stream) { int error; + fatal_signal_run(); while ((error = pstream_accept(pstream, new_stream)) == EAGAIN) { pstream_wait(pstream); poll_block(); @@ -639,3 +651,72 @@ pstream_init(struct pstream *pstream, struct pstream_class *class, pstream->class = class; pstream->name = xstrdup(name); } + +static int +count_fields(const char *s_) +{ + char *s, *field, *save_ptr; + int n = 0; + + save_ptr = NULL; + s = xstrdup(s_); + for (field = strtok_r(s, ":", &save_ptr); field != NULL; + field = strtok_r(NULL, ":", &save_ptr)) { + n++; + } + free(s); + + return n; +} + +/* Like stream_open(), but for tcp streams the port defaults to + * 'default_tcp_port' if no port number is given and for SSL streams the port + * defaults to 'default_ssl_port' if no port number is given. */ +int +stream_open_with_default_ports(const char *name_, + uint16_t default_tcp_port, + uint16_t default_ssl_port, + struct stream **streamp) +{ + char *name; + int error; + + if (!strncmp(name_, "tcp:", 4) && count_fields(name_) < 3) { + name = xasprintf("%s:%d", name_, default_tcp_port); + } else if (!strncmp(name_, "ssl:", 4) && count_fields(name_) < 3) { + name = xasprintf("%s:%d", name_, default_ssl_port); + } else { + name = xstrdup(name_); + } + error = stream_open(name, streamp); + free(name); + + return error; +} + +/* Like pstream_open(), but for ptcp streams the port defaults to + * 'default_ptcp_port' if no port number is given and for passive SSL streams + * the port defaults to 'default_pssl_port' if no port number is given. */ +int +pstream_open_with_default_ports(const char *name_, + uint16_t default_ptcp_port, + uint16_t default_pssl_port, + struct pstream **pstreamp) +{ + char *name; + int error; + + if (!strncmp(name_, "ptcp:", 5) && count_fields(name_) < 2) { + name = xasprintf("%s%d", name_, default_ptcp_port); + } else if (!strncmp(name_, "pssl:", 5) && count_fields(name_) < 2) { + name = xasprintf("%s%d", name_, default_pssl_port); + } else { + name = xstrdup(name_); + } + error = pstream_open(name, pstreamp); + free(name); + + return error; +} + +