bug #49684, api_msg: treat non-blocking ERR_MEM as ERR_WOULDBLOCK

This corrects a case in lwip_netconn_do_writemore() where if a
non-blocking socket receives ERR_MEM in a call to tcp_write(), it would
return ERR_MEM, which would result in ENOMEM coming out of the socket
layer

This case can be gracefully handled by returning ERR_WOULDBLOCK since the
socket is already marked as no longer writable and sent_tcp/poll_tcp will
mark the socket as writable again based on available buffer space

This is very similiar to how ERR_MEM is resolved for blocking sockets
diff --git a/src/api/api_msg.c b/src/api/api_msg.c
index e0b062b..1009228 100644
--- a/src/api/api_msg.c
+++ b/src/api/api_msg.c
@@ -1572,10 +1572,11 @@
         write_finished = 1;
         conn->current_msg->msg.w.len = 0;
       }
-    } else if ((err == ERR_MEM) && !dontblock) {
-      /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called
-         we do NOT return to the application thread, since ERR_MEM is
-         only a temporary error! */
+    } else if (err == ERR_MEM) {
+      /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called.
+         For blocking sockets, we do NOT return to the application
+         thread, since ERR_MEM is only a temporary error! Non-blocking
+         will remain non-writable until sent_tcp/poll_tcp is called */
 
       /* tcp_write returned ERR_MEM, try tcp_output anyway */
       err_t out_err = tcp_output(conn->pcb.tcp);
@@ -1586,6 +1587,11 @@
         err = out_err;
         write_finished = 1;
         conn->current_msg->msg.w.len = 0;
+      } else if (dontblock) {
+        /* non-blocking write is done on ERR_MEM */
+        err = ERR_WOULDBLOCK;
+        write_finished = 1;
+        conn->current_msg->msg.w.len = 0;
       }
     } else {
       /* On errors != ERR_MEM, we don't try writing any more but return