about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFedor Indutny <fedor@indutny.com>2016-06-04 19:25:26 -0400
committerFedor Indutny <fedor@indutny.com>2016-06-04 19:25:26 -0400
commit4916c3ba7e3dbefbddb8c5ba8370092ce1a634fb (patch)
tree623f8d6fc0dae590f29eca86ffb00af70e9a41c4
parent79d44e403c15b1cfe08f317f17ad20f4814ae4c9 (diff)
downloaduv_link_t-4916c3ba7e3dbefbddb8c5ba8370092ce1a634fb.tar.gz
api: uv_link_errno
-rw-r--r--docs/api.md9
-rw-r--r--include/uv_link_t.h1
-rw-r--r--src/uv_link_t.c35
3 files changed, 38 insertions, 7 deletions
diff --git a/docs/api.md b/docs/api.md
index 0d7e634..adb25e4 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -118,6 +118,15 @@ Invoke `shutdown` from the link's [`uv_link_methods_t`][]. Acts similarly to
 `uv_shutdown()`. `cb(uv_link_t* link, int status, void* arg)` is invoked on
 completion.
 
+### int uv_link_errno(...)
+
+* `uv_link_t** link`
+* `int err` - error code, previously either returned the one of the
+  `uv_link...` methods or passed as a negative `nread` to `link->read_cb`
+
+Unprefix internal error code and set the `link` pointer to the link that
+have emitted that error.
+
 ### const char* uv_link_strerror(...)
 
 * `uv_link_t* link`
diff --git a/include/uv_link_t.h b/include/uv_link_t.h
index 2f09d36..9c5876d 100644
--- a/include/uv_link_t.h
+++ b/include/uv_link_t.h
@@ -125,6 +125,7 @@ static int uv_link_shutdown(uv_link_t* link, uv_link_shutdown_cb cb,
   return uv_link_propagate_shutdown(link, link, cb, arg);
 }
 
+int uv_link_errno(uv_link_t** link, int err);
 const char* uv_link_strerror(uv_link_t* link, int err);
 
 /* Link Source */
diff --git a/src/uv_link_t.c b/src/uv_link_t.c
index 696dd15..32c676e 100644
--- a/src/uv_link_t.c
+++ b/src/uv_link_t.c
@@ -221,21 +221,42 @@ int uv_link_unchain(uv_link_t* from, uv_link_t* to) {
 }
 
 
-const char* uv_link_strerror(uv_link_t* link, int err) {
+int uv_link_errno(uv_link_t** link, int err) {
   unsigned int prefix;
   int local_err;
+  uv_link_t* p;
 
-  if (err >= UV_ERRNO_MAX)
-    return uv_strerror(err);
+  if (err >= UV_ERRNO_MAX) {
+    *link = NULL;
+    return err;
+  }
 
   prefix = (-err) & kErrorPrefixMask;
   local_err = -((-err) & kErrorValueMask);
 
-  for (; link != NULL; link = link->parent)
-    if (prefix == link->err_prefix)
-      return link->methods->strerror(link, local_err);
+  for (p = *link; p != NULL; p = p->parent) {
+    if (prefix == p->err_prefix) {
+      *link = p;
+      return local_err;
+    }
+  }
+
+  *link = NULL;
+  return err;
+}
+
+
+const char* uv_link_strerror(uv_link_t* link, int err) {
+  int local_err;
+
+  if (err >= UV_ERRNO_MAX)
+    return uv_strerror(err);
+
+  local_err = uv_link_errno(&link, err);
+  if (link == NULL)
+    return NULL;
 
-  return NULL;
+  return link->methods->strerror(link, local_err);
 }