[ovs-dev] [PATCH 10/15] stream: New functions stream_verify_name() and pstream_verify_name().
Ben Pfaff
blp at nicira.com
Wed Mar 24 20:18:13 UTC 2010
These functions can be useful for checking whether a given name is an
active or passive connection method.
The implementation is cut-and-paste from vconn_verify_name() and
pvconn_verify_name().
---
lib/stream.c | 158 +++++++++++++++++++++++++++++++++++++++++++---------------
lib/stream.h | 4 +-
2 files changed, 121 insertions(+), 41 deletions(-)
diff --git a/lib/stream.c b/lib/stream.c
index db6ec61..ed497d6 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -145,46 +145,83 @@ stream_usage(const char *name, bool active, bool passive,
#endif
}
-/* Attempts to connect a stream to a remote peer. 'name' is a connection name
- * in the form "TYPE:ARGS", where TYPE is an active stream class's name and
- * ARGS are stream class-specific.
- *
- * Returns 0 if successful, otherwise a positive errno value. If successful,
- * stores a pointer to the new connection in '*streamp', otherwise a null
- * pointer. */
-int
-stream_open(const char *name, struct stream **streamp)
+/* Given 'name', a stream name in the form "TYPE:ARGS", stores the class
+ * named "TYPE" into '*classp' and returns 0. Returns EAFNOSUPPORT and stores
+ * a null pointer into '*classp' if 'name' is in the wrong form or if no such
+ * class exists. */
+static int
+stream_lookup_class(const char *name, struct stream_class **classp)
{
size_t prefix_len;
size_t i;
- COVERAGE_INC(stream_open);
check_stream_classes();
- *streamp = NULL;
+ *classp = NULL;
prefix_len = strcspn(name, ":");
- if (prefix_len == strlen(name)) {
+ if (name[prefix_len] == '\0') {
return EAFNOSUPPORT;
}
for (i = 0; i < ARRAY_SIZE(stream_classes); i++) {
struct stream_class *class = stream_classes[i];
if (strlen(class->name) == prefix_len
&& !memcmp(class->name, name, prefix_len)) {
- struct stream *stream;
- char *suffix_copy = xstrdup(name + prefix_len + 1);
- int retval = class->open(name, suffix_copy, &stream);
- free(suffix_copy);
- if (!retval) {
- assert(stream->state != SCS_CONNECTING
- || stream->class->connect);
- *streamp = stream;
- }
- return retval;
+ *classp = class;
+ return 0;
}
}
return EAFNOSUPPORT;
}
+/* Returns 0 if 'name' is a stream name in the form "TYPE:ARGS" and TYPE is
+ * a supported stream type, otherwise EAFNOSUPPORT. */
+int
+stream_verify_name(const char *name)
+{
+ struct stream_class *class;
+ return stream_lookup_class(name, &class);
+}
+
+/* Attempts to connect a stream to a remote peer. 'name' is a connection name
+ * in the form "TYPE:ARGS", where TYPE is an active stream class's name and
+ * ARGS are stream class-specific.
+ *
+ * Returns 0 if successful, otherwise a positive errno value. If successful,
+ * stores a pointer to the new connection in '*streamp', otherwise a null
+ * pointer. */
+int
+stream_open(const char *name, struct stream **streamp)
+{
+ struct stream_class *class;
+ struct stream *stream;
+ char *suffix_copy;
+ int error;
+
+ COVERAGE_INC(stream_open);
+
+ /* Look up the class. */
+ error = stream_lookup_class(name, &class);
+ if (!class) {
+ goto error;
+ }
+
+ /* Call class's "open" function. */
+ suffix_copy = xstrdup(strchr(name, ':') + 1);
+ error = class->open(name, suffix_copy, &stream);
+ free(suffix_copy);
+ if (error) {
+ goto error;
+ }
+
+ /* Success. */
+ *streamp = stream;
+ return 0;
+
+error:
+ *streamp = NULL;
+ return error;
+}
+
int
stream_open_block(const char *name, struct stream **streamp)
{
@@ -399,42 +436,83 @@ stream_send_wait(struct stream *stream)
stream_wait(stream, STREAM_SEND);
}
-/* Attempts to start listening for remote stream connections. 'name' is a
- * connection name in the form "TYPE:ARGS", where TYPE is an passive stream
- * class's name and ARGS are stream class-specific.
- *
- * Returns 0 if successful, otherwise a positive errno value. If successful,
- * stores a pointer to the new connection in '*pstreamp', otherwise a null
- * pointer. */
-int
-pstream_open(const char *name, struct pstream **pstreamp)
+/* Given 'name', a pstream name in the form "TYPE:ARGS", stores the class
+ * named "TYPE" into '*classp' and returns 0. Returns EAFNOSUPPORT and stores
+ * a null pointer into '*classp' if 'name' is in the wrong form or if no such
+ * class exists. */
+static int
+pstream_lookup_class(const char *name, struct pstream_class **classp)
{
size_t prefix_len;
size_t i;
check_stream_classes();
- *pstreamp = NULL;
+ *classp = NULL;
prefix_len = strcspn(name, ":");
- if (prefix_len == strlen(name)) {
+ if (name[prefix_len] == '\0') {
return EAFNOSUPPORT;
}
for (i = 0; i < ARRAY_SIZE(pstream_classes); i++) {
struct pstream_class *class = pstream_classes[i];
if (strlen(class->name) == prefix_len
&& !memcmp(class->name, name, prefix_len)) {
- char *suffix_copy = xstrdup(name + prefix_len + 1);
- int retval = class->listen(name, suffix_copy, pstreamp);
- free(suffix_copy);
- if (retval) {
- *pstreamp = NULL;
- }
- return retval;
+ *classp = class;
+ return 0;
}
}
return EAFNOSUPPORT;
}
+/* Returns 0 if 'name' is a pstream name in the form "TYPE:ARGS" and TYPE is
+ * a supported pstream type, otherwise EAFNOSUPPORT. */
+int
+pstream_verify_name(const char *name)
+{
+ struct pstream_class *class;
+ return pstream_lookup_class(name, &class);
+}
+
+/* Attempts to start listening for remote stream connections. 'name' is a
+ * connection name in the form "TYPE:ARGS", where TYPE is an passive stream
+ * class's name and ARGS are stream class-specific.
+ *
+ * Returns 0 if successful, otherwise a positive errno value. If successful,
+ * stores a pointer to the new connection in '*pstreamp', otherwise a null
+ * pointer. */
+int
+pstream_open(const char *name, struct pstream **pstreamp)
+{
+ struct pstream_class *class;
+ struct pstream *pstream;
+ char *suffix_copy;
+ int error;
+
+ COVERAGE_INC(pstream_open);
+
+ /* Look up the class. */
+ error = pstream_lookup_class(name, &class);
+ if (!class) {
+ goto error;
+ }
+
+ /* Call class's "open" function. */
+ suffix_copy = xstrdup(strchr(name, ':') + 1);
+ error = class->listen(name, suffix_copy, &pstream);
+ free(suffix_copy);
+ if (error) {
+ goto error;
+ }
+
+ /* Success. */
+ *pstreamp = pstream;
+ return 0;
+
+error:
+ *pstreamp = NULL;
+ return error;
+}
+
/* Returns the name that was used to open 'pstream'. The caller must not
* modify or free the name. */
const char *
diff --git a/lib/stream.h b/lib/stream.h
index e7eef36..d21de2f 100644
--- a/lib/stream.h
+++ b/lib/stream.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009 Nicira Networks.
+ * Copyright (c) 2009, 2010 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ struct stream;
void stream_usage(const char *name, bool active, bool passive, bool bootstrap);
/* Bidirectional byte streams. */
+int stream_verify_name(const char *name);
int stream_open(const char *name, struct stream **);
int stream_open_block(const char *name, struct stream **);
void stream_close(struct stream *);
@@ -53,6 +54,7 @@ void stream_recv_wait(struct stream *);
void stream_send_wait(struct stream *);
/* Passive streams: listeners for incoming stream connections. */
+int pstream_verify_name(const char *name);
int pstream_open(const char *name, struct pstream **);
const char *pstream_get_name(const struct pstream *);
void pstream_close(struct pstream *);
--
1.6.6.1
More information about the dev
mailing list