summaryrefslogtreecommitdiff
path: root/src/libstddjb/mininetstring_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstddjb/mininetstring_write.c')
-rw-r--r--src/libstddjb/mininetstring_write.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/libstddjb/mininetstring_write.c b/src/libstddjb/mininetstring_write.c
new file mode 100644
index 0000000..6b31f17
--- /dev/null
+++ b/src/libstddjb/mininetstring_write.c
@@ -0,0 +1,37 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <skalibs/uint16.h>
+#include <skalibs/uint32.h>
+#include <skalibs/allreadwrite.h>
+#include <skalibs/mininetstring.h>
+
+int mininetstring_write (int fd, char const *s, uint16 len, uint32 *w)
+{
+ if (!w)
+ {
+ char pack[2] ;
+ uint16_pack_big(pack, len) ;
+ switch (fd_write(fd, pack, 2))
+ {
+ case -1 : return -1 ;
+ case 0 : return (errno = EAGAIN, -1) ;
+ case 1 : *w = (1U << 31) ; break ;
+ case 2 : *w = len ; break ;
+ default : return (errno = EDOM, -1) ;
+ }
+ }
+ if (*w & (1U << 31))
+ {
+ char c = len & 0xFFU ;
+ switch (fd_write(fd, &c, 1))
+ {
+ case -1 : return -1 ;
+ case 0 : return (errno = EAGAIN, -1) ;
+ case 1 : *w = len ; break ;
+ default : return (errno = EDOM, -1) ;
+ }
+ }
+ *w -= allwrite(fd, s + len - *w, *w) ;
+ return *w ? -1 : 1 ;
+}