summaryrefslogtreecommitdiff
path: root/src/libstddjb/slurpn.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-05-18 02:19:59 +0000
committerLaurent Bercot <ska@appnovation.com>2023-05-18 02:19:59 +0000
commit2af587d68d11b1826c356364b4e9679199eee2ed (patch)
tree4cffead67aea555d1306495e60fc30ce1185db7b /src/libstddjb/slurpn.c
parent8ef88c7d9a7108409c1e58c21b3d0590c859384f (diff)
downloadskalibs-2af587d68d11b1826c356364b4e9679199eee2ed.tar.xz
Add slurpn, refactor slurp, fix avltree/cdbmake bugs, add strerr_warnf
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/libstddjb/slurpn.c')
-rw-r--r--src/libstddjb/slurpn.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/libstddjb/slurpn.c b/src/libstddjb/slurpn.c
new file mode 100644
index 0000000..c9c5c11
--- /dev/null
+++ b/src/libstddjb/slurpn.c
@@ -0,0 +1,35 @@
+/* ISC license. */
+
+#include <sys/types.h>
+#include <errno.h>
+
+#include <skalibs/allreadwrite.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+#define N 4096
+
+int slurpn (int fd, stralloc *sa, size_t max)
+{
+ size_t sabase = sa->len ;
+ int wasnull = !sa->s ;
+ for (;;)
+ {
+ ssize_t r ;
+ size_t n = max && sa->len + N > max ? max - sa->len : N ;
+ if (!n) { errno = ENOBUFS ; goto err ; }
+ if (!stralloc_readyplus(sa, n)) break ;
+ r = fd_read(fd, sa->s + sa->len, n) ;
+ switch (r)
+ {
+ case -1 : goto err ;
+ case 0 : return 1 ;
+ default : sa->len += r ;
+ }
+ }
+
+err:
+ if (wasnull) stralloc_free(sa) ;
+ else sa->len = sabase ;
+ return 0 ;
+}