From a848231ae0f346dc7cc000973fbeb65b0894ee92 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 21:59:03 +0200 Subject: Adding upstream version 3.8.5. Signed-off-by: Daniel Baumann --- src/util/write_buf.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/util/write_buf.c (limited to 'src/util/write_buf.c') diff --git a/src/util/write_buf.c b/src/util/write_buf.c new file mode 100644 index 0000000..968a468 --- /dev/null +++ b/src/util/write_buf.c @@ -0,0 +1,89 @@ +/*++ +/* NAME +/* write_buf 3 +/* SUMMARY +/* write buffer or bust +/* SYNOPSIS +/* #include +/* +/* ssize_t write_buf(fd, buf, len, timeout) +/* int fd; +/* const char *buf; +/* ssize_t len; +/* int timeout; +/* DESCRIPTION +/* write_buf() writes a buffer to the named stream in as many +/* fragments as needed, and returns the number of bytes written, +/* which is always the number requested or an error indication. +/* +/* Arguments: +/* .IP fd +/* File descriptor in the range 0..FD_SETSIZE. +/* .IP buf +/* Address of data to be written. +/* .IP len +/* Amount of data to be written. +/* .IP timeout +/* Bounds the time in seconds to wait until \fIfd\fD becomes writable. +/* A value <= 0 means do not wait; this is useful only when \fIfd\fR +/* uses blocking I/O. +/* DIAGNOSTICS +/* write_buf() returns -1 in case of trouble. The global \fIerrno\fR +/* variable reflects the nature of the problem. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include +#include +#include +#include + +/* Utility library. */ + +#include +#include + +/* write_buf - write buffer or bust */ + +ssize_t write_buf(int fd, const char *buf, ssize_t len, int timeout) +{ + const char *start = buf; + ssize_t count; + time_t expire; + int time_left = timeout; + + if (time_left > 0) + expire = time((time_t *) 0) + time_left; + + while (len > 0) { + if (time_left > 0 && write_wait(fd, time_left) < 0) + return (-1); + if ((count = write(fd, buf, len)) < 0) { + if ((errno == EAGAIN && time_left > 0) || errno == EINTR) + /* void */ ; + else + return (-1); + } else { + buf += count; + len -= count; + } + if (len > 0 && time_left > 0) { + time_left = expire - time((time_t *) 0); + if (time_left <= 0) { + errno = ETIMEDOUT; + return (-1); + } + } + } + return (buf - start); +} -- cgit v1.2.3